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 "../librpc/gen_ndr/cli_lsa.h"
28 #include "../librpc/gen_ndr/cli_netlogon.h"
29 #include "../librpc/gen_ndr/cli_srvsvc.h"
30 #include "../librpc/gen_ndr/cli_spoolss.h"
31 #include "../librpc/gen_ndr/cli_initshutdown.h"
32 #include "../librpc/gen_ndr/cli_winreg.h"
34 static int net_mode_share;
35 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
40 * @brief RPC based subcommands for the 'net' utility.
42 * This file should contain much of the functionality that used to
43 * be found in rpcclient, execpt that the commands should change
44 * less often, and the fucntionality should be sane (the user is not
45 * expected to know a rid/sid before they conduct an operation etc.)
47 * @todo Perhaps eventually these should be split out into a number
48 * of files, as this could get quite big.
53 * Many of the RPC functions need the domain sid. This function gets
54 * it at the start of every run
56 * @param cli A cli_state already connected to the remote machine
58 * @return The Domain SID of the remote machine.
61 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
63 const char **domain_name)
65 struct rpc_pipe_client *lsa_pipe = NULL;
66 struct policy_handle pol;
67 NTSTATUS result = NT_STATUS_OK;
68 union lsa_PolicyInformation *info = NULL;
70 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
72 if (!NT_STATUS_IS_OK(result)) {
73 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
77 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
78 SEC_FLAG_MAXIMUM_ALLOWED,
80 if (!NT_STATUS_IS_OK(result)) {
81 d_fprintf(stderr, "open_policy %s: %s\n",
87 result = rpccli_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx,
89 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
91 if (!NT_STATUS_IS_OK(result)) {
92 d_fprintf(stderr, "lsaquery %s: %s\n",
98 *domain_name = info->account_domain.name.string;
99 *domain_sid = info->account_domain.sid;
101 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
102 TALLOC_FREE(lsa_pipe);
108 * Run a single RPC command, from start to finish.
110 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
111 * @param conn_flag a NET_FLAG_ combination. Passed to
112 * net_make_ipc_connection.
113 * @param argc Standard main() style argc.
114 * @param argv Standard main() style argv. Initial components are already
116 * @return A shell status integer (0 for success).
119 int run_rpc_command(struct net_context *c,
120 struct cli_state *cli_arg,
121 const struct ndr_syntax_id *interface,
127 struct cli_state *cli = NULL;
128 struct rpc_pipe_client *pipe_hnd = NULL;
132 const char *domain_name;
135 /* make use of cli_state handed over as an argument, if possible */
137 nt_status = net_make_ipc_connection(c, conn_flags, &cli);
138 if (!NT_STATUS_IS_OK(nt_status)) {
139 DEBUG(1, ("failed to make ipc connection: %s\n",
140 nt_errstr(nt_status)));
153 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
154 DEBUG(0, ("talloc_init() failed\n"));
158 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
160 if (!NT_STATUS_IS_OK(nt_status)) {
164 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
165 if (lp_client_schannel()
166 && (ndr_syntax_id_equal(interface,
167 &ndr_table_netlogon.syntax_id))) {
168 /* Always try and create an schannel netlogon pipe. */
169 nt_status = cli_rpc_pipe_open_schannel(
170 cli, interface, NCACN_NP,
171 DCERPC_AUTH_LEVEL_PRIVACY, domain_name,
173 if (!NT_STATUS_IS_OK(nt_status)) {
174 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
175 nt_errstr(nt_status) ));
179 if (conn_flags & NET_FLAGS_SEAL) {
180 nt_status = cli_rpc_pipe_open_ntlmssp(
182 (conn_flags & NET_FLAGS_TCP) ?
183 NCACN_IP_TCP : NCACN_NP,
184 DCERPC_AUTH_LEVEL_PRIVACY,
185 lp_workgroup(), c->opt_user_name,
186 c->opt_password, &pipe_hnd);
188 nt_status = cli_rpc_pipe_open_noauth(
192 if (!NT_STATUS_IS_OK(nt_status)) {
193 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
194 get_pipe_name_from_syntax(
195 talloc_tos(), interface),
196 nt_errstr(nt_status) ));
202 nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
204 if (!NT_STATUS_IS_OK(nt_status)) {
205 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
208 DEBUG(5, ("rpc command function succedded\n"));
211 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
213 TALLOC_FREE(pipe_hnd);
218 /* close the connection only if it was opened here */
223 talloc_destroy(mem_ctx);
228 * Force a change of the trust acccount password.
230 * All parameters are provided by the run_rpc_command function, except for
231 * argc, argv which are passed through.
233 * @param domain_sid The domain sid acquired from the remote server.
234 * @param cli A cli_state connected to the server.
235 * @param mem_ctx Talloc context, destroyed on completion of the function.
236 * @param argc Standard main() style argc.
237 * @param argv Standard main() style argv. Initial components are already
240 * @return Normal NTSTATUS return.
243 static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
244 const DOM_SID *domain_sid,
245 const char *domain_name,
246 struct cli_state *cli,
247 struct rpc_pipe_client *pipe_hnd,
254 status = trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup);
255 if (!NT_STATUS_IS_OK(status)) {
256 d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
265 * Force a change of the trust acccount password.
267 * @param argc Standard main() style argc.
268 * @param argv Standard main() style argv. Initial components are already
271 * @return A shell status integer (0 for success).
274 int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
276 if (c->display_usage) {
278 "net rpc changetrustpw\n"
281 _("Change the machine trust password"));
285 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
286 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
287 rpc_changetrustpw_internals,
292 * Join a domain, the old way.
294 * This uses 'machinename' as the inital password, and changes it.
296 * The password should be created with 'server manager' or equiv first.
298 * All parameters are provided by the run_rpc_command function, except for
299 * argc, argv which are passed through.
301 * @param domain_sid The domain sid acquired from the remote server.
302 * @param cli A cli_state connected to the server.
303 * @param mem_ctx Talloc context, destroyed on completion of the function.
304 * @param argc Standard main() style argc.
305 * @param argv Standard main() style argv. Initial components are already
308 * @return Normal NTSTATUS return.
311 static NTSTATUS rpc_oldjoin_internals(struct net_context *c,
312 const DOM_SID *domain_sid,
313 const char *domain_name,
314 struct cli_state *cli,
315 struct rpc_pipe_client *pipe_hnd,
321 fstring trust_passwd;
322 unsigned char orig_trust_passwd_hash[16];
324 enum netr_SchannelType sec_channel_type;
326 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
328 if (!NT_STATUS_IS_OK(result)) {
329 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
332 nt_errstr(result) ));
337 check what type of join - if the user want's to join as
338 a BDC, the server must agree that we are a BDC.
341 sec_channel_type = get_sec_channel_type(argv[0]);
343 sec_channel_type = get_sec_channel_type(NULL);
346 fstrcpy(trust_passwd, global_myname());
347 strlower_m(trust_passwd);
350 * Machine names can be 15 characters, but the max length on
351 * a password is 14. --jerry
354 trust_passwd[14] = '\0';
356 E_md4hash(trust_passwd, orig_trust_passwd_hash);
358 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup,
360 orig_trust_passwd_hash,
363 if (NT_STATUS_IS_OK(result))
364 printf(_("Joined domain %s.\n"), c->opt_target_workgroup);
367 if (!secrets_store_domain_sid(c->opt_target_workgroup, domain_sid)) {
368 DEBUG(0, ("error storing domain sid for %s\n", c->opt_target_workgroup));
369 result = NT_STATUS_UNSUCCESSFUL;
376 * Join a domain, the old way.
378 * @param argc Standard main() style argc.
379 * @param argv Standard main() style argv. Initial components are already
382 * @return A shell status integer (0 for success).
385 static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv)
387 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
388 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
389 rpc_oldjoin_internals,
394 * Join a domain, the old way. This function exists to allow
395 * the message to be displayed when oldjoin was explicitly
396 * requested, but not when it was implied by "net rpc join".
398 * @param argc Standard main() style argc.
399 * @param argv Standard main() style argv. Initial components are already
402 * @return A shell status integer (0 for success).
405 static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
409 if (c->display_usage) {
414 _("Join a domain the old way"));
418 rc = net_rpc_perform_oldjoin(c, argc, argv);
421 d_fprintf(stderr, _("Failed to join domain\n"));
428 * 'net rpc join' entrypoint.
429 * @param argc Standard main() style argc.
430 * @param argv Standard main() style argv. Initial components are already
433 * Main 'net_rpc_join()' (where the admin username/password is used) is
435 * Try to just change the password, but if that doesn't work, use/prompt
436 * for a username/password.
439 int net_rpc_join(struct net_context *c, int argc, const char **argv)
441 if (c->display_usage) {
444 _("net rpc join -U <username>[%%password] <type>\n"
446 " username\tName of the admin user"
447 " password\tPassword of the admin user, will "
448 "prompt if not specified\n"
449 " type\tCan be one of the following:\n"
450 "\t\tMEMBER\tJoin as member server (default)\n"
451 "\t\tBDC\tJoin as BDC\n"
452 "\t\tPDC\tJoin as PDC\n"));
456 if (lp_server_role() == ROLE_STANDALONE) {
457 d_printf(_("cannot join as standalone machine\n"));
461 if (strlen(global_myname()) > 15) {
462 d_printf(_("Our netbios name can be at most 15 chars long, "
463 "\"%s\" is %u chars long\n"),
464 global_myname(), (unsigned int)strlen(global_myname()));
468 if ((net_rpc_perform_oldjoin(c, argc, argv) == 0))
471 return net_rpc_join_newstyle(c, argc, argv);
475 * display info about a rpc domain
477 * All parameters are provided by the run_rpc_command function, except for
478 * argc, argv which are passed through.
480 * @param domain_sid The domain sid acquired from the remote server
481 * @param cli A cli_state connected to the server.
482 * @param mem_ctx Talloc context, destroyed on completion of the function.
483 * @param argc Standard main() style argc.
484 * @param argv Standard main() style argv. Initial components are already
487 * @return Normal NTSTATUS return.
490 NTSTATUS rpc_info_internals(struct net_context *c,
491 const DOM_SID *domain_sid,
492 const char *domain_name,
493 struct cli_state *cli,
494 struct rpc_pipe_client *pipe_hnd,
499 struct policy_handle connect_pol, domain_pol;
500 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
501 union samr_DomainInfo *info = NULL;
504 sid_to_fstring(sid_str, domain_sid);
506 /* Get sam policy handle */
507 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
509 MAXIMUM_ALLOWED_ACCESS,
511 if (!NT_STATUS_IS_OK(result)) {
512 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
517 /* Get domain policy handle */
518 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
520 MAXIMUM_ALLOWED_ACCESS,
521 CONST_DISCARD(struct dom_sid2 *, domain_sid),
523 if (!NT_STATUS_IS_OK(result)) {
524 d_fprintf(stderr, _("Could not open domain: %s\n"),
529 result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx,
533 if (NT_STATUS_IS_OK(result)) {
534 d_printf(_("Domain Name: %s\n"),
535 info->general.domain_name.string);
536 d_printf(_("Domain SID: %s\n"), sid_str);
537 d_printf(_("Sequence number: %llu\n"),
538 (unsigned long long)info->general.sequence_num);
539 d_printf(_("Num users: %u\n"), info->general.num_users);
540 d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
541 d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
549 * 'net rpc info' entrypoint.
550 * @param argc Standard main() style argc.
551 * @param argv Standard main() style argv. Initial components are already
555 int net_rpc_info(struct net_context *c, int argc, const char **argv)
557 if (c->display_usage) {
562 _("Display information about the domain"));
566 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
567 NET_FLAGS_PDC, rpc_info_internals,
572 * Fetch domain SID into the local secrets.tdb.
574 * All parameters are provided by the run_rpc_command function, except for
575 * argc, argv which are passed through.
577 * @param domain_sid The domain sid acquired from the remote server.
578 * @param cli A cli_state connected to the server.
579 * @param mem_ctx Talloc context, destroyed on completion of the function.
580 * @param argc Standard main() style argc.
581 * @param argv Standard main() style argv. Initial components are already
584 * @return Normal NTSTATUS return.
587 static NTSTATUS rpc_getsid_internals(struct net_context *c,
588 const DOM_SID *domain_sid,
589 const char *domain_name,
590 struct cli_state *cli,
591 struct rpc_pipe_client *pipe_hnd,
598 sid_to_fstring(sid_str, domain_sid);
599 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
600 sid_str, domain_name);
602 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
603 DEBUG(0,("Can't store domain SID\n"));
604 return NT_STATUS_UNSUCCESSFUL;
611 * 'net rpc getsid' entrypoint.
612 * @param argc Standard main() style argc.
613 * @param argv Standard main() style argv. Initial components are already
617 int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
619 int conn_flags = NET_FLAGS_PDC;
621 if (!c->opt_user_specified) {
622 conn_flags |= NET_FLAGS_ANONYMOUS;
625 if (c->display_usage) {
630 _("Fetch domain SID into local secrets.tdb"));
634 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
636 rpc_getsid_internals,
640 /****************************************************************************/
643 * Basic usage function for 'net rpc user'.
644 * @param argc Standard main() style argc.
645 * @param argv Standard main() style argv. Initial components are already
649 static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
651 return net_user_usage(c, argc, argv);
655 * Add a new user to a remote RPC server.
657 * @param argc Standard main() style argc.
658 * @param argv Standard main() style argv. Initial components are already
661 * @return A shell status integer (0 for success).
664 static int rpc_user_add(struct net_context *c, int argc, const char **argv)
666 NET_API_STATUS status;
667 struct USER_INFO_1 info1;
668 uint32_t parm_error = 0;
670 if (argc < 1 || c->display_usage) {
671 rpc_user_usage(c, argc, argv);
677 info1.usri1_name = argv[0];
679 info1.usri1_password = argv[1];
682 status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
685 d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
686 argv[0], libnetapi_get_error_string(c->netapi_ctx,
690 d_printf(_("Added user '%s'.\n"), argv[0]);
697 * Rename a user on a remote RPC server.
699 * @param argc Standard main() style argc.
700 * @param argv Standard main() style argv. Initial components are already
703 * @return A shell status integer (0 for success).
706 static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
708 NET_API_STATUS status;
709 struct USER_INFO_0 u0;
710 uint32_t parm_err = 0;
712 if (argc != 2 || c->display_usage) {
713 rpc_user_usage(c, argc, argv);
717 u0.usri0_name = argv[1];
719 status = NetUserSetInfo(c->opt_host, argv[0],
720 0, (uint8_t *)&u0, &parm_err);
723 _("Failed to rename user from %s to %s - %s\n"),
725 libnetapi_get_error_string(c->netapi_ctx, status));
727 d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
734 * Set a user's primary group
736 * @param argc Standard main() style argc.
737 * @param argv Standard main() style argv. Initial components are already
740 * @return A shell status integer (0 for success).
743 static int rpc_user_setprimarygroup(struct net_context *c, int argc,
746 NET_API_STATUS status;
748 struct GROUP_INFO_2 *g2;
749 struct USER_INFO_1051 u1051;
750 uint32_t parm_err = 0;
752 if (argc != 2 || c->display_usage) {
753 rpc_user_usage(c, argc, argv);
757 status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
759 d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
761 libnetapi_get_error_string(c->netapi_ctx, status));
764 g2 = (struct GROUP_INFO_2 *)buffer;
766 u1051.usri1051_primary_group_id = g2->grpi2_group_id;
768 NetApiBufferFree(buffer);
770 status = NetUserSetInfo(c->opt_host, argv[0], 1051,
771 (uint8_t *)&u1051, &parm_err);
774 _("Failed to set user's primary group %s to %s - "
775 "%s\n"), argv[0], argv[1],
776 libnetapi_get_error_string(c->netapi_ctx, status));
778 d_printf(_("Set primary group of user %s to %s\n"), argv[0],
785 * Delete a user from a remote RPC server.
787 * @param argc Standard main() style argc.
788 * @param argv Standard main() style argv. Initial components are already
791 * @return A shell status integer (0 for success).
794 static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
796 NET_API_STATUS status;
798 if (argc < 1 || c->display_usage) {
799 rpc_user_usage(c, argc, argv);
803 status = NetUserDel(c->opt_host, argv[0]);
806 d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
808 libnetapi_get_error_string(c->netapi_ctx, status));
811 d_printf(_("Deleted user '%s'.\n"), argv[0]);
818 * Set a user's password on a remote RPC server.
820 * @param argc Standard main() style argc.
821 * @param argv Standard main() style argv. Initial components are already
824 * @return A shell status integer (0 for success).
827 static int rpc_user_password(struct net_context *c, int argc, const char **argv)
829 NET_API_STATUS status;
831 struct USER_INFO_1003 u1003;
832 uint32_t parm_err = 0;
835 if (argc < 1 || c->display_usage) {
836 rpc_user_usage(c, argc, argv);
841 u1003.usri1003_password = argv[1];
843 ret = asprintf(&prompt, _("Enter new password for %s:"),
848 u1003.usri1003_password = talloc_strdup(c, getpass(prompt));
850 if (u1003.usri1003_password == NULL) {
855 status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
857 /* Display results */
860 _("Failed to set password for '%s' with error: %s.\n"),
861 argv[0], libnetapi_get_error_string(c->netapi_ctx,
870 * List a user's groups from a remote RPC server.
872 * @param argc Standard main() style argc.
873 * @param argv Standard main() style argv. Initial components are already
876 * @return A shell status integer (0 for success)
879 static int rpc_user_info(struct net_context *c, int argc, const char **argv)
882 NET_API_STATUS status;
883 struct GROUP_USERS_INFO_0 *u0 = NULL;
884 uint32_t entries_read = 0;
885 uint32_t total_entries = 0;
889 if (argc < 1 || c->display_usage) {
890 rpc_user_usage(c, argc, argv);
894 status = NetUserGetGroups(c->opt_host,
897 (uint8_t **)(void *)&u0,
903 _("Failed to get groups for '%s' with error: %s.\n"),
904 argv[0], libnetapi_get_error_string(c->netapi_ctx,
909 for (i=0; i < entries_read; i++) {
910 printf("%s\n", u0->grui0_name);
918 * List users on a remote RPC server.
920 * All parameters are provided by the run_rpc_command function, except for
921 * argc, argv which are passed through.
923 * @param domain_sid The domain sid acquired from the remote server.
924 * @param cli A cli_state connected to the server.
925 * @param mem_ctx Talloc context, destroyed on completion of the function.
926 * @param argc Standard main() style argc.
927 * @param argv Standard main() style argv. Initial components are already
930 * @return Normal NTSTATUS return.
933 static int rpc_user_list(struct net_context *c, int argc, const char **argv)
935 NET_API_STATUS status;
936 uint32_t start_idx=0, num_entries, i, loop_count = 0;
937 struct NET_DISPLAY_USER *info = NULL;
940 /* Query domain users */
941 if (c->opt_long_list_entries)
942 d_printf(_("\nUser name Comment"
943 "\n-----------------------------\n"));
945 uint32_t max_entries, max_size;
947 get_query_dispinfo_params(
948 loop_count, &max_entries, &max_size);
950 status = NetQueryDisplayInformation(c->opt_host,
957 if (status != 0 && status != ERROR_MORE_DATA) {
961 info = (struct NET_DISPLAY_USER *)buffer;
963 for (i = 0; i < num_entries; i++) {
965 if (c->opt_long_list_entries)
966 printf("%-21.21s %s\n", info->usri1_name,
967 info->usri1_comment);
969 printf("%s\n", info->usri1_name);
973 NetApiBufferFree(buffer);
976 start_idx += num_entries;
978 } while (status == ERROR_MORE_DATA);
984 * 'net rpc user' entrypoint.
985 * @param argc Standard main() style argc.
986 * @param argv Standard main() style argv. Initial components are already
990 int net_rpc_user(struct net_context *c, int argc, const char **argv)
992 NET_API_STATUS status;
994 struct functable func[] = {
999 N_("Add specified user"),
1000 N_("net rpc user add\n"
1001 " Add specified user")
1007 N_("List domain groups of user"),
1008 N_("net rpc user info\n"
1009 " Lis domain groups of user")
1015 N_("Remove specified user"),
1016 N_("net rpc user delete\n"
1017 " Remove specified user")
1023 N_("Change user password"),
1024 N_("net rpc user password\n"
1025 " Change user password")
1031 N_("Rename specified user"),
1032 N_("net rpc user rename\n"
1033 " Rename specified user")
1037 rpc_user_setprimarygroup,
1039 "Set a user's primary group",
1040 "net rpc user setprimarygroup\n"
1041 " Set a user's primary group"
1043 {NULL, NULL, 0, NULL, NULL}
1046 status = libnetapi_init(&c->netapi_ctx);
1050 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
1051 libnetapi_set_password(c->netapi_ctx, c->opt_password);
1052 if (c->opt_kerberos) {
1053 libnetapi_set_use_kerberos(c->netapi_ctx);
1057 if (c->display_usage) {
1062 _("List all users"));
1063 net_display_usage_from_functable(func);
1067 return rpc_user_list(c, argc, argv);
1070 return net_run_function(c, argc, argv, "net rpc user", func);
1073 static NTSTATUS rpc_sh_user_list(struct net_context *c,
1074 TALLOC_CTX *mem_ctx,
1075 struct rpc_sh_ctx *ctx,
1076 struct rpc_pipe_client *pipe_hnd,
1077 int argc, const char **argv)
1079 return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1082 static NTSTATUS rpc_sh_user_info(struct net_context *c,
1083 TALLOC_CTX *mem_ctx,
1084 struct rpc_sh_ctx *ctx,
1085 struct rpc_pipe_client *pipe_hnd,
1086 int argc, const char **argv)
1088 return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1091 static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1092 TALLOC_CTX *mem_ctx,
1093 struct rpc_sh_ctx *ctx,
1094 struct rpc_pipe_client *pipe_hnd,
1095 int argc, const char **argv,
1097 struct net_context *c,
1098 TALLOC_CTX *mem_ctx,
1099 struct rpc_sh_ctx *ctx,
1100 struct rpc_pipe_client *pipe_hnd,
1101 struct policy_handle *user_hnd,
1102 int argc, const char **argv))
1104 struct policy_handle connect_pol, domain_pol, user_pol;
1105 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1108 enum lsa_SidType type;
1111 d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1113 return NT_STATUS_INVALID_PARAMETER;
1116 ZERO_STRUCT(connect_pol);
1117 ZERO_STRUCT(domain_pol);
1118 ZERO_STRUCT(user_pol);
1120 result = net_rpc_lookup_name(c, mem_ctx, rpc_pipe_np_smb_conn(pipe_hnd),
1121 argv[0], NULL, NULL, &sid, &type);
1122 if (!NT_STATUS_IS_OK(result)) {
1123 d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1128 if (type != SID_NAME_USER) {
1129 d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1130 sid_type_lookup(type));
1131 result = NT_STATUS_NO_SUCH_USER;
1135 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1136 d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1137 result = NT_STATUS_NO_SUCH_USER;
1141 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1143 MAXIMUM_ALLOWED_ACCESS,
1145 if (!NT_STATUS_IS_OK(result)) {
1149 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1151 MAXIMUM_ALLOWED_ACCESS,
1154 if (!NT_STATUS_IS_OK(result)) {
1158 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1160 MAXIMUM_ALLOWED_ACCESS,
1163 if (!NT_STATUS_IS_OK(result)) {
1167 result = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1170 if (is_valid_policy_hnd(&user_pol)) {
1171 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1173 if (is_valid_policy_hnd(&domain_pol)) {
1174 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
1176 if (is_valid_policy_hnd(&connect_pol)) {
1177 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1182 static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1183 TALLOC_CTX *mem_ctx,
1184 struct rpc_sh_ctx *ctx,
1185 struct rpc_pipe_client *pipe_hnd,
1186 struct policy_handle *user_hnd,
1187 int argc, const char **argv)
1190 union samr_UserInfo *info = NULL;
1193 d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1195 return NT_STATUS_INVALID_PARAMETER;
1198 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1202 if (!NT_STATUS_IS_OK(result)) {
1206 d_printf(_("user rid: %d, group rid: %d\n"),
1208 info->info21.primary_gid);
1213 static NTSTATUS rpc_sh_user_show(struct net_context *c,
1214 TALLOC_CTX *mem_ctx,
1215 struct rpc_sh_ctx *ctx,
1216 struct rpc_pipe_client *pipe_hnd,
1217 int argc, const char **argv)
1219 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1220 rpc_sh_user_show_internals);
1223 #define FETCHSTR(name, rec) \
1224 do { if (strequal(ctx->thiscmd, name)) { \
1225 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1228 #define SETSTR(name, rec, flag) \
1229 do { if (strequal(ctx->thiscmd, name)) { \
1230 init_lsa_String(&(info->info21.rec), argv[0]); \
1231 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1234 static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1235 TALLOC_CTX *mem_ctx,
1236 struct rpc_sh_ctx *ctx,
1237 struct rpc_pipe_client *pipe_hnd,
1238 struct policy_handle *user_hnd,
1239 int argc, const char **argv)
1242 const char *username;
1243 const char *oldval = "";
1244 union samr_UserInfo *info = NULL;
1247 d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1248 _("Usage:"), ctx->whoami);
1249 return NT_STATUS_INVALID_PARAMETER;
1252 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1256 if (!NT_STATUS_IS_OK(result)) {
1260 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1262 FETCHSTR("fullname", full_name);
1263 FETCHSTR("homedir", home_directory);
1264 FETCHSTR("homedrive", home_drive);
1265 FETCHSTR("logonscript", logon_script);
1266 FETCHSTR("profilepath", profile_path);
1267 FETCHSTR("description", description);
1270 d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1274 if (strcmp(argv[0], "NULL") == 0) {
1278 ZERO_STRUCT(info->info21);
1280 SETSTR("fullname", full_name, FULL_NAME);
1281 SETSTR("homedir", home_directory, HOME_DIRECTORY);
1282 SETSTR("homedrive", home_drive, HOME_DRIVE);
1283 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1284 SETSTR("profilepath", profile_path, PROFILE_PATH);
1285 SETSTR("description", description, DESCRIPTION);
1287 result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
1292 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1293 ctx->thiscmd, oldval, argv[0]);
1300 #define HANDLEFLG(name, rec) \
1301 do { if (strequal(ctx->thiscmd, name)) { \
1302 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1304 newflags = oldflags | ACB_##rec; \
1306 newflags = oldflags & ~ACB_##rec; \
1309 static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1310 TALLOC_CTX *mem_ctx,
1311 struct rpc_sh_ctx *ctx,
1312 struct rpc_pipe_client *pipe_hnd,
1313 int argc, const char **argv)
1315 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1316 rpc_sh_user_str_edit_internals);
1319 static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1320 TALLOC_CTX *mem_ctx,
1321 struct rpc_sh_ctx *ctx,
1322 struct rpc_pipe_client *pipe_hnd,
1323 struct policy_handle *user_hnd,
1324 int argc, const char **argv)
1327 const char *username;
1328 const char *oldval = "unknown";
1329 uint32 oldflags, newflags;
1331 union samr_UserInfo *info = NULL;
1334 ((argc == 1) && !strequal(argv[0], "yes") &&
1335 !strequal(argv[0], "no"))) {
1336 /* TRANSATORS: The yes|no here are program keywords. Please do
1338 d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1340 return NT_STATUS_INVALID_PARAMETER;
1343 newval = strequal(argv[0], "yes");
1345 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1349 if (!NT_STATUS_IS_OK(result)) {
1353 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1354 oldflags = info->info21.acct_flags;
1355 newflags = info->info21.acct_flags;
1357 HANDLEFLG("disabled", DISABLED);
1358 HANDLEFLG("pwnotreq", PWNOTREQ);
1359 HANDLEFLG("autolock", AUTOLOCK);
1360 HANDLEFLG("pwnoexp", PWNOEXP);
1363 d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1368 ZERO_STRUCT(info->info21);
1370 info->info21.acct_flags = newflags;
1371 info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1373 result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
1378 if (NT_STATUS_IS_OK(result)) {
1379 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1380 ctx->thiscmd, oldval, argv[0]);
1388 static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1389 TALLOC_CTX *mem_ctx,
1390 struct rpc_sh_ctx *ctx,
1391 struct rpc_pipe_client *pipe_hnd,
1392 int argc, const char **argv)
1394 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1395 rpc_sh_user_flag_edit_internals);
1398 struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1399 TALLOC_CTX *mem_ctx,
1400 struct rpc_sh_ctx *ctx)
1402 static struct rpc_sh_cmd cmds[] = {
1404 { "fullname", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1405 N_("Show/Set a user's full name") },
1407 { "homedir", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1408 N_("Show/Set a user's home directory") },
1410 { "homedrive", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1411 N_("Show/Set a user's home drive") },
1413 { "logonscript", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1414 N_("Show/Set a user's logon script") },
1416 { "profilepath", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1417 N_("Show/Set a user's profile path") },
1419 { "description", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1420 N_("Show/Set a user's description") },
1422 { "disabled", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1423 N_("Show/Set whether a user is disabled") },
1425 { "autolock", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1426 N_("Show/Set whether a user locked out") },
1428 { "pwnotreq", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1429 N_("Show/Set whether a user does not need a password") },
1431 { "pwnoexp", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1432 N_("Show/Set whether a user's password does not expire") },
1434 { NULL, NULL, 0, NULL, NULL }
1440 struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1441 TALLOC_CTX *mem_ctx,
1442 struct rpc_sh_ctx *ctx)
1444 static struct rpc_sh_cmd cmds[] = {
1446 { "list", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_list,
1447 N_("List available users") },
1449 { "info", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_info,
1450 N_("List the domain groups a user is member of") },
1452 { "show", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_show,
1453 N_("Show info about a user") },
1455 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1456 N_("Show/Modify a user's fields") },
1458 { NULL, NULL, 0, NULL, NULL }
1464 /****************************************************************************/
1467 * Basic usage function for 'net rpc group'.
1468 * @param argc Standard main() style argc.
1469 * @param argv Standard main() style argv. Initial components are already
1473 static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1475 return net_group_usage(c, argc, argv);
1479 * Delete group on a remote RPC server.
1481 * All parameters are provided by the run_rpc_command function, except for
1482 * argc, argv which are passed through.
1484 * @param domain_sid The domain sid acquired from the remote server.
1485 * @param cli A cli_state connected to the server.
1486 * @param mem_ctx Talloc context, destroyed on completion of the function.
1487 * @param argc Standard main() style argc.
1488 * @param argv Standard main() style argv. Initial components are already
1491 * @return Normal NTSTATUS return.
1494 static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1495 const DOM_SID *domain_sid,
1496 const char *domain_name,
1497 struct cli_state *cli,
1498 struct rpc_pipe_client *pipe_hnd,
1499 TALLOC_CTX *mem_ctx,
1503 struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1504 bool group_is_primary = false;
1505 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1507 struct samr_RidTypeArray *rids = NULL;
1510 /* struct samr_RidWithAttribute *user_gids; */
1512 struct samr_Ids group_rids, name_types;
1513 struct lsa_String lsa_acct_name;
1514 union samr_UserInfo *info = NULL;
1516 if (argc < 1 || c->display_usage) {
1517 rpc_group_usage(c, argc,argv);
1518 return NT_STATUS_OK; /* ok? */
1521 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1523 MAXIMUM_ALLOWED_ACCESS,
1526 if (!NT_STATUS_IS_OK(result)) {
1527 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1531 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1533 MAXIMUM_ALLOWED_ACCESS,
1534 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1537 if (!NT_STATUS_IS_OK(result)) {
1538 d_fprintf(stderr, _("Request open_domain failed\n"));
1542 init_lsa_String(&lsa_acct_name, argv[0]);
1544 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1550 if (!NT_STATUS_IS_OK(result)) {
1551 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1555 switch (name_types.ids[0])
1557 case SID_NAME_DOM_GRP:
1558 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1560 MAXIMUM_ALLOWED_ACCESS,
1563 if (!NT_STATUS_IS_OK(result)) {
1564 d_fprintf(stderr, _("Request open_group failed"));
1568 group_rid = group_rids.ids[0];
1570 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
1574 if (!NT_STATUS_IS_OK(result)) {
1576 _("Unable to query group members of %s"),
1581 if (c->opt_verbose) {
1583 _("Domain Group %s (rid: %d) has %d members\n"),
1584 argv[0],group_rid, rids->count);
1587 /* Check if group is anyone's primary group */
1588 for (i = 0; i < rids->count; i++)
1590 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1592 MAXIMUM_ALLOWED_ACCESS,
1596 if (!NT_STATUS_IS_OK(result)) {
1598 _("Unable to open group member %d\n"),
1603 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1608 if (!NT_STATUS_IS_OK(result)) {
1610 _("Unable to lookup userinfo for group "
1616 if (info->info21.primary_gid == group_rid) {
1617 if (c->opt_verbose) {
1618 d_printf(_("Group is primary group "
1620 info->info21.account_name.string);
1622 group_is_primary = true;
1625 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1628 if (group_is_primary) {
1629 d_fprintf(stderr, _("Unable to delete group because "
1630 "some of it's members have it as primary "
1632 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1636 /* remove all group members */
1637 for (i = 0; i < rids->count; i++)
1640 d_printf(_("Remove group member %d..."),
1642 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
1646 if (NT_STATUS_IS_OK(result)) {
1648 d_printf(_("ok\n"));
1651 d_printf("%s\n", _("failed"));
1656 result = rpccli_samr_DeleteDomainGroup(pipe_hnd, mem_ctx,
1660 /* removing a local group is easier... */
1661 case SID_NAME_ALIAS:
1662 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1664 MAXIMUM_ALLOWED_ACCESS,
1668 if (!NT_STATUS_IS_OK(result)) {
1669 d_fprintf(stderr, _("Request open_alias failed\n"));
1673 result = rpccli_samr_DeleteDomAlias(pipe_hnd, mem_ctx,
1677 d_fprintf(stderr, _("%s is of type %s. This command is only "
1678 "for deleting local or global groups\n"),
1679 argv[0],sid_type_lookup(name_types.ids[0]));
1680 result = NT_STATUS_UNSUCCESSFUL;
1684 if (NT_STATUS_IS_OK(result)) {
1686 d_printf(_("Deleted %s '%s'\n"),
1687 sid_type_lookup(name_types.ids[0]), argv[0]);
1689 d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
1690 get_friendly_nt_error_msg(result));
1698 static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
1700 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
1701 rpc_group_delete_internals, argc,argv);
1704 static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
1706 NET_API_STATUS status;
1707 struct GROUP_INFO_1 info1;
1708 uint32_t parm_error = 0;
1710 if (argc != 1 || c->display_usage) {
1711 rpc_group_usage(c, argc, argv);
1717 info1.grpi1_name = argv[0];
1718 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1719 info1.grpi1_comment = c->opt_comment;
1722 status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1726 _("Failed to add group '%s' with error: %s.\n"),
1727 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1731 d_printf(_("Added group '%s'.\n"), argv[0]);
1737 static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
1739 NET_API_STATUS status;
1740 struct LOCALGROUP_INFO_1 info1;
1741 uint32_t parm_error = 0;
1743 if (argc != 1 || c->display_usage) {
1744 rpc_group_usage(c, argc, argv);
1750 info1.lgrpi1_name = argv[0];
1751 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1752 info1.lgrpi1_comment = c->opt_comment;
1755 status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1759 _("Failed to add alias '%s' with error: %s.\n"),
1760 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1764 d_printf(_("Added alias '%s'.\n"), argv[0]);
1770 static int rpc_group_add(struct net_context *c, int argc, const char **argv)
1772 if (c->opt_localgroup)
1773 return rpc_alias_add_internals(c, argc, argv);
1775 return rpc_group_add_internals(c, argc, argv);
1778 static NTSTATUS get_sid_from_name(struct cli_state *cli,
1779 TALLOC_CTX *mem_ctx,
1782 enum lsa_SidType *type)
1784 DOM_SID *sids = NULL;
1785 enum lsa_SidType *types = NULL;
1786 struct rpc_pipe_client *pipe_hnd = NULL;
1787 struct policy_handle lsa_pol;
1788 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1790 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
1792 if (!NT_STATUS_IS_OK(result)) {
1796 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
1797 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
1799 if (!NT_STATUS_IS_OK(result)) {
1803 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
1804 &name, NULL, 1, &sids, &types);
1806 if (NT_STATUS_IS_OK(result)) {
1807 sid_copy(sid, &sids[0]);
1811 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
1815 TALLOC_FREE(pipe_hnd);
1818 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
1820 /* Try as S-1-5-whatever */
1824 if (string_to_sid(&tmp_sid, name)) {
1825 sid_copy(sid, &tmp_sid);
1826 *type = SID_NAME_UNKNOWN;
1827 result = NT_STATUS_OK;
1834 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
1835 TALLOC_CTX *mem_ctx,
1836 const DOM_SID *group_sid,
1839 struct policy_handle connect_pol, domain_pol;
1842 struct policy_handle group_pol;
1844 struct samr_Ids rids, rid_types;
1845 struct lsa_String lsa_acct_name;
1849 sid_copy(&sid, group_sid);
1851 if (!sid_split_rid(&sid, &group_rid)) {
1852 return NT_STATUS_UNSUCCESSFUL;
1855 /* Get sam policy handle */
1856 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1858 MAXIMUM_ALLOWED_ACCESS,
1860 if (!NT_STATUS_IS_OK(result)) {
1864 /* Get domain policy handle */
1865 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1867 MAXIMUM_ALLOWED_ACCESS,
1870 if (!NT_STATUS_IS_OK(result)) {
1874 init_lsa_String(&lsa_acct_name, member);
1876 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1883 if (!NT_STATUS_IS_OK(result)) {
1884 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
1889 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1891 MAXIMUM_ALLOWED_ACCESS,
1895 if (!NT_STATUS_IS_OK(result)) {
1899 result = rpccli_samr_AddGroupMember(pipe_hnd, mem_ctx,
1902 0x0005); /* unknown flags */
1905 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1909 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
1910 TALLOC_CTX *mem_ctx,
1911 const DOM_SID *alias_sid,
1914 struct policy_handle connect_pol, domain_pol;
1917 struct policy_handle alias_pol;
1920 enum lsa_SidType member_type;
1924 sid_copy(&sid, alias_sid);
1926 if (!sid_split_rid(&sid, &alias_rid)) {
1927 return NT_STATUS_UNSUCCESSFUL;
1930 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
1931 member, &member_sid, &member_type);
1933 if (!NT_STATUS_IS_OK(result)) {
1934 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
1939 /* Get sam policy handle */
1940 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1942 MAXIMUM_ALLOWED_ACCESS,
1944 if (!NT_STATUS_IS_OK(result)) {
1948 /* Get domain policy handle */
1949 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1951 MAXIMUM_ALLOWED_ACCESS,
1954 if (!NT_STATUS_IS_OK(result)) {
1958 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1960 MAXIMUM_ALLOWED_ACCESS,
1964 if (!NT_STATUS_IS_OK(result)) {
1968 result = rpccli_samr_AddAliasMember(pipe_hnd, mem_ctx,
1972 if (!NT_STATUS_IS_OK(result)) {
1977 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1981 static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
1982 const DOM_SID *domain_sid,
1983 const char *domain_name,
1984 struct cli_state *cli,
1985 struct rpc_pipe_client *pipe_hnd,
1986 TALLOC_CTX *mem_ctx,
1991 enum lsa_SidType group_type;
1993 if (argc != 2 || c->display_usage) {
1996 _("net rpc group addmem <group> <member>\n"
1997 " Add a member to a group\n"
1998 " group\tGroup to add member to\n"
1999 " member\tMember to add to group\n"));
2000 return NT_STATUS_UNSUCCESSFUL;
2003 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2004 &group_sid, &group_type))) {
2005 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2007 return NT_STATUS_UNSUCCESSFUL;
2010 if (group_type == SID_NAME_DOM_GRP) {
2011 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2012 &group_sid, argv[1]);
2014 if (!NT_STATUS_IS_OK(result)) {
2015 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2016 argv[1], argv[0], nt_errstr(result));
2021 if (group_type == SID_NAME_ALIAS) {
2022 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2023 &group_sid, argv[1]);
2025 if (!NT_STATUS_IS_OK(result)) {
2026 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2027 argv[1], argv[0], nt_errstr(result));
2032 d_fprintf(stderr, _("Can only add members to global or local groups "
2033 "which %s is not\n"), argv[0]);
2035 return NT_STATUS_UNSUCCESSFUL;
2038 static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2040 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2041 rpc_group_addmem_internals,
2045 static NTSTATUS rpc_del_groupmem(struct net_context *c,
2046 struct rpc_pipe_client *pipe_hnd,
2047 TALLOC_CTX *mem_ctx,
2048 const DOM_SID *group_sid,
2051 struct policy_handle connect_pol, domain_pol;
2054 struct policy_handle group_pol;
2056 struct samr_Ids rids, rid_types;
2057 struct lsa_String lsa_acct_name;
2061 sid_copy(&sid, group_sid);
2063 if (!sid_split_rid(&sid, &group_rid))
2064 return NT_STATUS_UNSUCCESSFUL;
2066 /* Get sam policy handle */
2067 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2069 MAXIMUM_ALLOWED_ACCESS,
2071 if (!NT_STATUS_IS_OK(result))
2074 /* Get domain policy handle */
2075 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2077 MAXIMUM_ALLOWED_ACCESS,
2080 if (!NT_STATUS_IS_OK(result))
2083 init_lsa_String(&lsa_acct_name, member);
2085 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2091 if (!NT_STATUS_IS_OK(result)) {
2092 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2097 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2099 MAXIMUM_ALLOWED_ACCESS,
2103 if (!NT_STATUS_IS_OK(result))
2106 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
2111 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2115 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2116 TALLOC_CTX *mem_ctx,
2117 const DOM_SID *alias_sid,
2120 struct policy_handle connect_pol, domain_pol;
2123 struct policy_handle alias_pol;
2126 enum lsa_SidType member_type;
2130 sid_copy(&sid, alias_sid);
2132 if (!sid_split_rid(&sid, &alias_rid))
2133 return NT_STATUS_UNSUCCESSFUL;
2135 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2136 member, &member_sid, &member_type);
2138 if (!NT_STATUS_IS_OK(result)) {
2139 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2144 /* Get sam policy handle */
2145 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2147 MAXIMUM_ALLOWED_ACCESS,
2149 if (!NT_STATUS_IS_OK(result)) {
2153 /* Get domain policy handle */
2154 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2156 MAXIMUM_ALLOWED_ACCESS,
2159 if (!NT_STATUS_IS_OK(result)) {
2163 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2165 MAXIMUM_ALLOWED_ACCESS,
2169 if (!NT_STATUS_IS_OK(result))
2172 result = rpccli_samr_DeleteAliasMember(pipe_hnd, mem_ctx,
2176 if (!NT_STATUS_IS_OK(result))
2180 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2184 static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2185 const DOM_SID *domain_sid,
2186 const char *domain_name,
2187 struct cli_state *cli,
2188 struct rpc_pipe_client *pipe_hnd,
2189 TALLOC_CTX *mem_ctx,
2194 enum lsa_SidType group_type;
2196 if (argc != 2 || c->display_usage) {
2199 _("net rpc group delmem <group> <member>\n"
2200 " Delete a member from a group\n"
2201 " group\tGroup to delete member from\n"
2202 " member\tMember to delete from group\n"));
2203 return NT_STATUS_UNSUCCESSFUL;
2206 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2207 &group_sid, &group_type))) {
2208 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2210 return NT_STATUS_UNSUCCESSFUL;
2213 if (group_type == SID_NAME_DOM_GRP) {
2214 NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2215 &group_sid, argv[1]);
2217 if (!NT_STATUS_IS_OK(result)) {
2218 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2219 argv[1], argv[0], nt_errstr(result));
2224 if (group_type == SID_NAME_ALIAS) {
2225 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2226 &group_sid, argv[1]);
2228 if (!NT_STATUS_IS_OK(result)) {
2229 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2230 argv[1], argv[0], nt_errstr(result));
2235 d_fprintf(stderr, _("Can only delete members from global or local "
2236 "groups which %s is not\n"), argv[0]);
2238 return NT_STATUS_UNSUCCESSFUL;
2241 static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2243 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2244 rpc_group_delmem_internals,
2249 * List groups on a remote RPC server.
2251 * All parameters are provided by the run_rpc_command function, except for
2252 * argc, argv which are passes through.
2254 * @param domain_sid The domain sid acquired from the remote server.
2255 * @param cli A cli_state connected to the server.
2256 * @param mem_ctx Talloc context, destroyed on completion of the function.
2257 * @param argc Standard main() style argc.
2258 * @param argv Standard main() style argv. Initial components are already
2261 * @return Normal NTSTATUS return.
2264 static NTSTATUS rpc_group_list_internals(struct net_context *c,
2265 const DOM_SID *domain_sid,
2266 const char *domain_name,
2267 struct cli_state *cli,
2268 struct rpc_pipe_client *pipe_hnd,
2269 TALLOC_CTX *mem_ctx,
2273 struct policy_handle connect_pol, domain_pol;
2274 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2275 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2276 struct samr_SamArray *groups = NULL;
2277 bool global = false;
2279 bool builtin = false;
2281 if (c->display_usage) {
2284 _("net rpc group list [global] [local] [builtin]\n"
2285 " List groups on RPC server\n"
2286 " global\tList global groups\n"
2287 " local\tList local groups\n"
2288 " builtin\tList builtin groups\n"
2289 " If none of global, local or builtin is "
2290 "specified, all three options are considered "
2292 return NT_STATUS_OK;
2301 for (i=0; i<argc; i++) {
2302 if (strequal(argv[i], "global"))
2305 if (strequal(argv[i], "local"))
2308 if (strequal(argv[i], "builtin"))
2312 /* Get sam policy handle */
2314 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2316 MAXIMUM_ALLOWED_ACCESS,
2318 if (!NT_STATUS_IS_OK(result)) {
2322 /* Get domain policy handle */
2324 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2326 MAXIMUM_ALLOWED_ACCESS,
2327 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2329 if (!NT_STATUS_IS_OK(result)) {
2333 /* Query domain groups */
2334 if (c->opt_long_list_entries)
2335 d_printf(_("\nGroup name Comment"
2336 "\n-----------------------------\n"));
2338 uint32_t max_size, total_size, returned_size;
2339 union samr_DispInfo info;
2343 get_query_dispinfo_params(
2344 loop_count, &max_entries, &max_size);
2346 result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx,
2355 num_entries = info.info3.count;
2356 start_idx += info.info3.count;
2358 if (!NT_STATUS_IS_OK(result) &&
2359 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2362 for (i = 0; i < num_entries; i++) {
2364 const char *group = NULL;
2365 const char *desc = NULL;
2367 group = info.info3.entries[i].account_name.string;
2368 desc = info.info3.entries[i].description.string;
2370 if (c->opt_long_list_entries)
2371 printf("%-21.21s %-50.50s\n",
2374 printf("%s\n", group);
2376 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2377 /* query domain aliases */
2382 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2388 if (!NT_STATUS_IS_OK(result) &&
2389 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2392 for (i = 0; i < num_entries; i++) {
2394 const char *description = NULL;
2396 if (c->opt_long_list_entries) {
2398 struct policy_handle alias_pol;
2399 union samr_AliasInfo *info = NULL;
2401 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2404 groups->entries[i].idx,
2406 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2410 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2412 description = info->description.string;
2416 if (description != NULL) {
2417 printf("%-21.21s %-50.50s\n",
2418 groups->entries[i].name.string,
2421 printf("%s\n", groups->entries[i].name.string);
2424 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2425 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2426 /* Get builtin policy handle */
2428 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2430 MAXIMUM_ALLOWED_ACCESS,
2431 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
2433 if (!NT_STATUS_IS_OK(result)) {
2436 /* query builtin aliases */
2439 if (!builtin) break;
2441 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2447 if (!NT_STATUS_IS_OK(result) &&
2448 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2451 for (i = 0; i < num_entries; i++) {
2453 const char *description = NULL;
2455 if (c->opt_long_list_entries) {
2457 struct policy_handle alias_pol;
2458 union samr_AliasInfo *info = NULL;
2460 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2463 groups->entries[i].idx,
2465 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2469 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2471 description = info->description.string;
2475 if (description != NULL) {
2476 printf("%-21.21s %-50.50s\n",
2477 groups->entries[i].name.string,
2480 printf("%s\n", groups->entries[i].name.string);
2483 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2489 static int rpc_group_list(struct net_context *c, int argc, const char **argv)
2491 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2492 rpc_group_list_internals,
2496 static NTSTATUS rpc_list_group_members(struct net_context *c,
2497 struct rpc_pipe_client *pipe_hnd,
2498 TALLOC_CTX *mem_ctx,
2499 const char *domain_name,
2500 const DOM_SID *domain_sid,
2501 struct policy_handle *domain_pol,
2505 struct policy_handle group_pol;
2506 uint32 num_members, *group_rids;
2508 struct samr_RidTypeArray *rids = NULL;
2509 struct lsa_Strings names;
2510 struct samr_Ids types;
2513 sid_to_fstring(sid_str, domain_sid);
2515 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2517 MAXIMUM_ALLOWED_ACCESS,
2521 if (!NT_STATUS_IS_OK(result))
2524 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
2528 if (!NT_STATUS_IS_OK(result))
2531 num_members = rids->count;
2532 group_rids = rids->rids;
2534 while (num_members > 0) {
2535 int this_time = 512;
2537 if (num_members < this_time)
2538 this_time = num_members;
2540 result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx,
2547 if (!NT_STATUS_IS_OK(result))
2550 /* We only have users as members, but make the output
2551 the same as the output of alias members */
2553 for (i = 0; i < this_time; i++) {
2555 if (c->opt_long_list_entries) {
2556 printf("%s-%d %s\\%s %d\n", sid_str,
2557 group_rids[i], domain_name,
2558 names.names[i].string,
2561 printf("%s\\%s\n", domain_name,
2562 names.names[i].string);
2566 num_members -= this_time;
2570 return NT_STATUS_OK;
2573 static NTSTATUS rpc_list_alias_members(struct net_context *c,
2574 struct rpc_pipe_client *pipe_hnd,
2575 TALLOC_CTX *mem_ctx,
2576 struct policy_handle *domain_pol,
2580 struct rpc_pipe_client *lsa_pipe;
2581 struct policy_handle alias_pol, lsa_pol;
2583 DOM_SID *alias_sids;
2586 enum lsa_SidType *types;
2588 struct lsa_SidArray sid_array;
2590 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2592 MAXIMUM_ALLOWED_ACCESS,
2596 if (!NT_STATUS_IS_OK(result))
2599 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
2603 if (!NT_STATUS_IS_OK(result)) {
2604 d_fprintf(stderr, _("Couldn't list alias members\n"));
2608 num_members = sid_array.num_sids;
2610 if (num_members == 0) {
2611 return NT_STATUS_OK;
2614 result = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd),
2615 &ndr_table_lsarpc.syntax_id,
2617 if (!NT_STATUS_IS_OK(result)) {
2618 d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
2619 nt_errstr(result) );
2623 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
2624 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2626 if (!NT_STATUS_IS_OK(result)) {
2627 d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
2628 TALLOC_FREE(lsa_pipe);
2632 alias_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
2634 d_fprintf(stderr, _("Out of memory\n"));
2635 TALLOC_FREE(lsa_pipe);
2636 return NT_STATUS_NO_MEMORY;
2639 for (i=0; i<num_members; i++) {
2640 sid_copy(&alias_sids[i], sid_array.sids[i].sid);
2643 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
2644 num_members, alias_sids,
2645 &domains, &names, &types);
2647 if (!NT_STATUS_IS_OK(result) &&
2648 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2649 d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
2650 TALLOC_FREE(lsa_pipe);
2654 for (i = 0; i < num_members; i++) {
2656 sid_to_fstring(sid_str, &alias_sids[i]);
2658 if (c->opt_long_list_entries) {
2659 printf("%s %s\\%s %d\n", sid_str,
2660 domains[i] ? domains[i] : _("*unknown*"),
2661 names[i] ? names[i] : _("*unknown*"), types[i]);
2664 printf("%s\\%s\n", domains[i], names[i]);
2666 printf("%s\n", sid_str);
2670 TALLOC_FREE(lsa_pipe);
2671 return NT_STATUS_OK;
2674 static NTSTATUS rpc_group_members_internals(struct net_context *c,
2675 const DOM_SID *domain_sid,
2676 const char *domain_name,
2677 struct cli_state *cli,
2678 struct rpc_pipe_client *pipe_hnd,
2679 TALLOC_CTX *mem_ctx,
2684 struct policy_handle connect_pol, domain_pol;
2685 struct samr_Ids rids, rid_types;
2686 struct lsa_String lsa_acct_name;
2688 /* Get sam policy handle */
2690 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2692 MAXIMUM_ALLOWED_ACCESS,
2695 if (!NT_STATUS_IS_OK(result))
2698 /* Get domain policy handle */
2700 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2702 MAXIMUM_ALLOWED_ACCESS,
2703 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2706 if (!NT_STATUS_IS_OK(result))
2709 init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
2711 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2718 if (!NT_STATUS_IS_OK(result)) {
2720 /* Ok, did not find it in the global sam, try with builtin */
2722 DOM_SID sid_Builtin;
2724 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2726 sid_copy(&sid_Builtin, &global_sid_Builtin);
2728 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2730 MAXIMUM_ALLOWED_ACCESS,
2734 if (!NT_STATUS_IS_OK(result)) {
2735 d_fprintf(stderr, _("Couldn't find group %s\n"),
2740 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2747 if (!NT_STATUS_IS_OK(result)) {
2748 d_fprintf(stderr, _("Couldn't find group %s\n"),
2754 if (rids.count != 1) {
2755 d_fprintf(stderr, _("Couldn't find group %s\n"),
2760 if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
2761 return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
2762 domain_sid, &domain_pol,
2766 if (rid_types.ids[0] == SID_NAME_ALIAS) {
2767 return rpc_list_alias_members(c, pipe_hnd, mem_ctx, &domain_pol,
2771 return NT_STATUS_NO_SUCH_GROUP;
2774 static int rpc_group_members(struct net_context *c, int argc, const char **argv)
2776 if (argc != 1 || c->display_usage) {
2777 return rpc_group_usage(c, argc, argv);
2780 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2781 rpc_group_members_internals,
2785 static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
2787 NET_API_STATUS status;
2788 struct GROUP_INFO_0 g0;
2792 d_printf(_("Usage:\n"));
2793 d_printf("net rpc group rename group newname\n");
2797 g0.grpi0_name = argv[1];
2799 status = NetGroupSetInfo(c->opt_host,
2806 d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
2807 argv[0], libnetapi_get_error_string(c->netapi_ctx,
2815 static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
2817 if (argc != 2 || c->display_usage) {
2818 return rpc_group_usage(c, argc, argv);
2821 return rpc_group_rename_internals(c, argc, argv);
2825 * 'net rpc group' entrypoint.
2826 * @param argc Standard main() style argc.
2827 * @param argv Standard main() style argv. Initial components are already
2831 int net_rpc_group(struct net_context *c, int argc, const char **argv)
2833 NET_API_STATUS status;
2835 struct functable func[] = {
2840 N_("Create specified group"),
2841 N_("net rpc group add\n"
2842 " Create specified group")
2848 N_("Delete specified group"),
2849 N_("net rpc group delete\n"
2850 " Delete specified group")
2856 N_("Add member to group"),
2857 N_("net rpc group addmem\n"
2858 " Add member to group")
2864 N_("Remove member from group"),
2865 N_("net rpc group delmem\n"
2866 " Remove member from group")
2873 N_("net rpc group list\n"
2880 N_("List group members"),
2881 N_("net rpc group members\n"
2882 " List group members")
2889 N_("net rpc group rename\n"
2892 {NULL, NULL, 0, NULL, NULL}
2895 status = libnetapi_init(&c->netapi_ctx);
2899 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
2900 libnetapi_set_password(c->netapi_ctx, c->opt_password);
2901 if (c->opt_kerberos) {
2902 libnetapi_set_use_kerberos(c->netapi_ctx);
2906 if (c->display_usage) {
2907 d_printf(_("Usage:\n"));
2908 d_printf(_("net rpc group\n"
2909 " Alias for net rpc group list global "
2910 "local builtin\n"));
2911 net_display_usage_from_functable(func);
2915 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2916 rpc_group_list_internals,
2920 return net_run_function(c, argc, argv, "net rpc group", func);
2923 /****************************************************************************/
2925 static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
2927 return net_share_usage(c, argc, argv);
2931 * Add a share on a remote RPC server.
2933 * @param argc Standard main() style argc.
2934 * @param argv Standard main() style argv. Initial components are already
2937 * @return A shell status integer (0 for success).
2940 static int rpc_share_add(struct net_context *c, int argc, const char **argv)
2942 NET_API_STATUS status;
2945 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
2946 uint32 num_users=0, perms=0;
2947 char *password=NULL; /* don't allow a share password */
2948 struct SHARE_INFO_2 i2;
2949 uint32_t parm_error = 0;
2951 if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
2952 return rpc_share_usage(c, argc, argv);
2955 if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
2959 path = strchr(sharename, '=');
2966 i2.shi2_netname = sharename;
2967 i2.shi2_type = type;
2968 i2.shi2_remark = c->opt_comment;
2969 i2.shi2_permissions = perms;
2970 i2.shi2_max_uses = c->opt_maxusers;
2971 i2.shi2_current_uses = num_users;
2972 i2.shi2_path = path;
2973 i2.shi2_passwd = password;
2975 status = NetShareAdd(c->opt_host,
2980 printf(_("NetShareAdd failed with: %s\n"),
2981 libnetapi_get_error_string(c->netapi_ctx, status));
2988 * Delete a share on a remote RPC server.
2990 * @param domain_sid The domain sid acquired from the remote server.
2991 * @param argc Standard main() style argc.
2992 * @param argv Standard main() style argv. Initial components are already
2995 * @return A shell status integer (0 for success).
2997 static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
2999 if (argc < 1 || c->display_usage) {
3000 return rpc_share_usage(c, argc, argv);
3003 return NetShareDel(c->opt_host, argv[0], 0);
3007 * Formatted print of share info
3009 * @param r pointer to SHARE_INFO_1 to format
3012 static void display_share_info_1(struct net_context *c,
3013 struct SHARE_INFO_1 *r)
3015 if (c->opt_long_list_entries) {
3016 d_printf("%-12s %-8.8s %-50s\n",
3018 net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3021 d_printf("%s\n", r->shi1_netname);
3025 static WERROR get_share_info(struct net_context *c,
3026 struct rpc_pipe_client *pipe_hnd,
3027 TALLOC_CTX *mem_ctx,
3031 struct srvsvc_NetShareInfoCtr *info_ctr)
3035 union srvsvc_NetShareInfo info;
3037 /* no specific share requested, enumerate all */
3040 uint32_t preferred_len = 0xffffffff;
3041 uint32_t total_entries = 0;
3042 uint32_t resume_handle = 0;
3044 info_ctr->level = level;
3046 status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, mem_ctx,
3056 /* request just one share */
3057 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
3064 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
3069 ZERO_STRUCTP(info_ctr);
3071 info_ctr->level = level;
3076 struct srvsvc_NetShareCtr1 *ctr1;
3078 ctr1 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr1);
3079 W_ERROR_HAVE_NO_MEMORY(ctr1);
3082 ctr1->array = info.info1;
3084 info_ctr->ctr.ctr1 = ctr1;
3088 struct srvsvc_NetShareCtr2 *ctr2;
3090 ctr2 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr2);
3091 W_ERROR_HAVE_NO_MEMORY(ctr2);
3094 ctr2->array = info.info2;
3096 info_ctr->ctr.ctr2 = ctr2;
3100 struct srvsvc_NetShareCtr502 *ctr502;
3102 ctr502 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr502);
3103 W_ERROR_HAVE_NO_MEMORY(ctr502);
3106 ctr502->array = info.info502;
3108 info_ctr->ctr.ctr502 = ctr502;
3116 * 'net rpc share list' entrypoint.
3117 * @param argc Standard main() style argc.
3118 * @param argv Standard main() style argv. Initial components are already
3121 static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3123 NET_API_STATUS status;
3124 struct SHARE_INFO_1 *i1 = NULL;
3125 uint32_t entries_read = 0;
3126 uint32_t total_entries = 0;
3127 uint32_t resume_handle = 0;
3128 uint32_t i, level = 1;
3130 if (c->display_usage) {
3132 "net rpc share list\n"
3135 _("List shares on remote server"));
3139 status = NetShareEnum(c->opt_host,
3141 (uint8_t **)(void *)&i1,
3150 /* Display results */
3152 if (c->opt_long_list_entries) {
3154 "\nEnumerating shared resources (exports) on remote server:\n\n"
3155 "\nShare name Type Description\n"
3156 "---------- ---- -----------\n"));
3158 for (i = 0; i < entries_read; i++)
3159 display_share_info_1(c, &i1[i]);
3164 static bool check_share_availability(struct cli_state *cli, const char *netname)
3168 status = cli_tcon_andx(cli, netname, "A:", "", 0);
3169 if (!NT_STATUS_IS_OK(status)) {
3170 d_printf(_("skipping [%s]: not a file share.\n"), netname);
3174 status = cli_tdis(cli);
3175 if (!NT_STATUS_IS_OK(status)) {
3176 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3183 static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3184 const char *netname, uint32 type)
3186 /* only support disk shares */
3187 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3188 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3193 /* skip builtin shares */
3194 /* FIXME: should print$ be added too ? */
3195 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3196 strequal(netname,"global"))
3199 if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3200 printf(_("excluding [%s]\n"), netname);
3204 return check_share_availability(cli, netname);
3208 * Migrate shares from a remote RPC server to the local RPC server.
3210 * All parameters are provided by the run_rpc_command function, except for
3211 * argc, argv which are passed through.
3213 * @param domain_sid The domain sid acquired from the remote server.
3214 * @param cli A cli_state connected to the server.
3215 * @param mem_ctx Talloc context, destroyed on completion of the function.
3216 * @param argc Standard main() style argc.
3217 * @param argv Standard main() style argv. Initial components are already
3220 * @return Normal NTSTATUS return.
3223 static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3224 const DOM_SID *domain_sid,
3225 const char *domain_name,
3226 struct cli_state *cli,
3227 struct rpc_pipe_client *pipe_hnd,
3228 TALLOC_CTX *mem_ctx,
3233 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3234 struct srvsvc_NetShareInfoCtr ctr_src;
3236 struct rpc_pipe_client *srvsvc_pipe = NULL;
3237 struct cli_state *cli_dst = NULL;
3238 uint32 level = 502; /* includes secdesc */
3239 uint32_t parm_error = 0;
3241 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3243 if (!W_ERROR_IS_OK(result))
3246 /* connect destination PI_SRVSVC */
3247 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3248 &ndr_table_srvsvc.syntax_id);
3249 if (!NT_STATUS_IS_OK(nt_status))
3253 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3255 union srvsvc_NetShareInfo info;
3256 struct srvsvc_NetShareInfo502 info502 =
3257 ctr_src.ctr.ctr502->array[i];
3259 /* reset error-code */
3260 nt_status = NT_STATUS_UNSUCCESSFUL;
3262 if (!check_share_sanity(c, cli, info502.name, info502.type))
3265 /* finally add the share on the dst server */
3267 printf(_("migrating: [%s], path: %s, comment: %s, without "
3269 info502.name, info502.path, info502.comment);
3271 info.info502 = &info502;
3273 nt_status = rpccli_srvsvc_NetShareAdd(srvsvc_pipe, mem_ctx,
3274 srvsvc_pipe->desthost,
3280 if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3281 printf(_(" [%s] does already exist\n"),
3286 if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) {
3287 printf(_("cannot add share: %s\n"), win_errstr(result));
3293 nt_status = NT_STATUS_OK;
3297 cli_shutdown(cli_dst);
3305 * Migrate shares from a RPC server to another.
3307 * @param argc Standard main() style argc.
3308 * @param argv Standard main() style argv. Initial components are already
3311 * @return A shell status integer (0 for success).
3313 static int rpc_share_migrate_shares(struct net_context *c, int argc,
3316 if (c->display_usage) {
3318 "net rpc share migrate shares\n"
3321 _("Migrate shares to local server"));
3326 printf(_("no server to migrate\n"));
3330 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3331 rpc_share_migrate_shares_internals,
3338 * @param f file_info
3339 * @param mask current search mask
3340 * @param state arg-pointer
3343 static void copy_fn(const char *mnt, file_info *f,
3344 const char *mask, void *state)
3346 static NTSTATUS nt_status;
3347 static struct copy_clistate *local_state;
3348 static fstring filename, new_mask;
3351 struct net_context *c;
3353 local_state = (struct copy_clistate *)state;
3354 nt_status = NT_STATUS_UNSUCCESSFUL;
3358 if (strequal(f->name, ".") || strequal(f->name, ".."))
3361 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3364 if (f->mode & aDIR) {
3366 DEBUG(3,("got dir: %s\n", f->name));
3368 fstrcpy(dir, local_state->cwd);
3370 fstrcat(dir, f->name);
3372 switch (net_mode_share)
3374 case NET_MODE_SHARE_MIGRATE:
3375 /* create that directory */
3376 nt_status = net_copy_file(c, local_state->mem_ctx,
3377 local_state->cli_share_src,
3378 local_state->cli_share_dst,
3380 c->opt_acls? true : false,
3381 c->opt_attrs? true : false,
3382 c->opt_timestamps? true:false,
3386 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3390 if (!NT_STATUS_IS_OK(nt_status))
3391 printf(_("could not handle dir %s: %s\n"),
3392 dir, nt_errstr(nt_status));
3394 /* search below that directory */
3395 fstrcpy(new_mask, dir);
3396 fstrcat(new_mask, "\\*");
3398 old_dir = local_state->cwd;
3399 local_state->cwd = dir;
3400 if (!sync_files(local_state, new_mask))
3401 printf(_("could not handle files\n"));
3402 local_state->cwd = old_dir;
3409 fstrcpy(filename, local_state->cwd);
3410 fstrcat(filename, "\\");
3411 fstrcat(filename, f->name);
3413 DEBUG(3,("got file: %s\n", filename));
3415 switch (net_mode_share)
3417 case NET_MODE_SHARE_MIGRATE:
3418 nt_status = net_copy_file(c, local_state->mem_ctx,
3419 local_state->cli_share_src,
3420 local_state->cli_share_dst,
3422 c->opt_acls? true : false,
3423 c->opt_attrs? true : false,
3424 c->opt_timestamps? true: false,
3428 d_fprintf(stderr, _("Unsupported file mode %d\n"),
3433 if (!NT_STATUS_IS_OK(nt_status))
3434 printf(_("could not handle file %s: %s\n"),
3435 filename, nt_errstr(nt_status));
3440 * sync files, can be called recursivly to list files
3441 * and then call copy_fn for each file
3443 * @param cp_clistate pointer to the copy_clistate we work with
3444 * @param mask the current search mask
3446 * @return Boolean result
3448 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3450 struct cli_state *targetcli;
3451 char *targetpath = NULL;
3453 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3455 if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
3456 mask, &targetcli, &targetpath ) ) {
3457 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
3459 mask, cli_errstr(cp_clistate->cli_share_src));
3463 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3464 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
3465 mask, cli_errstr(targetcli));
3474 * Set the top level directory permissions before we do any further copies.
3475 * Should set up ACL inheritance.
3478 bool copy_top_level_perms(struct net_context *c,
3479 struct copy_clistate *cp_clistate,
3480 const char *sharename)
3482 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3484 switch (net_mode_share) {
3485 case NET_MODE_SHARE_MIGRATE:
3486 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3487 nt_status = net_copy_fileattr(c,
3488 cp_clistate->mem_ctx,
3489 cp_clistate->cli_share_src,
3490 cp_clistate->cli_share_dst,
3492 c->opt_acls? true : false,
3493 c->opt_attrs? true : false,
3494 c->opt_timestamps? true: false,
3498 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3502 if (!NT_STATUS_IS_OK(nt_status)) {
3503 printf(_("Could handle directory attributes for top level "
3504 "directory of share %s. Error %s\n"),
3505 sharename, nt_errstr(nt_status));
3513 * Sync all files inside a remote share to another share (over smb).
3515 * All parameters are provided by the run_rpc_command function, except for
3516 * argc, argv which are passed through.
3518 * @param domain_sid The domain sid acquired from the remote server.
3519 * @param cli A cli_state connected to the server.
3520 * @param mem_ctx Talloc context, destroyed on completion of the function.
3521 * @param argc Standard main() style argc.
3522 * @param argv Standard main() style argv. Initial components are already
3525 * @return Normal NTSTATUS return.
3528 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
3529 const DOM_SID *domain_sid,
3530 const char *domain_name,
3531 struct cli_state *cli,
3532 struct rpc_pipe_client *pipe_hnd,
3533 TALLOC_CTX *mem_ctx,
3538 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3539 struct srvsvc_NetShareInfoCtr ctr_src;
3542 struct copy_clistate cp_clistate;
3543 bool got_src_share = false;
3544 bool got_dst_share = false;
3545 const char *mask = "\\*";
3548 dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
3550 nt_status = NT_STATUS_NO_MEMORY;
3554 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3557 if (!W_ERROR_IS_OK(result))
3560 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3562 struct srvsvc_NetShareInfo502 info502 =
3563 ctr_src.ctr.ctr502->array[i];
3565 if (!check_share_sanity(c, cli, info502.name, info502.type))
3568 /* one might not want to mirror whole discs :) */
3569 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
3570 d_printf(_("skipping [%s]: builtin/hidden share\n"),
3575 switch (net_mode_share)
3577 case NET_MODE_SHARE_MIGRATE:
3581 d_fprintf(stderr, _("Unsupported mode %d\n"),
3585 printf(_(" [%s] files and directories %s ACLs, %s DOS "
3588 c->opt_acls ? _("including") : _("without"),
3589 c->opt_attrs ? _("including") : _("without"),
3590 c->opt_timestamps ? _("(preserving timestamps)") : "");
3592 cp_clistate.mem_ctx = mem_ctx;
3593 cp_clistate.cli_share_src = NULL;
3594 cp_clistate.cli_share_dst = NULL;
3595 cp_clistate.cwd = NULL;
3596 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3599 /* open share source */
3600 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
3601 &cli->dest_ss, cli->desthost,
3602 info502.name, "A:");
3603 if (!NT_STATUS_IS_OK(nt_status))
3606 got_src_share = true;
3608 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3609 /* open share destination */
3610 nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
3611 NULL, dst, info502.name, "A:");
3612 if (!NT_STATUS_IS_OK(nt_status))
3615 got_dst_share = true;
3618 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
3619 d_fprintf(stderr, _("Could not handle the top level "
3620 "directory permissions for the "
3621 "share: %s\n"), info502.name);
3622 nt_status = NT_STATUS_UNSUCCESSFUL;
3626 if (!sync_files(&cp_clistate, mask)) {
3627 d_fprintf(stderr, _("could not handle files for share: "
3628 "%s\n"), info502.name);
3629 nt_status = NT_STATUS_UNSUCCESSFUL;
3634 nt_status = NT_STATUS_OK;
3639 cli_shutdown(cp_clistate.cli_share_src);
3642 cli_shutdown(cp_clistate.cli_share_dst);
3649 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
3651 if (c->display_usage) {
3653 "net share migrate files\n"
3656 _("Migrate files to local server"));
3661 d_printf(_("no server to migrate\n"));
3665 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3666 rpc_share_migrate_files_internals,
3671 * Migrate share-ACLs from a remote RPC server to the local RPC server.
3673 * All parameters are provided by the run_rpc_command function, except for
3674 * argc, argv which are passed through.
3676 * @param domain_sid The domain sid acquired from the remote server.
3677 * @param cli A cli_state connected to the server.
3678 * @param mem_ctx Talloc context, destroyed on completion of the function.
3679 * @param argc Standard main() style argc.
3680 * @param argv Standard main() style argv. Initial components are already
3683 * @return Normal NTSTATUS return.
3686 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
3687 const DOM_SID *domain_sid,
3688 const char *domain_name,
3689 struct cli_state *cli,
3690 struct rpc_pipe_client *pipe_hnd,
3691 TALLOC_CTX *mem_ctx,
3696 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3697 struct srvsvc_NetShareInfoCtr ctr_src;
3698 union srvsvc_NetShareInfo info;
3700 struct rpc_pipe_client *srvsvc_pipe = NULL;
3701 struct cli_state *cli_dst = NULL;
3702 uint32 level = 502; /* includes secdesc */
3703 uint32_t parm_error = 0;
3705 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3708 if (!W_ERROR_IS_OK(result))
3711 /* connect destination PI_SRVSVC */
3712 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3713 &ndr_table_srvsvc.syntax_id);
3714 if (!NT_STATUS_IS_OK(nt_status))
3718 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3720 struct srvsvc_NetShareInfo502 info502 =
3721 ctr_src.ctr.ctr502->array[i];
3723 /* reset error-code */
3724 nt_status = NT_STATUS_UNSUCCESSFUL;
3726 if (!check_share_sanity(c, cli, info502.name, info502.type))
3729 printf(_("migrating: [%s], path: %s, comment: %s, including "
3731 info502.name, info502.path, info502.comment);
3734 display_sec_desc(info502.sd_buf.sd);
3736 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3737 info.info502 = &info502;
3739 /* finally modify the share on the dst server */
3740 nt_status = rpccli_srvsvc_NetShareSetInfo(srvsvc_pipe, mem_ctx,
3741 srvsvc_pipe->desthost,
3747 if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) {
3748 printf(_("cannot set share-acl: %s\n"),
3749 win_errstr(result));
3755 nt_status = NT_STATUS_OK;
3759 cli_shutdown(cli_dst);
3767 * Migrate share-acls from a RPC server to another.
3769 * @param argc Standard main() style argc.
3770 * @param argv Standard main() style argv. Initial components are already
3773 * @return A shell status integer (0 for success).
3775 static int rpc_share_migrate_security(struct net_context *c, int argc,
3778 if (c->display_usage) {
3780 "net rpc share migrate security\n"
3783 _("Migrate share-acls to local server"));
3788 d_printf(_("no server to migrate\n"));
3792 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3793 rpc_share_migrate_security_internals,
3798 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3799 * from one server to another.
3801 * @param argc Standard main() style argc.
3802 * @param argv Standard main() style argv. Initial components are already
3805 * @return A shell status integer (0 for success).
3808 static int rpc_share_migrate_all(struct net_context *c, int argc,
3813 if (c->display_usage) {
3815 "net rpc share migrate all\n"
3818 _("Migrates shares including all share settings"));
3823 d_printf(_("no server to migrate\n"));
3827 /* order is important. we don't want to be locked out by the share-acl
3828 * before copying files - gd */
3830 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3831 rpc_share_migrate_shares_internals, argc, argv);
3835 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3836 rpc_share_migrate_files_internals, argc, argv);
3840 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3841 rpc_share_migrate_security_internals, argc,
3847 * 'net rpc share migrate' entrypoint.
3848 * @param argc Standard main() style argc.
3849 * @param argv Standard main() style argv. Initial components are already
3852 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
3855 struct functable func[] = {
3858 rpc_share_migrate_all,
3860 N_("Migrate shares from remote to local server"),
3861 N_("net rpc share migrate all\n"
3862 " Migrate shares from remote to local server")
3866 rpc_share_migrate_files,
3868 N_("Migrate files from remote to local server"),
3869 N_("net rpc share migrate files\n"
3870 " Migrate files from remote to local server")
3874 rpc_share_migrate_security,
3876 N_("Migrate share-ACLs from remote to local server"),
3877 N_("net rpc share migrate security\n"
3878 " Migrate share-ACLs from remote to local server")
3882 rpc_share_migrate_shares,
3884 N_("Migrate shares from remote to local server"),
3885 N_("net rpc share migrate shares\n"
3886 " Migrate shares from remote to local server")
3888 {NULL, NULL, 0, NULL, NULL}
3891 net_mode_share = NET_MODE_SHARE_MIGRATE;
3893 return net_run_function(c, argc, argv, "net rpc share migrate", func);
3902 static int num_server_aliases;
3903 static struct full_alias *server_aliases;
3906 * Add an alias to the static list.
3908 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3910 if (server_aliases == NULL)
3911 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3913 server_aliases[num_server_aliases] = *alias;
3914 num_server_aliases += 1;
3918 * For a specific domain on the server, fetch all the aliases
3919 * and their members. Add all of them to the server_aliases.
3922 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
3923 TALLOC_CTX *mem_ctx,
3924 struct policy_handle *connect_pol,
3925 const DOM_SID *domain_sid)
3927 uint32 start_idx, max_entries, num_entries, i;
3928 struct samr_SamArray *groups = NULL;
3930 struct policy_handle domain_pol;
3932 /* Get domain policy handle */
3934 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
3936 MAXIMUM_ALLOWED_ACCESS,
3937 CONST_DISCARD(struct dom_sid2 *, domain_sid),
3939 if (!NT_STATUS_IS_OK(result))
3946 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
3952 for (i = 0; i < num_entries; i++) {
3954 struct policy_handle alias_pol;
3955 struct full_alias alias;
3956 struct lsa_SidArray sid_array;
3959 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
3961 MAXIMUM_ALLOWED_ACCESS,
3962 groups->entries[i].idx,
3964 if (!NT_STATUS_IS_OK(result))
3967 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
3970 if (!NT_STATUS_IS_OK(result))
3973 alias.num_members = sid_array.num_sids;
3975 result = rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol);
3976 if (!NT_STATUS_IS_OK(result))
3979 alias.members = NULL;
3981 if (alias.num_members > 0) {
3982 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
3984 for (j = 0; j < alias.num_members; j++)
3985 sid_copy(&alias.members[j],
3986 sid_array.sids[j].sid);
3989 sid_compose(&alias.sid, domain_sid,
3990 groups->entries[i].idx);
3992 push_alias(mem_ctx, &alias);
3994 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
3996 result = NT_STATUS_OK;
3999 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
4005 * Dump server_aliases as names for debugging purposes.
4008 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4009 const DOM_SID *domain_sid,
4010 const char *domain_name,
4011 struct cli_state *cli,
4012 struct rpc_pipe_client *pipe_hnd,
4013 TALLOC_CTX *mem_ctx,
4019 struct policy_handle lsa_pol;
4021 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4022 SEC_FLAG_MAXIMUM_ALLOWED,
4024 if (!NT_STATUS_IS_OK(result))
4027 for (i=0; i<num_server_aliases; i++) {
4030 enum lsa_SidType *types;
4033 struct full_alias *alias = &server_aliases[i];
4035 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4037 &domains, &names, &types);
4038 if (!NT_STATUS_IS_OK(result))
4041 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4043 if (alias->num_members == 0) {
4048 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4051 &domains, &names, &types);
4053 if (!NT_STATUS_IS_OK(result) &&
4054 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4057 for (j=0; j<alias->num_members; j++)
4058 DEBUG(1, ("%s\\%s (%d); ",
4059 domains[j] ? domains[j] : "*unknown*",
4060 names[j] ? names[j] : "*unknown*",types[j]));
4064 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4066 return NT_STATUS_OK;
4070 * Fetch a list of all server aliases and their members into
4074 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4075 const DOM_SID *domain_sid,
4076 const char *domain_name,
4077 struct cli_state *cli,
4078 struct rpc_pipe_client *pipe_hnd,
4079 TALLOC_CTX *mem_ctx,
4084 struct policy_handle connect_pol;
4086 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
4088 MAXIMUM_ALLOWED_ACCESS,
4091 if (!NT_STATUS_IS_OK(result))
4094 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4095 &global_sid_Builtin);
4097 if (!NT_STATUS_IS_OK(result))
4100 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4103 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
4108 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4110 token->num_sids = 4;
4112 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4113 d_fprintf(stderr, "malloc %s\n",_("failed"));
4114 token->num_sids = 0;
4118 token->user_sids[0] = *user_sid;
4119 sid_copy(&token->user_sids[1], &global_sid_World);
4120 sid_copy(&token->user_sids[2], &global_sid_Network);
4121 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4124 static void free_user_token(NT_USER_TOKEN *token)
4126 SAFE_FREE(token->user_sids);
4129 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4131 if (is_sid_in_token(token, sid))
4134 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4135 if (!token->user_sids) {
4139 sid_copy(&token->user_sids[token->num_sids], sid);
4141 token->num_sids += 1;
4146 NT_USER_TOKEN token;
4149 static void dump_user_token(struct user_token *token)
4153 d_printf("%s\n", token->name);
4155 for (i=0; i<token->token.num_sids; i++) {
4156 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4160 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4164 for (i=0; i<alias->num_members; i++) {
4165 if (sid_compare(sid, &alias->members[i]) == 0)
4172 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4176 for (i=0; i<num_server_aliases; i++) {
4177 if (is_alias_member(&sid, &server_aliases[i]))
4178 add_sid_to_token(token, &server_aliases[i].sid);
4183 * We got a user token with all the SIDs we can know about without asking the
4184 * server directly. These are the user and domain group sids. All of these can
4185 * be members of aliases. So scan the list of aliases for each of the SIDs and
4186 * add them to the token.
4189 static void collect_alias_memberships(NT_USER_TOKEN *token)
4191 int num_global_sids = token->num_sids;
4194 for (i=0; i<num_global_sids; i++) {
4195 collect_sid_memberships(token, token->user_sids[i]);
4199 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4201 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4202 enum wbcSidType type;
4204 struct wbcDomainSid wsid;
4205 char *sid_str = NULL;
4207 uint32_t num_groups;
4208 gid_t *groups = NULL;
4211 fstr_sprintf(full_name, "%s%c%s",
4212 domain, *lp_winbind_separator(), user);
4214 /* First let's find out the user sid */
4216 wbc_status = wbcLookupName(domain, user, &wsid, &type);
4218 if (!WBC_ERROR_IS_OK(wbc_status)) {
4219 DEBUG(1, ("winbind could not find %s: %s\n",
4220 full_name, wbcErrorString(wbc_status)));
4224 wbc_status = wbcSidToString(&wsid, &sid_str);
4225 if (!WBC_ERROR_IS_OK(wbc_status)) {
4229 if (type != SID_NAME_USER) {
4230 wbcFreeMemory(sid_str);
4231 DEBUG(1, ("%s is not a user\n", full_name));
4235 if (!string_to_sid(&user_sid, sid_str)) {
4236 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4240 wbcFreeMemory(sid_str);
4243 init_user_token(token, &user_sid);
4245 /* And now the groups winbind knows about */
4247 wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4248 if (!WBC_ERROR_IS_OK(wbc_status)) {
4249 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4250 full_name, wbcErrorString(wbc_status)));
4254 for (i = 0; i < num_groups; i++) {
4255 gid_t gid = groups[i];
4258 wbc_status = wbcGidToSid(gid, &wsid);
4259 if (!WBC_ERROR_IS_OK(wbc_status)) {
4260 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4261 (unsigned int)gid, wbcErrorString(wbc_status)));
4262 wbcFreeMemory(groups);
4266 wbc_status = wbcSidToString(&wsid, &sid_str);
4267 if (!WBC_ERROR_IS_OK(wbc_status)) {
4268 wbcFreeMemory(groups);
4272 DEBUG(3, (" %s\n", sid_str));
4274 string_to_sid(&sid, sid_str);
4275 wbcFreeMemory(sid_str);
4278 add_sid_to_token(token, &sid);
4280 wbcFreeMemory(groups);
4286 * Get a list of all user tokens we want to look at
4289 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4290 struct user_token **user_tokens)
4292 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4293 uint32_t i, num_users;
4295 struct user_token *result;
4296 TALLOC_CTX *frame = NULL;
4298 if (lp_winbind_use_default_domain() &&
4299 (c->opt_target_workgroup == NULL)) {
4300 d_fprintf(stderr, _("winbind use default domain = yes set, "
4301 "please specify a workgroup\n"));
4305 /* Send request to winbind daemon */
4307 wbc_status = wbcListUsers(NULL, &num_users, &users);
4308 if (!WBC_ERROR_IS_OK(wbc_status)) {
4309 DEBUG(1, (_("winbind could not list users: %s\n"),
4310 wbcErrorString(wbc_status)));
4314 result = SMB_MALLOC_ARRAY(struct user_token, num_users);
4316 if (result == NULL) {
4317 DEBUG(1, ("Could not malloc sid array\n"));
4318 wbcFreeMemory(users);
4322 frame = talloc_stackframe();
4323 for (i=0; i < num_users; i++) {
4324 fstring domain, user;
4327 fstrcpy(result[i].name, users[i]);
4329 p = strchr(users[i], *lp_winbind_separator());
4331 DEBUG(3, ("%s\n", users[i]));
4334 fstrcpy(domain, c->opt_target_workgroup);
4335 fstrcpy(user, users[i]);
4338 fstrcpy(domain, users[i]);
4343 get_user_sids(domain, user, &(result[i].token));
4347 wbcFreeMemory(users);
4349 *num_tokens = num_users;
4350 *user_tokens = result;
4355 static bool get_user_tokens_from_file(FILE *f,
4357 struct user_token **tokens)
4359 struct user_token *token = NULL;
4364 if (fgets(line, sizeof(line)-1, f) == NULL) {
4368 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
4369 line[strlen(line)-1] = '\0';
4372 if (line[0] == ' ') {
4376 if(!string_to_sid(&sid, &line[1])) {
4377 DEBUG(1,("get_user_tokens_from_file: Could "
4378 "not convert sid %s \n",&line[1]));
4382 if (token == NULL) {
4383 DEBUG(0, ("File does not begin with username"));
4387 add_sid_to_token(&token->token, &sid);
4391 /* And a new user... */
4394 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4395 if (*tokens == NULL) {
4396 DEBUG(0, ("Could not realloc tokens\n"));
4400 token = &((*tokens)[*num_tokens-1]);
4402 fstrcpy(token->name, line);
4403 token->token.num_sids = 0;
4404 token->token.user_sids = NULL;
4413 * Show the list of all users that have access to a share
4416 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4417 TALLOC_CTX *mem_ctx,
4418 const char *netname,
4420 struct user_token *tokens)
4423 SEC_DESC *share_sd = NULL;
4424 SEC_DESC *root_sd = NULL;
4425 struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
4427 union srvsvc_NetShareInfo info;
4432 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
4439 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4440 DEBUG(1, ("Coult not query secdesc for share %s\n",
4445 share_sd = info.info502->sd_buf.sd;
4446 if (share_sd == NULL) {
4447 DEBUG(1, ("Got no secdesc for share %s\n",
4453 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
4457 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
4458 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
4459 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4462 for (i=0; i<num_tokens; i++) {
4465 if (share_sd != NULL) {
4466 status = se_access_check(share_sd, &tokens[i].token,
4469 if (!NT_STATUS_IS_OK(status)) {
4470 DEBUG(1, ("Could not check share_sd for "
4477 if (root_sd == NULL) {
4478 d_printf(" %s\n", tokens[i].name);
4482 status = se_access_check(root_sd, &tokens[i].token,
4484 if (!NT_STATUS_IS_OK(status)) {
4485 DEBUG(1, ("Could not check root_sd for user %s\n",
4489 d_printf(" %s\n", tokens[i].name);
4492 if (fnum != (uint16_t)-1)
4493 cli_close(cli, fnum);
4505 static void collect_share(const char *name, uint32 m,
4506 const char *comment, void *state)
4508 struct share_list *share_list = (struct share_list *)state;
4510 if (m != STYPE_DISKTREE)
4513 share_list->num_shares += 1;
4514 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4515 if (!share_list->shares) {
4516 share_list->num_shares = 0;
4519 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4523 * List shares on a remote RPC server, including the security descriptors.
4525 * All parameters are provided by the run_rpc_command function, except for
4526 * argc, argv which are passed through.
4528 * @param domain_sid The domain sid acquired from the remote server.
4529 * @param cli A cli_state connected to the server.
4530 * @param mem_ctx Talloc context, destroyed on completion of the function.
4531 * @param argc Standard main() style argc.
4532 * @param argv Standard main() style argv. Initial components are already
4535 * @return Normal NTSTATUS return.
4538 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
4539 const DOM_SID *domain_sid,
4540 const char *domain_name,
4541 struct cli_state *cli,
4542 struct rpc_pipe_client *pipe_hnd,
4543 TALLOC_CTX *mem_ctx,
4552 struct user_token *tokens = NULL;
4555 struct share_list share_list;
4560 f = fopen(argv[0], "r");
4564 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4565 return NT_STATUS_UNSUCCESSFUL;
4568 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4574 DEBUG(0, ("Could not read users from file\n"));
4575 return NT_STATUS_UNSUCCESSFUL;
4578 for (i=0; i<num_tokens; i++)
4579 collect_alias_memberships(&tokens[i].token);
4581 share_list.num_shares = 0;
4582 share_list.shares = NULL;
4584 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4587 DEBUG(0, ("Error returning browse list: %s\n",
4592 for (i = 0; i < share_list.num_shares; i++) {
4593 char *netname = share_list.shares[i];
4595 if (netname[strlen(netname)-1] == '$')
4598 d_printf("%s\n", netname);
4600 show_userlist(pipe_hnd, mem_ctx, netname,
4601 num_tokens, tokens);
4604 for (i=0; i<num_tokens; i++) {
4605 free_user_token(&tokens[i].token);
4608 SAFE_FREE(share_list.shares);
4610 return NT_STATUS_OK;
4613 static int rpc_share_allowedusers(struct net_context *c, int argc,
4618 if (c->display_usage) {
4620 "net rpc share allowedusers\n"
4623 _("List allowed users"));
4627 result = run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
4628 rpc_aliaslist_internals,
4633 result = run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0,
4639 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4640 rpc_share_allowedusers_internals,
4644 int net_usersidlist(struct net_context *c, int argc, const char **argv)
4647 struct user_token *tokens = NULL;
4651 net_usersidlist_usage(c, argc, argv);
4655 if (!get_user_tokens(c, &num_tokens, &tokens)) {
4656 DEBUG(0, ("Could not get the user/sid list\n"));
4660 for (i=0; i<num_tokens; i++) {
4661 dump_user_token(&tokens[i]);
4662 free_user_token(&tokens[i].token);
4669 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
4671 d_printf(_("net usersidlist\n"
4672 "\tprints out a list of all users the running winbind knows\n"
4673 "\tabout, together with all their SIDs. This is used as\n"
4674 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
4676 net_common_flags_usage(c, argc, argv);
4681 * 'net rpc share' entrypoint.
4682 * @param argc Standard main() style argc.
4683 * @param argv Standard main() style argv. Initial components are already
4687 int net_rpc_share(struct net_context *c, int argc, const char **argv)
4689 NET_API_STATUS status;
4691 struct functable func[] = {
4697 N_("net rpc share add\n"
4705 N_("net rpc share delete\n"
4710 rpc_share_allowedusers,
4712 N_("Modify allowed users"),
4713 N_("net rpc share allowedusers\n"
4714 " Modify allowed users")
4720 N_("Migrate share to local server"),
4721 N_("net rpc share migrate\n"
4722 " Migrate share to local server")
4729 N_("net rpc share list\n"
4732 {NULL, NULL, 0, NULL, NULL}
4735 status = libnetapi_init(&c->netapi_ctx);
4739 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
4740 libnetapi_set_password(c->netapi_ctx, c->opt_password);
4741 if (c->opt_kerberos) {
4742 libnetapi_set_use_kerberos(c->netapi_ctx);
4746 if (c->display_usage) {
4751 " Alias for net rpc share list\n"));
4752 net_display_usage_from_functable(func);
4756 return rpc_share_list(c, argc, argv);
4759 return net_run_function(c, argc, argv, "net rpc share", func);
4762 static NTSTATUS rpc_sh_share_list(struct net_context *c,
4763 TALLOC_CTX *mem_ctx,
4764 struct rpc_sh_ctx *ctx,
4765 struct rpc_pipe_client *pipe_hnd,
4766 int argc, const char **argv)
4769 return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
4772 static NTSTATUS rpc_sh_share_add(struct net_context *c,
4773 TALLOC_CTX *mem_ctx,
4774 struct rpc_sh_ctx *ctx,
4775 struct rpc_pipe_client *pipe_hnd,
4776 int argc, const char **argv)
4778 NET_API_STATUS status;
4779 uint32_t parm_err = 0;
4780 struct SHARE_INFO_2 i2;
4782 if ((argc < 2) || (argc > 3)) {
4783 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
4785 return NT_STATUS_INVALID_PARAMETER;
4788 i2.shi2_netname = argv[0];
4789 i2.shi2_type = STYPE_DISKTREE;
4790 i2.shi2_remark = (argc == 3) ? argv[2] : "";
4791 i2.shi2_permissions = 0;
4792 i2.shi2_max_uses = 0;
4793 i2.shi2_current_uses = 0;
4794 i2.shi2_path = argv[1];
4795 i2.shi2_passwd = NULL;
4797 status = NetShareAdd(pipe_hnd->desthost,
4802 return werror_to_ntstatus(W_ERROR(status));
4805 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
4806 TALLOC_CTX *mem_ctx,
4807 struct rpc_sh_ctx *ctx,
4808 struct rpc_pipe_client *pipe_hnd,
4809 int argc, const char **argv)
4812 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4813 return NT_STATUS_INVALID_PARAMETER;
4816 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
4819 static NTSTATUS rpc_sh_share_info(struct net_context *c,
4820 TALLOC_CTX *mem_ctx,
4821 struct rpc_sh_ctx *ctx,
4822 struct rpc_pipe_client *pipe_hnd,
4823 int argc, const char **argv)
4825 union srvsvc_NetShareInfo info;
4830 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4831 return NT_STATUS_INVALID_PARAMETER;
4834 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
4840 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4844 d_printf(_("Name: %s\n"), info.info2->name);
4845 d_printf(_("Comment: %s\n"), info.info2->comment);
4846 d_printf(_("Path: %s\n"), info.info2->path);
4847 d_printf(_("Password: %s\n"), info.info2->password);
4850 return werror_to_ntstatus(result);
4853 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
4854 struct rpc_sh_ctx *ctx)
4856 static struct rpc_sh_cmd cmds[] = {
4858 { "list", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_list,
4859 N_("List available shares") },
4861 { "add", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_add,
4862 N_("Add a share") },
4864 { "delete", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_delete,
4865 N_("Delete a share") },
4867 { "info", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_info,
4868 N_("Get information about a share") },
4870 { NULL, NULL, 0, NULL, NULL }
4876 /****************************************************************************/
4878 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
4880 return net_file_usage(c, argc, argv);
4884 * Close a file on a remote RPC server.
4886 * @param argc Standard main() style argc.
4887 * @param argv Standard main() style argv. Initial components are already
4890 * @return A shell status integer (0 for success).
4892 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
4894 if (argc < 1 || c->display_usage) {
4895 return rpc_file_usage(c, argc, argv);
4898 return NetFileClose(c->opt_host, atoi(argv[0]));
4902 * Formatted print of open file info
4904 * @param r struct FILE_INFO_3 contents
4907 static void display_file_info_3(struct FILE_INFO_3 *r)
4909 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4910 r->fi3_id, r->fi3_username, r->fi3_permissions,
4911 r->fi3_num_locks, r->fi3_pathname);
4915 * List files for a user on a remote RPC server.
4917 * @param argc Standard main() style argc.
4918 * @param argv Standard main() style argv. Initial components are already
4921 * @return A shell status integer (0 for success)..
4924 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
4926 NET_API_STATUS status;
4927 uint32 preferred_len = 0xffffffff, i;
4928 const char *username=NULL;
4929 uint32_t total_entries = 0;
4930 uint32_t entries_read = 0;
4931 uint32_t resume_handle = 0;
4932 struct FILE_INFO_3 *i3 = NULL;
4934 if (c->display_usage) {
4935 return rpc_file_usage(c, argc, argv);
4938 /* if argc > 0, must be user command */
4940 username = smb_xstrdup(argv[0]);
4943 status = NetFileEnum(c->opt_host,
4947 (uint8_t **)(void *)&i3,
4957 /* Display results */
4960 "\nEnumerating open files on remote server:\n\n"
4961 "\nFileId Opened by Perms Locks Path"
4962 "\n------ --------- ----- ----- ---- \n"));
4963 for (i = 0; i < entries_read; i++) {
4964 display_file_info_3(&i3[i]);
4971 * 'net rpc file' entrypoint.
4972 * @param argc Standard main() style argc.
4973 * @param argv Standard main() style argv. Initial components are already
4977 int net_rpc_file(struct net_context *c, int argc, const char **argv)
4979 NET_API_STATUS status;
4981 struct functable func[] = {
4986 N_("Close opened file"),
4987 N_("net rpc file close\n"
4988 " Close opened file")
4994 N_("List files opened by user"),
4995 N_("net rpc file user\n"
4996 " List files opened by user")
5003 N_("Display information about opened file"),
5004 N_("net rpc file info\n"
5005 " Display information about opened file")
5008 {NULL, NULL, 0, NULL, NULL}
5011 status = libnetapi_init(&c->netapi_ctx);
5015 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5016 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5017 if (c->opt_kerberos) {
5018 libnetapi_set_use_kerberos(c->netapi_ctx);
5022 if (c->display_usage) {
5023 d_printf(_("Usage:\n"));
5024 d_printf(_("net rpc file\n"
5025 " List opened files\n"));
5026 net_display_usage_from_functable(func);
5030 return rpc_file_user(c, argc, argv);
5033 return net_run_function(c, argc, argv, "net rpc file", func);
5037 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5039 * All parameters are provided by the run_rpc_command function, except for
5040 * argc, argv which are passed through.
5042 * @param c A net_context structure.
5043 * @param domain_sid The domain sid acquired from the remote server.
5044 * @param cli A cli_state connected to the server.
5045 * @param mem_ctx Talloc context, destroyed on completion of the function.
5046 * @param argc Standard main() style argc.
5047 * @param argv Standard main() style argv. Initial components are already
5050 * @return Normal NTSTATUS return.
5053 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5054 const DOM_SID *domain_sid,
5055 const char *domain_name,
5056 struct cli_state *cli,
5057 struct rpc_pipe_client *pipe_hnd,
5058 TALLOC_CTX *mem_ctx,
5062 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5064 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5066 if (NT_STATUS_IS_OK(result)) {
5067 d_printf(_("\nShutdown successfully aborted\n"));
5068 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5070 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5076 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5078 * All parameters are provided by the run_rpc_command function, except for
5079 * argc, argv which are passed through.
5081 * @param c A net_context structure.
5082 * @param domain_sid The domain sid acquired from the remote server.
5083 * @param cli A cli_state connected to the server.
5084 * @param mem_ctx Talloc context, destroyed on completion of the function.
5085 * @param argc Standard main() style argc.
5086 * @param argv Standard main() style argv. Initial components are already
5089 * @return Normal NTSTATUS return.
5092 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5093 const DOM_SID *domain_sid,
5094 const char *domain_name,
5095 struct cli_state *cli,
5096 struct rpc_pipe_client *pipe_hnd,
5097 TALLOC_CTX *mem_ctx,
5101 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5103 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5105 if (NT_STATUS_IS_OK(result)) {
5106 d_printf(_("\nShutdown successfully aborted\n"));
5107 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5109 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5115 * ABORT the shutdown of a remote RPC server.
5117 * @param argc Standard main() style argc.
5118 * @param argv Standard main() style argv. Initial components are already
5121 * @return A shell status integer (0 for success).
5124 static int rpc_shutdown_abort(struct net_context *c, int argc,
5129 if (c->display_usage) {
5131 "net rpc abortshutdown\n"
5134 _("Abort a scheduled shutdown"));
5138 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5139 rpc_shutdown_abort_internals, argc, argv);
5144 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5146 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5147 rpc_reg_shutdown_abort_internals,
5152 * Shut down a remote RPC Server via initshutdown pipe.
5154 * All parameters are provided by the run_rpc_command function, except for
5155 * argc, argv which are passed through.
5157 * @param c A net_context structure.
5158 * @param domain_sid The domain sid acquired from the remote server.
5159 * @param cli A cli_state connected to the server.
5160 * @param mem_ctx Talloc context, destroyed on completion of the function.
5161 * @param argc Standard main() style argc.
5162 * @param argv Standard main() style argv. Initial components are already
5165 * @return Normal NTSTATUS return.
5168 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5169 const DOM_SID *domain_sid,
5170 const char *domain_name,
5171 struct cli_state *cli,
5172 struct rpc_pipe_client *pipe_hnd,
5173 TALLOC_CTX *mem_ctx,
5177 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5178 const char *msg = N_("This machine will be shutdown shortly");
5179 uint32 timeout = 20;
5180 struct lsa_StringLarge msg_string;
5182 if (c->opt_comment) {
5183 msg = c->opt_comment;
5185 if (c->opt_timeout) {
5186 timeout = c->opt_timeout;
5189 msg_string.string = msg;
5191 /* create an entry */
5192 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5193 &msg_string, timeout, c->opt_force, c->opt_reboot,
5196 if (NT_STATUS_IS_OK(result)) {
5197 d_printf(_("\nShutdown of remote machine succeeded\n"));
5198 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5200 DEBUG(1,("Shutdown of remote machine failed!\n"));
5206 * Shut down a remote RPC Server via winreg pipe.
5208 * All parameters are provided by the run_rpc_command function, except for
5209 * argc, argv which are passed through.
5211 * @param c A net_context structure.
5212 * @param domain_sid The domain sid acquired from the remote server.
5213 * @param cli A cli_state connected to the server.
5214 * @param mem_ctx Talloc context, destroyed on completion of the function.
5215 * @param argc Standard main() style argc.
5216 * @param argv Standard main() style argv. Initial components are already
5219 * @return Normal NTSTATUS return.
5222 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5223 const DOM_SID *domain_sid,
5224 const char *domain_name,
5225 struct cli_state *cli,
5226 struct rpc_pipe_client *pipe_hnd,
5227 TALLOC_CTX *mem_ctx,
5231 const char *msg = N_("This machine will be shutdown shortly");
5232 uint32 timeout = 20;
5233 struct lsa_StringLarge msg_string;
5237 if (c->opt_comment) {
5238 msg = c->opt_comment;
5240 msg_string.string = msg;
5242 if (c->opt_timeout) {
5243 timeout = c->opt_timeout;
5246 /* create an entry */
5247 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5248 &msg_string, timeout, c->opt_force, c->opt_reboot,
5251 if (NT_STATUS_IS_OK(result)) {
5252 d_printf(_("\nShutdown of remote machine succeeded\n"));
5254 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5255 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5256 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5258 d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
5265 * Shut down a remote RPC server.
5267 * @param argc Standard main() style argc.
5268 * @param argv Standard main() style argv. Initial components are already
5271 * @return A shell status integer (0 for success).
5274 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
5278 if (c->display_usage) {
5280 "net rpc shutdown\n"
5283 _("Shut down a remote RPC server"));
5287 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5288 rpc_init_shutdown_internals, argc, argv);
5291 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5292 rc = run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5293 rpc_reg_shutdown_internals, argc, argv);
5299 /***************************************************************************
5300 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5301 ***************************************************************************/
5304 * Add interdomain trust account to the RPC server.
5305 * All parameters (except for argc and argv) are passed by run_rpc_command
5308 * @param c A net_context structure.
5309 * @param domain_sid The domain sid acquired from the server.
5310 * @param cli A cli_state connected to the server.
5311 * @param mem_ctx Talloc context, destroyed on completion of the function.
5312 * @param argc Standard main() style argc.
5313 * @param argv Standard main() style argv. Initial components are already
5316 * @return normal NTSTATUS return code.
5319 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
5320 const DOM_SID *domain_sid,
5321 const char *domain_name,
5322 struct cli_state *cli,
5323 struct rpc_pipe_client *pipe_hnd,
5324 TALLOC_CTX *mem_ctx,
5328 struct policy_handle connect_pol, domain_pol, user_pol;
5329 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5331 struct lsa_String lsa_acct_name;
5333 uint32 acct_flags=0;
5335 uint32_t access_granted = 0;
5336 union samr_UserInfo info;
5337 unsigned int orig_timeout;
5342 _(" net rpc trustdom add <domain_name> "
5343 "<trust password>\n"));
5344 return NT_STATUS_INVALID_PARAMETER;
5348 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5351 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5352 return NT_STATUS_NO_MEMORY;
5355 strupper_m(acct_name);
5357 init_lsa_String(&lsa_acct_name, acct_name);
5359 /* Get samr policy handle */
5360 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5362 MAXIMUM_ALLOWED_ACCESS,
5364 if (!NT_STATUS_IS_OK(result)) {
5368 /* Get domain policy handle */
5369 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5371 MAXIMUM_ALLOWED_ACCESS,
5372 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5374 if (!NT_STATUS_IS_OK(result)) {
5378 /* This call can take a long time - allow the server to time out.
5379 * 35 seconds should do it. */
5381 orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
5383 /* Create trusting domain's account */
5384 acb_info = ACB_NORMAL;
5385 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5386 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5387 SAMR_USER_ACCESS_SET_PASSWORD |
5388 SAMR_USER_ACCESS_GET_ATTRIBUTES |
5389 SAMR_USER_ACCESS_SET_ATTRIBUTES;
5391 result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx,
5400 /* And restore our original timeout. */
5401 rpccli_set_timeout(pipe_hnd, orig_timeout);
5403 if (!NT_STATUS_IS_OK(result)) {
5404 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
5405 acct_name, nt_errstr(result));
5410 struct samr_CryptPassword crypt_pwd;
5412 ZERO_STRUCT(info.info23);
5414 init_samr_CryptPassword(argv[1],
5415 &cli->user_session_key,
5418 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
5419 SAMR_FIELD_NT_PASSWORD_PRESENT;
5420 info.info23.info.acct_flags = ACB_DOMTRUST;
5421 info.info23.password = crypt_pwd;
5423 result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
5428 if (!NT_STATUS_IS_OK(result)) {
5429 DEBUG(0,("Could not set trust account password: %s\n",
5430 nt_errstr(result)));
5436 SAFE_FREE(acct_name);
5441 * Create interdomain trust account for a remote domain.
5443 * @param argc Standard argc.
5444 * @param argv Standard argv without initial components.
5446 * @return Integer status (0 means success).
5449 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
5451 if (argc > 0 && !c->display_usage) {
5452 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5453 rpc_trustdom_add_internals, argc, argv);
5457 _("net rpc trustdom add <domain_name> <trust "
5465 * Remove interdomain trust account from the RPC server.
5466 * All parameters (except for argc and argv) are passed by run_rpc_command
5469 * @param c A net_context structure.
5470 * @param domain_sid The domain sid acquired from the server.
5471 * @param cli A cli_state connected to the server.
5472 * @param mem_ctx Talloc context, destroyed on completion of the function.
5473 * @param argc Standard main() style argc.
5474 * @param argv Standard main() style argv. Initial components are already
5477 * @return normal NTSTATUS return code.
5480 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
5481 const DOM_SID *domain_sid,
5482 const char *domain_name,
5483 struct cli_state *cli,
5484 struct rpc_pipe_client *pipe_hnd,
5485 TALLOC_CTX *mem_ctx,
5489 struct policy_handle connect_pol, domain_pol, user_pol;
5490 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5492 DOM_SID trust_acct_sid;
5493 struct samr_Ids user_rids, name_types;
5494 struct lsa_String lsa_acct_name;
5499 _(" net rpc trustdom del <domain_name>\n"));
5500 return NT_STATUS_INVALID_PARAMETER;
5504 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5506 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5508 if (acct_name == NULL)
5509 return NT_STATUS_NO_MEMORY;
5511 strupper_m(acct_name);
5513 /* Get samr policy handle */
5514 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5516 MAXIMUM_ALLOWED_ACCESS,
5518 if (!NT_STATUS_IS_OK(result)) {
5522 /* Get domain policy handle */
5523 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5525 MAXIMUM_ALLOWED_ACCESS,
5526 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5528 if (!NT_STATUS_IS_OK(result)) {
5532 init_lsa_String(&lsa_acct_name, acct_name);
5534 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
5541 if (!NT_STATUS_IS_OK(result)) {
5542 d_printf(_("net rpc trustdom del: LookupNames on user %s "
5544 acct_name, nt_errstr(result) );
5548 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
5550 MAXIMUM_ALLOWED_ACCESS,
5554 if (!NT_STATUS_IS_OK(result)) {
5555 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
5557 acct_name, nt_errstr(result) );
5561 /* append the rid to the domain sid */
5562 if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
5566 /* remove the sid */
5568 result = rpccli_samr_RemoveMemberFromForeignDomain(pipe_hnd, mem_ctx,
5571 if (!NT_STATUS_IS_OK(result)) {
5572 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
5573 " on user %s failed %s\n"),
5574 acct_name, nt_errstr(result) );
5580 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
5583 if (!NT_STATUS_IS_OK(result)) {
5584 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
5586 acct_name, nt_errstr(result) );
5590 if (!NT_STATUS_IS_OK(result)) {
5591 d_printf(_("Could not set trust account password: %s\n"),
5601 * Delete interdomain trust account for a remote domain.
5603 * @param argc Standard argc.
5604 * @param argv Standard argv without initial components.
5606 * @return Integer status (0 means success).
5609 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
5611 if (argc > 0 && !c->display_usage) {
5612 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5613 rpc_trustdom_del_internals, argc, argv);
5617 _("net rpc trustdom del <domain>\n"));
5622 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
5623 struct cli_state *cli,
5624 TALLOC_CTX *mem_ctx,
5625 const char *domain_name)
5627 char *dc_name = NULL;
5628 const char *buffer = NULL;
5629 struct rpc_pipe_client *netr;
5632 /* Use NetServerEnum2 */
5634 if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
5636 return NT_STATUS_OK;
5639 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
5640 for domain %s\n", domain_name));
5642 /* Try netr_GetDcName */
5644 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
5646 if (!NT_STATUS_IS_OK(status)) {
5650 status = rpccli_netr_GetDcName(netr, mem_ctx,
5657 if (NT_STATUS_IS_OK(status)) {
5661 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
5662 for domain %s\n", domain_name));
5668 * Establish trust relationship to a trusting domain.
5669 * Interdomain account must already be created on remote PDC.
5671 * @param c A net_context structure.
5672 * @param argc Standard argc.
5673 * @param argv Standard argv without initial components.
5675 * @return Integer status (0 means success).
5678 static int rpc_trustdom_establish(struct net_context *c, int argc,
5681 struct cli_state *cli = NULL;
5682 struct sockaddr_storage server_ss;
5683 struct rpc_pipe_client *pipe_hnd = NULL;
5684 struct policy_handle connect_hnd;
5685 TALLOC_CTX *mem_ctx;
5687 DOM_SID *domain_sid;
5692 union lsa_PolicyInformation *info = NULL;
5695 * Connect to \\server\ipc$ as 'our domain' account with password
5698 if (argc != 1 || c->display_usage) {
5701 _("net rpc trustdom establish <domain_name>\n"));
5705 domain_name = smb_xstrdup(argv[0]);
5706 strupper_m(domain_name);
5708 /* account name used at first is our domain's name with '$' */
5709 if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
5712 strupper_m(acct_name);
5715 * opt_workgroup will be used by connection functions further,
5716 * hence it should be set to remote domain name instead of ours
5718 if (c->opt_workgroup) {
5719 c->opt_workgroup = smb_xstrdup(domain_name);
5722 c->opt_user_name = acct_name;
5724 /* find the domain controller */
5725 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5726 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5730 /* connect to ipc$ as username/password */
5731 nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
5732 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5734 /* Is it trusting domain account for sure ? */
5735 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5736 nt_errstr(nt_status)));
5740 /* store who we connected to */
5742 saf_store( domain_name, pdc_name );
5745 * Connect to \\server\ipc$ again (this time anonymously)
5748 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
5751 if (NT_STATUS_IS_ERR(nt_status)) {
5752 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5753 domain_name, nt_errstr(nt_status)));
5757 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5758 "domain %s", domain_name))) {
5759 DEBUG(0, ("talloc_init() failed\n"));
5764 /* Make sure we're talking to a proper server */
5766 nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
5767 if (!NT_STATUS_IS_OK(nt_status)) {
5769 talloc_destroy(mem_ctx);
5774 * Call LsaOpenPolicy and LsaQueryInfo
5777 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
5779 if (!NT_STATUS_IS_OK(nt_status)) {
5780 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5782 talloc_destroy(mem_ctx);
5786 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
5788 if (NT_STATUS_IS_ERR(nt_status)) {
5789 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5790 nt_errstr(nt_status)));
5792 talloc_destroy(mem_ctx);
5796 /* Querying info level 5 */
5798 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
5800 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
5802 if (NT_STATUS_IS_ERR(nt_status)) {
5803 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5804 nt_errstr(nt_status)));
5806 talloc_destroy(mem_ctx);
5810 domain_sid = info->account_domain.sid;
5812 /* There should be actually query info level 3 (following nt serv behaviour),
5813 but I still don't know if it's _really_ necessary */
5816 * Store the password in secrets db
5819 if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
5820 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5822 talloc_destroy(mem_ctx);
5827 * Close the pipes and clean up
5830 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5831 if (NT_STATUS_IS_ERR(nt_status)) {
5832 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5833 nt_errstr(nt_status)));
5835 talloc_destroy(mem_ctx);
5841 talloc_destroy(mem_ctx);
5843 d_printf(_("Trust to domain %s established\n"), domain_name);
5848 * Revoke trust relationship to the remote domain.
5850 * @param c A net_context structure.
5851 * @param argc Standard argc.
5852 * @param argv Standard argv without initial components.
5854 * @return Integer status (0 means success).
5857 static int rpc_trustdom_revoke(struct net_context *c, int argc,
5863 if (argc < 1 || c->display_usage) {
5866 _("net rpc trustdom revoke <domain_name>\n"
5867 " Revoke trust relationship\n"
5868 " domain_name\tName of domain to revoke trust\n"));
5872 /* generate upper cased domain name */
5873 domain_name = smb_xstrdup(argv[0]);
5874 strupper_m(domain_name);
5876 /* delete password of the trust */
5877 if (!pdb_del_trusteddom_pw(domain_name)) {
5878 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5885 SAFE_FREE(domain_name);
5889 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
5890 const DOM_SID *domain_sid,
5891 const char *domain_name,
5892 struct cli_state *cli,
5893 struct rpc_pipe_client *pipe_hnd,
5894 TALLOC_CTX *mem_ctx,
5899 if (!sid_to_fstring(str_sid, domain_sid)) {
5900 return NT_STATUS_UNSUCCESSFUL;
5902 d_printf("%s\n", str_sid);
5903 return NT_STATUS_OK;
5906 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5910 /* convert sid into ascii string */
5911 sid_to_fstring(ascii_sid, dom_sid);
5913 d_printf("%-20s%s\n", trusted_dom_name, ascii_sid);
5916 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5917 TALLOC_CTX *mem_ctx,
5918 struct policy_handle *pol,
5920 const char *trusted_dom_name)
5923 union lsa_TrustedDomainInfo *info = NULL;
5924 char *cleartextpwd = NULL;
5925 uint8_t session_key[16];
5926 DATA_BLOB session_key_blob;
5927 DATA_BLOB data = data_blob_null;
5929 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5932 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5934 if (NT_STATUS_IS_ERR(nt_status)) {
5935 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5936 nt_errstr(nt_status)));
5940 data = data_blob(info->password.password->data,
5941 info->password.password->length);
5943 if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) {
5944 DEBUG(0, ("Could not retrieve password hash\n"));
5948 session_key_blob = data_blob_const(session_key, sizeof(session_key));
5949 cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob);
5951 if (cleartextpwd == NULL) {
5952 DEBUG(0,("retrieved NULL password\n"));
5953 nt_status = NT_STATUS_UNSUCCESSFUL;
5957 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5958 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5959 nt_status = NT_STATUS_UNSUCCESSFUL;
5963 #ifdef DEBUG_PASSWORD
5964 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
5965 "password: [%s]\n", trusted_dom_name,
5966 sid_string_dbg(&dom_sid), cleartextpwd));
5970 SAFE_FREE(cleartextpwd);
5971 data_blob_free(&data);
5976 static int rpc_trustdom_vampire(struct net_context *c, int argc,
5979 /* common variables */
5980 TALLOC_CTX* mem_ctx;
5981 struct cli_state *cli = NULL;
5982 struct rpc_pipe_client *pipe_hnd = NULL;
5984 const char *domain_name = NULL;
5985 DOM_SID *queried_dom_sid;
5986 struct policy_handle connect_hnd;
5987 union lsa_PolicyInformation *info = NULL;
5989 /* trusted domains listing variables */
5990 unsigned int enum_ctx = 0;
5992 struct lsa_DomainList dom_list;
5995 if (c->display_usage) {
5997 "net rpc trustdom vampire\n"
6000 _("Vampire trust relationship from remote server"));
6005 * Listing trusted domains (stored in secrets.tdb, if local)
6008 mem_ctx = talloc_init("trust relationships vampire");
6011 * set domain and pdc name to local samba server (default)
6012 * or to remote one given in command line
6015 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6016 domain_name = c->opt_workgroup;
6017 c->opt_target_workgroup = c->opt_workgroup;
6019 fstrcpy(pdc_name, global_myname());
6020 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6021 c->opt_target_workgroup = domain_name;
6024 /* open \PIPE\lsarpc and open policy handle */
6025 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6026 if (!NT_STATUS_IS_OK(nt_status)) {
6027 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6028 nt_errstr(nt_status)));
6029 talloc_destroy(mem_ctx);
6033 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6035 if (!NT_STATUS_IS_OK(nt_status)) {
6036 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6037 nt_errstr(nt_status) ));
6039 talloc_destroy(mem_ctx);
6043 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6045 if (NT_STATUS_IS_ERR(nt_status)) {
6046 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6047 nt_errstr(nt_status)));
6049 talloc_destroy(mem_ctx);
6053 /* query info level 5 to obtain sid of a domain being queried */
6054 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6056 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6059 if (NT_STATUS_IS_ERR(nt_status)) {
6060 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6061 nt_errstr(nt_status)));
6063 talloc_destroy(mem_ctx);
6067 queried_dom_sid = info->account_domain.sid;
6070 * Keep calling LsaEnumTrustdom over opened pipe until
6071 * the end of enumeration is reached
6074 d_printf(_("Vampire trusted domains:\n\n"));
6077 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6082 if (NT_STATUS_IS_ERR(nt_status)) {
6083 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6084 nt_errstr(nt_status)));
6086 talloc_destroy(mem_ctx);
6090 for (i = 0; i < dom_list.count; i++) {
6092 print_trusted_domain(dom_list.domains[i].sid,
6093 dom_list.domains[i].name.string);
6095 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6096 *dom_list.domains[i].sid,
6097 dom_list.domains[i].name.string);
6098 if (!NT_STATUS_IS_OK(nt_status)) {
6100 talloc_destroy(mem_ctx);
6106 * in case of no trusted domains say something rather
6107 * than just display blank line
6109 if (!dom_list.count) d_printf(_("none\n"));
6111 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6113 /* close this connection before doing next one */
6114 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6115 if (NT_STATUS_IS_ERR(nt_status)) {
6116 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6117 nt_errstr(nt_status)));
6119 talloc_destroy(mem_ctx);
6123 /* close lsarpc pipe and connection to IPC$ */
6126 talloc_destroy(mem_ctx);
6130 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
6132 /* common variables */
6133 TALLOC_CTX* mem_ctx;
6134 struct cli_state *cli = NULL, *remote_cli = NULL;
6135 struct rpc_pipe_client *pipe_hnd = NULL;
6137 const char *domain_name = NULL;
6138 DOM_SID *queried_dom_sid;
6139 int ascii_dom_name_len;
6140 struct policy_handle connect_hnd;
6141 union lsa_PolicyInformation *info = NULL;
6143 /* trusted domains listing variables */
6144 unsigned int num_domains, enum_ctx = 0;
6146 struct lsa_DomainList dom_list;
6150 /* trusting domains listing variables */
6151 struct policy_handle domain_hnd;
6152 struct samr_SamArray *trusts = NULL;
6154 if (c->display_usage) {
6156 "net rpc trustdom list\n"
6159 _("List incoming and outgoing trust relationships"));
6164 * Listing trusted domains (stored in secrets.tdb, if local)
6167 mem_ctx = talloc_init("trust relationships listing");
6170 * set domain and pdc name to local samba server (default)
6171 * or to remote one given in command line
6174 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6175 domain_name = c->opt_workgroup;
6176 c->opt_target_workgroup = c->opt_workgroup;
6178 fstrcpy(pdc_name, global_myname());
6179 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6180 c->opt_target_workgroup = domain_name;
6183 /* open \PIPE\lsarpc and open policy handle */
6184 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6185 if (!NT_STATUS_IS_OK(nt_status)) {
6186 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6187 nt_errstr(nt_status)));
6188 talloc_destroy(mem_ctx);
6192 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6194 if (!NT_STATUS_IS_OK(nt_status)) {
6195 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6196 nt_errstr(nt_status) ));
6198 talloc_destroy(mem_ctx);
6202 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6204 if (NT_STATUS_IS_ERR(nt_status)) {
6205 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6206 nt_errstr(nt_status)));
6208 talloc_destroy(mem_ctx);
6212 /* query info level 5 to obtain sid of a domain being queried */
6213 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6215 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6218 if (NT_STATUS_IS_ERR(nt_status)) {
6219 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6220 nt_errstr(nt_status)));
6222 talloc_destroy(mem_ctx);
6226 queried_dom_sid = info->account_domain.sid;
6229 * Keep calling LsaEnumTrustdom over opened pipe until
6230 * the end of enumeration is reached
6233 d_printf(_("Trusted domains list:\n\n"));
6235 found_domain = false;
6238 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6243 if (NT_STATUS_IS_ERR(nt_status)) {
6244 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6245 nt_errstr(nt_status)));
6247 talloc_destroy(mem_ctx);
6251 for (i = 0; i < dom_list.count; i++) {
6252 print_trusted_domain(dom_list.domains[i].sid,
6253 dom_list.domains[i].name.string);
6254 found_domain = true;
6258 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6261 * in case of no trusted domains say something rather
6262 * than just display blank line
6264 if (!found_domain) {
6265 d_printf(_("none\n"));
6268 /* close this connection before doing next one */
6269 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6270 if (NT_STATUS_IS_ERR(nt_status)) {
6271 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6272 nt_errstr(nt_status)));
6274 talloc_destroy(mem_ctx);
6278 TALLOC_FREE(pipe_hnd);
6281 * Listing trusting domains (stored in passdb backend, if local)
6284 d_printf(_("\nTrusting domains list:\n\n"));
6287 * Open \PIPE\samr and get needed policy handles
6289 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
6291 if (!NT_STATUS_IS_OK(nt_status)) {
6292 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6294 talloc_destroy(mem_ctx);
6299 nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
6301 SAMR_ACCESS_LOOKUP_DOMAIN,
6303 if (!NT_STATUS_IS_OK(nt_status)) {
6304 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6305 nt_errstr(nt_status)));
6307 talloc_destroy(mem_ctx);
6311 /* SamrOpenDomain - we have to open domain policy handle in order to be
6312 able to enumerate accounts*/
6313 nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
6315 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6318 if (!NT_STATUS_IS_OK(nt_status)) {
6319 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6320 nt_errstr(nt_status)));
6322 talloc_destroy(mem_ctx);
6327 * perform actual enumeration
6330 found_domain = false;
6332 enum_ctx = 0; /* reset enumeration context from last enumeration */
6335 nt_status = rpccli_samr_EnumDomainUsers(pipe_hnd, mem_ctx,
6342 if (NT_STATUS_IS_ERR(nt_status)) {
6343 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6344 nt_errstr(nt_status)));
6346 talloc_destroy(mem_ctx);
6350 for (i = 0; i < num_domains; i++) {
6352 char *str = CONST_DISCARD(char *, trusts->entries[i].name.string);
6354 found_domain = true;
6357 * get each single domain's sid (do we _really_ need this ?):
6358 * 1) connect to domain's pdc
6359 * 2) query the pdc for domain's sid
6362 /* get rid of '$' tail */
6363 ascii_dom_name_len = strlen(str);
6364 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6365 str[ascii_dom_name_len - 1] = '\0';
6367 /* set opt_* variables to remote domain */
6369 c->opt_workgroup = talloc_strdup(mem_ctx, str);
6370 c->opt_target_workgroup = c->opt_workgroup;
6372 d_printf("%-20s", str);
6374 /* connect to remote domain controller */
6375 nt_status = net_make_ipc_connection(c,
6376 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6378 if (NT_STATUS_IS_OK(nt_status)) {
6379 /* query for domain's sid */
6380 if (run_rpc_command(
6382 &ndr_table_lsarpc.syntax_id, 0,
6383 rpc_query_domain_sid, argc,
6385 d_printf(_("strange - couldn't get domain's sid\n"));
6387 cli_shutdown(remote_cli);
6390 d_fprintf(stderr, _("domain controller is not "
6391 "responding: %s\n"),
6392 nt_errstr(nt_status));
6393 d_printf(_("couldn't get domain's sid\n"));
6397 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6399 if (!found_domain) {
6403 /* close opened samr and domain policy handles */
6404 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_hnd);
6405 if (!NT_STATUS_IS_OK(nt_status)) {
6406 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6409 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_hnd);
6410 if (!NT_STATUS_IS_OK(nt_status)) {
6411 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6414 /* close samr pipe and connection to IPC$ */
6417 talloc_destroy(mem_ctx);
6422 * Entrypoint for 'net rpc trustdom' code.
6424 * @param argc Standard argc.
6425 * @param argv Standard argv without initial components.
6427 * @return Integer status (0 means success).
6430 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
6432 struct functable func[] = {
6437 N_("Add trusting domain's account"),
6438 N_("net rpc trustdom add\n"
6439 " Add trusting domain's account")
6445 N_("Remove trusting domain's account"),
6446 N_("net rpc trustdom del\n"
6447 " Remove trusting domain's account")
6451 rpc_trustdom_establish,
6453 N_("Establish outgoing trust relationship"),
6454 N_("net rpc trustdom establish\n"
6455 " Establish outgoing trust relationship")
6459 rpc_trustdom_revoke,
6461 N_("Revoke outgoing trust relationship"),
6462 N_("net rpc trustdom revoke\n"
6463 " Revoke outgoing trust relationship")
6469 N_("List in- and outgoing domain trusts"),
6470 N_("net rpc trustdom list\n"
6471 " List in- and outgoing domain trusts")
6475 rpc_trustdom_vampire,
6477 N_("Vampire trusts from remote server"),
6478 N_("net rpc trustdom vampire\n"
6479 " Vampire trusts from remote server")
6481 {NULL, NULL, 0, NULL, NULL}
6484 return net_run_function(c, argc, argv, "net rpc trustdom", func);
6488 * Check if a server will take rpc commands
6489 * @param flags Type of server to connect to (PDC, DMB, localhost)
6490 * if the host is not explicitly specified
6491 * @return bool (true means rpc supported)
6493 bool net_rpc_check(struct net_context *c, unsigned flags)
6495 struct cli_state *cli;
6497 struct sockaddr_storage server_ss;
6498 char *server_name = NULL;
6501 /* flags (i.e. server type) may depend on command */
6502 if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
6505 if ((cli = cli_initialise()) == NULL) {
6509 status = cli_connect(cli, server_name, &server_ss);
6510 if (!NT_STATUS_IS_OK(status))
6512 if (!attempt_netbios_session_request(&cli, global_myname(),
6513 server_name, &server_ss))
6515 status = cli_negprot(cli);
6516 if (!NT_STATUS_IS_OK(status))
6518 if (cli->protocol < PROTOCOL_NT1)
6527 /* dump sam database via samsync rpc calls */
6528 static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
6529 if (c->display_usage) {
6534 _("Dump remote SAM database"));
6538 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6539 NET_FLAGS_ANONYMOUS,
6540 rpc_samdump_internals, argc, argv);
6543 /* syncronise sam database via samsync rpc calls */
6544 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
6546 struct functable func[] = {
6551 N_("Dump remote SAM database to ldif"),
6552 N_("net rpc vampire ldif\n"
6553 " Dump remote SAM database to LDIF file or "
6560 N_("Dump remote SAM database to Kerberos Keytab"),
6561 N_("net rpc vampire keytab\n"
6562 " Dump remote SAM database to Kerberos keytab "
6569 N_("Dump remote SAM database to passdb"),
6570 N_("net rpc vampire passdb\n"
6571 " Dump remote SAM database to passdb")
6574 {NULL, NULL, 0, NULL, NULL}
6578 if (c->display_usage) {
6583 _("Vampire remote SAM database"));
6587 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6588 NET_FLAGS_ANONYMOUS,
6589 rpc_vampire_internals,
6593 return net_run_function(c, argc, argv, "net rpc vampire", func);
6597 * Migrate everything from a print server.
6599 * @param c A net_context structure.
6600 * @param argc Standard main() style argc.
6601 * @param argv Standard main() style argv. Initial components are already
6604 * @return A shell status integer (0 for success).
6606 * The order is important !
6607 * To successfully add drivers the print queues have to exist !
6608 * Applying ACLs should be the last step, because you're easily locked out.
6611 static int rpc_printer_migrate_all(struct net_context *c, int argc,
6616 if (c->display_usage) {
6618 "net rpc printer migrate all\n"
6621 _("Migrate everything from a print server"));
6626 d_printf(_("no server to migrate\n"));
6630 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6631 rpc_printer_migrate_printers_internals, argc,
6636 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6637 rpc_printer_migrate_drivers_internals, argc,
6642 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6643 rpc_printer_migrate_forms_internals, argc, argv);
6647 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6648 rpc_printer_migrate_settings_internals, argc,
6653 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6654 rpc_printer_migrate_security_internals, argc,
6660 * Migrate print drivers from a print server.
6662 * @param c A net_context structure.
6663 * @param argc Standard main() style argc.
6664 * @param argv Standard main() style argv. Initial components are already
6667 * @return A shell status integer (0 for success).
6669 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
6672 if (c->display_usage) {
6674 "net rpc printer migrate drivers\n"
6677 _("Migrate print-drivers from a print-server"));
6682 d_printf(_("no server to migrate\n"));
6686 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6687 rpc_printer_migrate_drivers_internals,
6692 * Migrate print-forms from a print-server.
6694 * @param c A net_context structure.
6695 * @param argc Standard main() style argc.
6696 * @param argv Standard main() style argv. Initial components are already
6699 * @return A shell status integer (0 for success).
6701 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
6704 if (c->display_usage) {
6706 "net rpc printer migrate forms\n"
6709 _("Migrate print-forms from a print-server"));
6714 d_printf(_("no server to migrate\n"));
6718 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6719 rpc_printer_migrate_forms_internals,
6724 * Migrate printers from a print-server.
6726 * @param c A net_context structure.
6727 * @param argc Standard main() style argc.
6728 * @param argv Standard main() style argv. Initial components are already
6731 * @return A shell status integer (0 for success).
6733 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
6736 if (c->display_usage) {
6738 "net rpc printer migrate printers\n"
6741 _("Migrate printers from a print-server"));
6746 d_printf(_("no server to migrate\n"));
6750 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6751 rpc_printer_migrate_printers_internals,
6756 * Migrate printer-ACLs from a print-server
6758 * @param c A net_context structure.
6759 * @param argc Standard main() style argc.
6760 * @param argv Standard main() style argv. Initial components are already
6763 * @return A shell status integer (0 for success).
6765 static int rpc_printer_migrate_security(struct net_context *c, int argc,
6768 if (c->display_usage) {
6770 "net rpc printer migrate security\n"
6773 _("Migrate printer-ACLs from a print-server"));
6778 d_printf(_("no server to migrate\n"));
6782 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6783 rpc_printer_migrate_security_internals,
6788 * Migrate printer-settings from a print-server.
6790 * @param c A net_context structure.
6791 * @param argc Standard main() style argc.
6792 * @param argv Standard main() style argv. Initial components are already
6795 * @return A shell status integer (0 for success).
6797 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
6800 if (c->display_usage) {
6802 "net rpc printer migrate settings\n"
6805 _("Migrate printer-settings from a "
6811 d_printf(_("no server to migrate\n"));
6815 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6816 rpc_printer_migrate_settings_internals,
6821 * 'net rpc printer' entrypoint.
6823 * @param c A net_context structure.
6824 * @param argc Standard main() style argc.
6825 * @param argv Standard main() style argv. Initial components are already
6829 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
6832 /* ouch: when addriver and setdriver are called from within
6833 rpc_printer_migrate_drivers_internals, the printer-queue already
6836 struct functable func[] = {
6839 rpc_printer_migrate_all,
6841 N_("Migrate all from remote to local print server"),
6842 N_("net rpc printer migrate all\n"
6843 " Migrate all from remote to local print server")
6847 rpc_printer_migrate_drivers,
6849 N_("Migrate drivers to local server"),
6850 N_("net rpc printer migrate drivers\n"
6851 " Migrate drivers to local server")
6855 rpc_printer_migrate_forms,
6857 N_("Migrate froms to local server"),
6858 N_("net rpc printer migrate forms\n"
6859 " Migrate froms to local server")
6863 rpc_printer_migrate_printers,
6865 N_("Migrate printers to local server"),
6866 N_("net rpc printer migrate printers\n"
6867 " Migrate printers to local server")
6871 rpc_printer_migrate_security,
6873 N_("Mirgate printer ACLs to local server"),
6874 N_("net rpc printer migrate security\n"
6875 " Mirgate printer ACLs to local server")
6879 rpc_printer_migrate_settings,
6881 N_("Migrate printer settings to local server"),
6882 N_("net rpc printer migrate settings\n"
6883 " Migrate printer settings to local server")
6885 {NULL, NULL, 0, NULL, NULL}
6888 return net_run_function(c, argc, argv, "net rpc printer migrate",func);
6893 * List printers on a remote RPC server.
6895 * @param c A net_context structure.
6896 * @param argc Standard main() style argc.
6897 * @param argv Standard main() style argv. Initial components are already
6900 * @return A shell status integer (0 for success).
6902 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
6904 if (c->display_usage) {
6906 "net rpc printer list\n"
6909 _("List printers on a remote RPC server"));
6913 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6914 rpc_printer_list_internals,
6919 * List printer-drivers on a remote RPC server.
6921 * @param c A net_context structure.
6922 * @param argc Standard main() style argc.
6923 * @param argv Standard main() style argv. Initial components are already
6926 * @return A shell status integer (0 for success).
6928 static int rpc_printer_driver_list(struct net_context *c, int argc,
6931 if (c->display_usage) {
6933 "net rpc printer driver\n"
6936 _("List printer-drivers on a remote RPC server"));
6940 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6941 rpc_printer_driver_list_internals,
6946 * Publish printer in ADS via MSRPC.
6948 * @param c A net_context structure.
6949 * @param argc Standard main() style argc.
6950 * @param argv Standard main() style argv. Initial components are already
6953 * @return A shell status integer (0 for success).
6955 static int rpc_printer_publish_publish(struct net_context *c, int argc,
6958 if (c->display_usage) {
6960 "net rpc printer publish publish\n"
6963 _("Publish printer in ADS via MSRPC"));
6967 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6968 rpc_printer_publish_publish_internals,
6973 * Update printer in ADS via MSRPC.
6975 * @param c A net_context structure.
6976 * @param argc Standard main() style argc.
6977 * @param argv Standard main() style argv. Initial components are already
6980 * @return A shell status integer (0 for success).
6982 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
6984 if (c->display_usage) {
6986 "net rpc printer publish update\n"
6989 _("Update printer in ADS via MSRPC"));
6993 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6994 rpc_printer_publish_update_internals,
6999 * UnPublish printer in ADS via MSRPC.
7001 * @param c A net_context structure.
7002 * @param argc Standard main() style argc.
7003 * @param argv Standard main() style argv. Initial components are already
7006 * @return A shell status integer (0 for success).
7008 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7011 if (c->display_usage) {
7013 "net rpc printer publish unpublish\n"
7016 _("UnPublish printer in ADS via MSRPC"));
7020 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7021 rpc_printer_publish_unpublish_internals,
7026 * List published printers via MSRPC.
7028 * @param c A net_context structure.
7029 * @param argc Standard main() style argc.
7030 * @param argv Standard main() style argv. Initial components are already
7033 * @return A shell status integer (0 for success).
7035 static int rpc_printer_publish_list(struct net_context *c, int argc,
7038 if (c->display_usage) {
7040 "net rpc printer publish list\n"
7043 _("List published printers via MSRPC"));
7047 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7048 rpc_printer_publish_list_internals,
7054 * Publish printer in ADS.
7056 * @param c A net_context structure.
7057 * @param argc Standard main() style argc.
7058 * @param argv Standard main() style argv. Initial components are already
7061 * @return A shell status integer (0 for success).
7063 static int rpc_printer_publish(struct net_context *c, int argc,
7067 struct functable func[] = {
7070 rpc_printer_publish_publish,
7072 N_("Publish printer in AD"),
7073 N_("net rpc printer publish publish\n"
7074 " Publish printer in AD")
7078 rpc_printer_publish_update,
7080 N_("Update printer in AD"),
7081 N_("net rpc printer publish update\n"
7082 " Update printer in AD")
7086 rpc_printer_publish_unpublish,
7088 N_("Unpublish printer"),
7089 N_("net rpc printer publish unpublish\n"
7090 " Unpublish printer")
7094 rpc_printer_publish_list,
7096 N_("List published printers"),
7097 N_("net rpc printer publish list\n"
7098 " List published printers")
7100 {NULL, NULL, 0, NULL, NULL}
7104 if (c->display_usage) {
7105 d_printf(_("Usage:\n"));
7106 d_printf(_("net rpc printer publish\n"
7107 " List published printers\n"
7108 " Alias of net rpc printer publish "
7110 net_display_usage_from_functable(func);
7113 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7114 rpc_printer_publish_list_internals,
7118 return net_run_function(c, argc, argv, "net rpc printer publish",func);
7124 * Display rpc printer help page.
7126 * @param c A net_context structure.
7127 * @param argc Standard main() style argc.
7128 * @param argv Standard main() style argv. Initial components are already
7131 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
7133 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
7134 "\tlists all printers on print-server\n\n"));
7135 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7136 "\tlists all printer-drivers on print-server\n\n"));
7137 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7138 "\tpublishes printer settings in Active Directory\n"
7139 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
7140 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7141 "\n\tmigrates printers from remote to local server\n\n"));
7142 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7143 "\n\tmigrates printer-settings from remote to local server\n\n"));
7144 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7145 "\n\tmigrates printer-drivers from remote to local server\n\n"));
7146 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7147 "\n\tmigrates printer-forms from remote to local server\n\n"));
7148 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7149 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
7150 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7151 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7152 "\tremote to local print-server\n\n"));
7153 net_common_methods_usage(c, argc, argv);
7154 net_common_flags_usage(c, argc, argv);
7156 "\t-v or --verbose\t\t\tgive verbose output\n"
7157 "\t --destination\t\tmigration target server (default: localhost)\n"));
7163 * 'net rpc printer' entrypoint.
7165 * @param c A net_context structure.
7166 * @param argc Standard main() style argc.
7167 * @param argv Standard main() style argv. Initial components are already
7170 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
7172 struct functable func[] = {
7177 N_("List all printers on print server"),
7178 N_("net rpc printer list\n"
7179 " List all printers on print server")
7183 rpc_printer_migrate,
7185 N_("Migrate printer to local server"),
7186 N_("net rpc printer migrate\n"
7187 " Migrate printer to local server")
7191 rpc_printer_driver_list,
7193 N_("List printer drivers"),
7194 N_("net rpc printer driver\n"
7195 " List printer drivers")
7199 rpc_printer_publish,
7201 N_("Publish printer in AD"),
7202 N_("net rpc printer publish\n"
7203 " Publish printer in AD")
7205 {NULL, NULL, 0, NULL, NULL}
7209 if (c->display_usage) {
7210 d_printf(_("Usage:\n"));
7211 d_printf(_("net rpc printer\n"
7212 " List printers\n"));
7213 net_display_usage_from_functable(func);
7216 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7217 rpc_printer_list_internals,
7221 return net_run_function(c, argc, argv, "net rpc printer", func);
7225 * 'net rpc' entrypoint.
7227 * @param c A net_context structure.
7228 * @param argc Standard main() style argc.
7229 * @param argv Standard main() style argv. Initial components are already
7233 int net_rpc(struct net_context *c, int argc, const char **argv)
7235 NET_API_STATUS status;
7237 struct functable func[] = {
7242 N_("Modify global audit settings"),
7243 N_("net rpc audit\n"
7244 " Modify global audit settings")
7250 N_("Show basic info about a domain"),
7252 " Show basic info about a domain")
7258 N_("Join a domain"),
7266 N_("Join a domain created in server manager"),
7267 N_("net rpc oldjoin\n"
7268 " Join a domain created in server manager")
7274 N_("Test that a join is valid"),
7275 N_("net rpc testjoin\n"
7276 " Test that a join is valid")
7282 N_("List/modify users"),
7284 " List/modify users")
7290 N_("Change a user password"),
7291 N_("net rpc password\n"
7292 " Change a user password\n"
7293 " Alias for net rpc user password")
7299 N_("List/modify groups"),
7300 N_("net rpc group\n"
7301 " List/modify groups")
7307 N_("List/modify shares"),
7308 N_("net rpc share\n"
7309 " List/modify shares")
7315 N_("List open files"),
7323 N_("List/modify printers"),
7324 N_("net rpc printer\n"
7325 " List/modify printers")
7329 net_rpc_changetrustpw,
7331 N_("Change trust account password"),
7332 N_("net rpc changetrustpw\n"
7333 " Change trust account password")
7339 N_("Modify domain trusts"),
7340 N_("net rpc trustdom\n"
7341 " Modify domain trusts")
7347 N_("Abort a remote shutdown"),
7348 N_("net rpc abortshutdown\n"
7349 " Abort a remote shutdown")
7355 N_("Shutdown a remote server"),
7356 N_("net rpc shutdown\n"
7357 " Shutdown a remote server")
7363 N_("Dump SAM data of remote NT PDC"),
7364 N_("net rpc samdump\n"
7365 " Dump SAM data of remote NT PDC")
7371 N_("Sync a remote NT PDC's data into local passdb"),
7372 N_("net rpc vampire\n"
7373 " Sync a remote NT PDC's data into local passdb")
7379 N_("Fetch the domain sid into local secrets.tdb"),
7380 N_("net rpc getsid\n"
7381 " Fetch the domain sid into local secrets.tdb")
7387 N_("Manage privileges assigned to SID"),
7388 N_("net rpc rights\n"
7389 " Manage privileges assigned to SID")
7395 N_("Start/stop/query remote services"),
7396 N_("net rpc service\n"
7397 " Start/stop/query remote services")
7403 N_("Manage registry hives"),
7404 N_("net rpc registry\n"
7405 " Manage registry hives")
7411 N_("Open interactive shell on remote server"),
7412 N_("net rpc shell\n"
7413 " Open interactive shell on remote server")
7415 {NULL, NULL, 0, NULL, NULL}
7418 status = libnetapi_init(&c->netapi_ctx);
7422 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
7423 libnetapi_set_password(c->netapi_ctx, c->opt_password);
7424 if (c->opt_kerberos) {
7425 libnetapi_set_use_kerberos(c->netapi_ctx);
7427 if (c->opt_ccache) {
7428 libnetapi_set_use_ccache(c->netapi_ctx);
7431 return net_run_function(c, argc, argv, "net rpc", func);