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/ndr_samr_c.h"
27 #include "rpc_client/cli_samr.h"
28 #include "rpc_client/init_samr.h"
29 #include "../librpc/gen_ndr/cli_lsa.h"
30 #include "rpc_client/cli_lsarpc.h"
31 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
33 #include "../librpc/gen_ndr/ndr_spoolss.h"
34 #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
35 #include "../librpc/gen_ndr/ndr_winreg_c.h"
37 #include "lib/netapi/netapi.h"
38 #include "lib/netapi/netapi_net.h"
39 #include "rpc_client/init_lsa.h"
40 #include "../libcli/security/security.h"
42 static int net_mode_share;
43 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask);
48 * @brief RPC based subcommands for the 'net' utility.
50 * This file should contain much of the functionality that used to
51 * be found in rpcclient, execpt that the commands should change
52 * less often, and the fucntionality should be sane (the user is not
53 * expected to know a rid/sid before they conduct an operation etc.)
55 * @todo Perhaps eventually these should be split out into a number
56 * of files, as this could get quite big.
61 * Many of the RPC functions need the domain sid. This function gets
62 * it at the start of every run
64 * @param cli A cli_state already connected to the remote machine
66 * @return The Domain SID of the remote machine.
69 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
70 struct dom_sid **domain_sid,
71 const char **domain_name)
73 struct rpc_pipe_client *lsa_pipe = NULL;
74 struct policy_handle pol;
75 NTSTATUS result = NT_STATUS_OK;
76 union lsa_PolicyInformation *info = NULL;
78 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
80 if (!NT_STATUS_IS_OK(result)) {
81 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
85 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
86 SEC_FLAG_MAXIMUM_ALLOWED,
88 if (!NT_STATUS_IS_OK(result)) {
89 d_fprintf(stderr, "open_policy %s: %s\n",
95 result = rpccli_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx,
97 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
99 if (!NT_STATUS_IS_OK(result)) {
100 d_fprintf(stderr, "lsaquery %s: %s\n",
106 *domain_name = info->account_domain.name.string;
107 *domain_sid = info->account_domain.sid;
109 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
110 TALLOC_FREE(lsa_pipe);
116 * Run a single RPC command, from start to finish.
118 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
119 * @param conn_flag a NET_FLAG_ combination. Passed to
120 * net_make_ipc_connection.
121 * @param argc Standard main() style argc.
122 * @param argv Standard main() style argv. Initial components are already
124 * @return A shell status integer (0 for success).
127 int run_rpc_command(struct net_context *c,
128 struct cli_state *cli_arg,
129 const struct ndr_syntax_id *interface,
135 struct cli_state *cli = NULL;
136 struct rpc_pipe_client *pipe_hnd = NULL;
139 struct dom_sid *domain_sid;
140 const char *domain_name;
143 /* make use of cli_state handed over as an argument, if possible */
145 nt_status = net_make_ipc_connection(c, conn_flags, &cli);
146 if (!NT_STATUS_IS_OK(nt_status)) {
147 DEBUG(1, ("failed to make ipc connection: %s\n",
148 nt_errstr(nt_status)));
161 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
162 DEBUG(0, ("talloc_init() failed\n"));
166 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
168 if (!NT_STATUS_IS_OK(nt_status)) {
172 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
173 if (lp_client_schannel()
174 && (ndr_syntax_id_equal(interface,
175 &ndr_table_netlogon.syntax_id))) {
176 /* Always try and create an schannel netlogon pipe. */
177 nt_status = cli_rpc_pipe_open_schannel(
178 cli, interface, NCACN_NP,
179 DCERPC_AUTH_LEVEL_PRIVACY, domain_name,
181 if (!NT_STATUS_IS_OK(nt_status)) {
182 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
183 nt_errstr(nt_status) ));
187 if (conn_flags & NET_FLAGS_SEAL) {
188 nt_status = cli_rpc_pipe_open_ntlmssp(
190 (conn_flags & NET_FLAGS_TCP) ?
191 NCACN_IP_TCP : NCACN_NP,
192 DCERPC_AUTH_LEVEL_PRIVACY,
193 lp_workgroup(), c->opt_user_name,
194 c->opt_password, &pipe_hnd);
196 nt_status = cli_rpc_pipe_open_noauth(
200 if (!NT_STATUS_IS_OK(nt_status)) {
201 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
202 get_pipe_name_from_syntax(
203 talloc_tos(), interface),
204 nt_errstr(nt_status) ));
210 nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
212 if (!NT_STATUS_IS_OK(nt_status)) {
213 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
216 DEBUG(5, ("rpc command function succedded\n"));
219 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
221 TALLOC_FREE(pipe_hnd);
226 /* close the connection only if it was opened here */
231 talloc_destroy(mem_ctx);
236 * Force a change of the trust acccount password.
238 * All parameters are provided by the run_rpc_command function, except for
239 * argc, argv which are passed through.
241 * @param domain_sid The domain sid acquired from the remote server.
242 * @param cli A cli_state connected to the server.
243 * @param mem_ctx Talloc context, destroyed on completion of the function.
244 * @param argc Standard main() style argc.
245 * @param argv Standard main() style argv. Initial components are already
248 * @return Normal NTSTATUS return.
251 static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
252 const struct dom_sid *domain_sid,
253 const char *domain_name,
254 struct cli_state *cli,
255 struct rpc_pipe_client *pipe_hnd,
262 status = trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup);
263 if (!NT_STATUS_IS_OK(status)) {
264 d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
273 * Force a change of the trust acccount password.
275 * @param argc Standard main() style argc.
276 * @param argv Standard main() style argv. Initial components are already
279 * @return A shell status integer (0 for success).
282 int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
284 if (c->display_usage) {
286 "net rpc changetrustpw\n"
289 _("Change the machine trust password"));
293 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
294 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
295 rpc_changetrustpw_internals,
300 * Join a domain, the old way.
302 * This uses 'machinename' as the inital password, and changes it.
304 * The password should be created with 'server manager' or equiv first.
306 * All parameters are provided by the run_rpc_command function, except for
307 * argc, argv which are passed through.
309 * @param domain_sid The domain sid acquired from the remote server.
310 * @param cli A cli_state connected to the server.
311 * @param mem_ctx Talloc context, destroyed on completion of the function.
312 * @param argc Standard main() style argc.
313 * @param argv Standard main() style argv. Initial components are already
316 * @return Normal NTSTATUS return.
319 static NTSTATUS rpc_oldjoin_internals(struct net_context *c,
320 const struct dom_sid *domain_sid,
321 const char *domain_name,
322 struct cli_state *cli,
323 struct rpc_pipe_client *pipe_hnd,
329 fstring trust_passwd;
330 unsigned char orig_trust_passwd_hash[16];
332 enum netr_SchannelType sec_channel_type;
334 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
336 if (!NT_STATUS_IS_OK(result)) {
337 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
340 nt_errstr(result) ));
345 check what type of join - if the user want's to join as
346 a BDC, the server must agree that we are a BDC.
349 sec_channel_type = get_sec_channel_type(argv[0]);
351 sec_channel_type = get_sec_channel_type(NULL);
354 fstrcpy(trust_passwd, global_myname());
355 strlower_m(trust_passwd);
358 * Machine names can be 15 characters, but the max length on
359 * a password is 14. --jerry
362 trust_passwd[14] = '\0';
364 E_md4hash(trust_passwd, orig_trust_passwd_hash);
366 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup,
368 orig_trust_passwd_hash,
371 if (NT_STATUS_IS_OK(result))
372 printf(_("Joined domain %s.\n"), c->opt_target_workgroup);
375 if (!secrets_store_domain_sid(c->opt_target_workgroup, domain_sid)) {
376 DEBUG(0, ("error storing domain sid for %s\n", c->opt_target_workgroup));
377 result = NT_STATUS_UNSUCCESSFUL;
384 * Join a domain, the old way.
386 * @param argc Standard main() style argc.
387 * @param argv Standard main() style argv. Initial components are already
390 * @return A shell status integer (0 for success).
393 static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv)
395 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
396 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
397 rpc_oldjoin_internals,
402 * Join a domain, the old way. This function exists to allow
403 * the message to be displayed when oldjoin was explicitly
404 * requested, but not when it was implied by "net rpc join".
406 * @param argc Standard main() style argc.
407 * @param argv Standard main() style argv. Initial components are already
410 * @return A shell status integer (0 for success).
413 static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
417 if (c->display_usage) {
422 _("Join a domain the old way"));
426 rc = net_rpc_perform_oldjoin(c, argc, argv);
429 d_fprintf(stderr, _("Failed to join domain\n"));
436 * 'net rpc join' entrypoint.
437 * @param argc Standard main() style argc.
438 * @param argv Standard main() style argv. Initial components are already
441 * Main 'net_rpc_join()' (where the admin username/password is used) is
443 * Try to just change the password, but if that doesn't work, use/prompt
444 * for a username/password.
447 int net_rpc_join(struct net_context *c, int argc, const char **argv)
449 if (c->display_usage) {
452 _("net rpc join -U <username>[%%password] <type>\n"
454 " username\tName of the admin user"
455 " password\tPassword of the admin user, will "
456 "prompt if not specified\n"
457 " type\tCan be one of the following:\n"
458 "\t\tMEMBER\tJoin as member server (default)\n"
459 "\t\tBDC\tJoin as BDC\n"
460 "\t\tPDC\tJoin as PDC\n"));
464 if (lp_server_role() == ROLE_STANDALONE) {
465 d_printf(_("cannot join as standalone machine\n"));
469 if (strlen(global_myname()) > 15) {
470 d_printf(_("Our netbios name can be at most 15 chars long, "
471 "\"%s\" is %u chars long\n"),
472 global_myname(), (unsigned int)strlen(global_myname()));
476 if ((net_rpc_perform_oldjoin(c, argc, argv) == 0))
479 return net_rpc_join_newstyle(c, argc, argv);
483 * display info about a rpc domain
485 * All parameters are provided by the run_rpc_command function, except for
486 * argc, argv which are passed through.
488 * @param domain_sid The domain sid acquired from the remote server
489 * @param cli A cli_state connected to the server.
490 * @param mem_ctx Talloc context, destroyed on completion of the function.
491 * @param argc Standard main() style argc.
492 * @param argv Standard main() style argv. Initial components are already
495 * @return Normal NTSTATUS return.
498 NTSTATUS rpc_info_internals(struct net_context *c,
499 const struct dom_sid *domain_sid,
500 const char *domain_name,
501 struct cli_state *cli,
502 struct rpc_pipe_client *pipe_hnd,
507 struct policy_handle connect_pol, domain_pol;
508 NTSTATUS status, result;
509 union samr_DomainInfo *info = NULL;
511 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
513 sid_to_fstring(sid_str, domain_sid);
515 /* Get sam policy handle */
516 status = dcerpc_samr_Connect2(b, mem_ctx,
518 MAXIMUM_ALLOWED_ACCESS,
521 if (!NT_STATUS_IS_OK(status)) {
522 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
527 if (!NT_STATUS_IS_OK(result)) {
529 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
534 /* Get domain policy handle */
535 status = dcerpc_samr_OpenDomain(b, mem_ctx,
537 MAXIMUM_ALLOWED_ACCESS,
538 CONST_DISCARD(struct dom_sid2 *, domain_sid),
541 if (!NT_STATUS_IS_OK(status)) {
542 d_fprintf(stderr, _("Could not open domain: %s\n"),
546 if (!NT_STATUS_IS_OK(result)) {
548 d_fprintf(stderr, _("Could not open domain: %s\n"),
553 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
558 if (!NT_STATUS_IS_OK(status)) {
562 if (NT_STATUS_IS_OK(result)) {
563 d_printf(_("Domain Name: %s\n"),
564 info->general.domain_name.string);
565 d_printf(_("Domain SID: %s\n"), sid_str);
566 d_printf(_("Sequence number: %llu\n"),
567 (unsigned long long)info->general.sequence_num);
568 d_printf(_("Num users: %u\n"), info->general.num_users);
569 d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
570 d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
578 * 'net rpc info' entrypoint.
579 * @param argc Standard main() style argc.
580 * @param argv Standard main() style argv. Initial components are already
584 int net_rpc_info(struct net_context *c, int argc, const char **argv)
586 if (c->display_usage) {
591 _("Display information about the domain"));
595 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
596 NET_FLAGS_PDC, rpc_info_internals,
601 * Fetch domain SID into the local secrets.tdb.
603 * All parameters are provided by the run_rpc_command function, except for
604 * argc, argv which are passed through.
606 * @param domain_sid The domain sid acquired from the remote server.
607 * @param cli A cli_state connected to the server.
608 * @param mem_ctx Talloc context, destroyed on completion of the function.
609 * @param argc Standard main() style argc.
610 * @param argv Standard main() style argv. Initial components are already
613 * @return Normal NTSTATUS return.
616 static NTSTATUS rpc_getsid_internals(struct net_context *c,
617 const struct dom_sid *domain_sid,
618 const char *domain_name,
619 struct cli_state *cli,
620 struct rpc_pipe_client *pipe_hnd,
627 sid_to_fstring(sid_str, domain_sid);
628 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
629 sid_str, domain_name);
631 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
632 DEBUG(0,("Can't store domain SID\n"));
633 return NT_STATUS_UNSUCCESSFUL;
640 * 'net rpc getsid' entrypoint.
641 * @param argc Standard main() style argc.
642 * @param argv Standard main() style argv. Initial components are already
646 int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
648 int conn_flags = NET_FLAGS_PDC;
650 if (!c->opt_user_specified) {
651 conn_flags |= NET_FLAGS_ANONYMOUS;
654 if (c->display_usage) {
659 _("Fetch domain SID into local secrets.tdb"));
663 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
665 rpc_getsid_internals,
669 /****************************************************************************/
672 * Basic usage function for 'net rpc user'.
673 * @param argc Standard main() style argc.
674 * @param argv Standard main() style argv. Initial components are already
678 static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
680 return net_user_usage(c, argc, argv);
684 * Add a new user to a remote RPC server.
686 * @param argc Standard main() style argc.
687 * @param argv Standard main() style argv. Initial components are already
690 * @return A shell status integer (0 for success).
693 static int rpc_user_add(struct net_context *c, int argc, const char **argv)
695 NET_API_STATUS status;
696 struct USER_INFO_1 info1;
697 uint32_t parm_error = 0;
699 if (argc < 1 || c->display_usage) {
700 rpc_user_usage(c, argc, argv);
706 info1.usri1_name = argv[0];
708 info1.usri1_password = argv[1];
711 status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
714 d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
715 argv[0], libnetapi_get_error_string(c->netapi_ctx,
719 d_printf(_("Added user '%s'.\n"), argv[0]);
726 * Rename a user on a remote RPC server.
728 * @param argc Standard main() style argc.
729 * @param argv Standard main() style argv. Initial components are already
732 * @return A shell status integer (0 for success).
735 static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
737 NET_API_STATUS status;
738 struct USER_INFO_0 u0;
739 uint32_t parm_err = 0;
741 if (argc != 2 || c->display_usage) {
742 rpc_user_usage(c, argc, argv);
746 u0.usri0_name = argv[1];
748 status = NetUserSetInfo(c->opt_host, argv[0],
749 0, (uint8_t *)&u0, &parm_err);
752 _("Failed to rename user from %s to %s - %s\n"),
754 libnetapi_get_error_string(c->netapi_ctx, status));
756 d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
763 * Set a user's primary group
765 * @param argc Standard main() style argc.
766 * @param argv Standard main() style argv. Initial components are already
769 * @return A shell status integer (0 for success).
772 static int rpc_user_setprimarygroup(struct net_context *c, int argc,
775 NET_API_STATUS status;
777 struct GROUP_INFO_2 *g2;
778 struct USER_INFO_1051 u1051;
779 uint32_t parm_err = 0;
781 if (argc != 2 || c->display_usage) {
782 rpc_user_usage(c, argc, argv);
786 status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
788 d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
790 libnetapi_get_error_string(c->netapi_ctx, status));
793 g2 = (struct GROUP_INFO_2 *)buffer;
795 u1051.usri1051_primary_group_id = g2->grpi2_group_id;
797 NetApiBufferFree(buffer);
799 status = NetUserSetInfo(c->opt_host, argv[0], 1051,
800 (uint8_t *)&u1051, &parm_err);
803 _("Failed to set user's primary group %s to %s - "
804 "%s\n"), argv[0], argv[1],
805 libnetapi_get_error_string(c->netapi_ctx, status));
807 d_printf(_("Set primary group of user %s to %s\n"), argv[0],
814 * Delete a user from a remote RPC server.
816 * @param argc Standard main() style argc.
817 * @param argv Standard main() style argv. Initial components are already
820 * @return A shell status integer (0 for success).
823 static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
825 NET_API_STATUS status;
827 if (argc < 1 || c->display_usage) {
828 rpc_user_usage(c, argc, argv);
832 status = NetUserDel(c->opt_host, argv[0]);
835 d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
837 libnetapi_get_error_string(c->netapi_ctx, status));
840 d_printf(_("Deleted user '%s'.\n"), argv[0]);
847 * Set a user's password on a remote RPC server.
849 * @param argc Standard main() style argc.
850 * @param argv Standard main() style argv. Initial components are already
853 * @return A shell status integer (0 for success).
856 static int rpc_user_password(struct net_context *c, int argc, const char **argv)
858 NET_API_STATUS status;
860 struct USER_INFO_1003 u1003;
861 uint32_t parm_err = 0;
864 if (argc < 1 || c->display_usage) {
865 rpc_user_usage(c, argc, argv);
870 u1003.usri1003_password = argv[1];
872 ret = asprintf(&prompt, _("Enter new password for %s:"),
877 u1003.usri1003_password = talloc_strdup(c, getpass(prompt));
879 if (u1003.usri1003_password == NULL) {
884 status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
886 /* Display results */
889 _("Failed to set password for '%s' with error: %s.\n"),
890 argv[0], libnetapi_get_error_string(c->netapi_ctx,
899 * List a user's groups from a remote RPC server.
901 * @param argc Standard main() style argc.
902 * @param argv Standard main() style argv. Initial components are already
905 * @return A shell status integer (0 for success)
908 static int rpc_user_info(struct net_context *c, int argc, const char **argv)
911 NET_API_STATUS status;
912 struct GROUP_USERS_INFO_0 *u0 = NULL;
913 uint32_t entries_read = 0;
914 uint32_t total_entries = 0;
918 if (argc < 1 || c->display_usage) {
919 rpc_user_usage(c, argc, argv);
923 status = NetUserGetGroups(c->opt_host,
926 (uint8_t **)(void *)&u0,
932 _("Failed to get groups for '%s' with error: %s.\n"),
933 argv[0], libnetapi_get_error_string(c->netapi_ctx,
938 for (i=0; i < entries_read; i++) {
939 printf("%s\n", u0->grui0_name);
947 * List users on a remote RPC server.
949 * All parameters are provided by the run_rpc_command function, except for
950 * argc, argv which are passed through.
952 * @param domain_sid The domain sid acquired from the remote server.
953 * @param cli A cli_state connected to the server.
954 * @param mem_ctx Talloc context, destroyed on completion of the function.
955 * @param argc Standard main() style argc.
956 * @param argv Standard main() style argv. Initial components are already
959 * @return Normal NTSTATUS return.
962 static int rpc_user_list(struct net_context *c, int argc, const char **argv)
964 NET_API_STATUS status;
965 uint32_t start_idx=0, num_entries, i, loop_count = 0;
966 struct NET_DISPLAY_USER *info = NULL;
969 /* Query domain users */
970 if (c->opt_long_list_entries)
971 d_printf(_("\nUser name Comment"
972 "\n-----------------------------\n"));
974 uint32_t max_entries, max_size;
976 dcerpc_get_query_dispinfo_params(
977 loop_count, &max_entries, &max_size);
979 status = NetQueryDisplayInformation(c->opt_host,
986 if (status != 0 && status != ERROR_MORE_DATA) {
990 info = (struct NET_DISPLAY_USER *)buffer;
992 for (i = 0; i < num_entries; i++) {
994 if (c->opt_long_list_entries)
995 printf("%-21.21s %s\n", info->usri1_name,
996 info->usri1_comment);
998 printf("%s\n", info->usri1_name);
1002 NetApiBufferFree(buffer);
1005 start_idx += num_entries;
1007 } while (status == ERROR_MORE_DATA);
1013 * 'net rpc user' entrypoint.
1014 * @param argc Standard main() style argc.
1015 * @param argv Standard main() style argv. Initial components are already
1019 int net_rpc_user(struct net_context *c, int argc, const char **argv)
1021 NET_API_STATUS status;
1023 struct functable func[] = {
1028 N_("Add specified user"),
1029 N_("net rpc user add\n"
1030 " Add specified user")
1036 N_("List domain groups of user"),
1037 N_("net rpc user info\n"
1038 " List domain groups of user")
1044 N_("Remove specified user"),
1045 N_("net rpc user delete\n"
1046 " Remove specified user")
1052 N_("Change user password"),
1053 N_("net rpc user password\n"
1054 " Change user password")
1060 N_("Rename specified user"),
1061 N_("net rpc user rename\n"
1062 " Rename specified user")
1066 rpc_user_setprimarygroup,
1068 "Set a user's primary group",
1069 "net rpc user setprimarygroup\n"
1070 " Set a user's primary group"
1072 {NULL, NULL, 0, NULL, NULL}
1075 status = libnetapi_net_init(&c->netapi_ctx);
1079 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
1080 libnetapi_set_password(c->netapi_ctx, c->opt_password);
1081 if (c->opt_kerberos) {
1082 libnetapi_set_use_kerberos(c->netapi_ctx);
1086 if (c->display_usage) {
1091 _("List all users"));
1092 net_display_usage_from_functable(func);
1096 return rpc_user_list(c, argc, argv);
1099 return net_run_function(c, argc, argv, "net rpc user", func);
1102 static NTSTATUS rpc_sh_user_list(struct net_context *c,
1103 TALLOC_CTX *mem_ctx,
1104 struct rpc_sh_ctx *ctx,
1105 struct rpc_pipe_client *pipe_hnd,
1106 int argc, const char **argv)
1108 return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1111 static NTSTATUS rpc_sh_user_info(struct net_context *c,
1112 TALLOC_CTX *mem_ctx,
1113 struct rpc_sh_ctx *ctx,
1114 struct rpc_pipe_client *pipe_hnd,
1115 int argc, const char **argv)
1117 return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1120 static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1121 TALLOC_CTX *mem_ctx,
1122 struct rpc_sh_ctx *ctx,
1123 struct rpc_pipe_client *pipe_hnd,
1124 int argc, const char **argv,
1126 struct net_context *c,
1127 TALLOC_CTX *mem_ctx,
1128 struct rpc_sh_ctx *ctx,
1129 struct rpc_pipe_client *pipe_hnd,
1130 struct policy_handle *user_hnd,
1131 int argc, const char **argv))
1133 struct policy_handle connect_pol, domain_pol, user_pol;
1134 NTSTATUS status, result;
1137 enum lsa_SidType type;
1138 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1141 d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1143 return NT_STATUS_INVALID_PARAMETER;
1146 ZERO_STRUCT(connect_pol);
1147 ZERO_STRUCT(domain_pol);
1148 ZERO_STRUCT(user_pol);
1150 status = net_rpc_lookup_name(c, mem_ctx, rpc_pipe_np_smb_conn(pipe_hnd),
1151 argv[0], NULL, NULL, &sid, &type);
1152 if (!NT_STATUS_IS_OK(status)) {
1153 d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1158 if (type != SID_NAME_USER) {
1159 d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1160 sid_type_lookup(type));
1161 status = NT_STATUS_NO_SUCH_USER;
1165 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1166 d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1167 status = NT_STATUS_NO_SUCH_USER;
1171 status = dcerpc_samr_Connect2(b, mem_ctx,
1173 MAXIMUM_ALLOWED_ACCESS,
1176 if (!NT_STATUS_IS_OK(status)) {
1179 if (!NT_STATUS_IS_OK(result)) {
1184 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1186 MAXIMUM_ALLOWED_ACCESS,
1190 if (!NT_STATUS_IS_OK(status)) {
1193 if (!NT_STATUS_IS_OK(result)) {
1198 status = dcerpc_samr_OpenUser(b, mem_ctx,
1200 MAXIMUM_ALLOWED_ACCESS,
1204 if (!NT_STATUS_IS_OK(status)) {
1207 if (!NT_STATUS_IS_OK(result)) {
1212 status = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1215 if (is_valid_policy_hnd(&user_pol)) {
1216 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1218 if (is_valid_policy_hnd(&domain_pol)) {
1219 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1221 if (is_valid_policy_hnd(&connect_pol)) {
1222 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1227 static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1228 TALLOC_CTX *mem_ctx,
1229 struct rpc_sh_ctx *ctx,
1230 struct rpc_pipe_client *pipe_hnd,
1231 struct policy_handle *user_hnd,
1232 int argc, const char **argv)
1234 NTSTATUS status, result;
1235 union samr_UserInfo *info = NULL;
1236 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1239 d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1241 return NT_STATUS_INVALID_PARAMETER;
1244 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1249 if (!NT_STATUS_IS_OK(status)) {
1252 if (!NT_STATUS_IS_OK(result)) {
1256 d_printf(_("user rid: %d, group rid: %d\n"),
1258 info->info21.primary_gid);
1263 static NTSTATUS rpc_sh_user_show(struct net_context *c,
1264 TALLOC_CTX *mem_ctx,
1265 struct rpc_sh_ctx *ctx,
1266 struct rpc_pipe_client *pipe_hnd,
1267 int argc, const char **argv)
1269 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1270 rpc_sh_user_show_internals);
1273 #define FETCHSTR(name, rec) \
1274 do { if (strequal(ctx->thiscmd, name)) { \
1275 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1278 #define SETSTR(name, rec, flag) \
1279 do { if (strequal(ctx->thiscmd, name)) { \
1280 init_lsa_String(&(info->info21.rec), argv[0]); \
1281 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1284 static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1285 TALLOC_CTX *mem_ctx,
1286 struct rpc_sh_ctx *ctx,
1287 struct rpc_pipe_client *pipe_hnd,
1288 struct policy_handle *user_hnd,
1289 int argc, const char **argv)
1291 NTSTATUS status, result;
1292 const char *username;
1293 const char *oldval = "";
1294 union samr_UserInfo *info = NULL;
1295 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1298 d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1299 _("Usage:"), ctx->whoami);
1300 return NT_STATUS_INVALID_PARAMETER;
1303 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1308 if (!NT_STATUS_IS_OK(status)) {
1311 if (!NT_STATUS_IS_OK(result)) {
1315 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1317 FETCHSTR("fullname", full_name);
1318 FETCHSTR("homedir", home_directory);
1319 FETCHSTR("homedrive", home_drive);
1320 FETCHSTR("logonscript", logon_script);
1321 FETCHSTR("profilepath", profile_path);
1322 FETCHSTR("description", description);
1325 d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1329 if (strcmp(argv[0], "NULL") == 0) {
1333 ZERO_STRUCT(info->info21);
1335 SETSTR("fullname", full_name, FULL_NAME);
1336 SETSTR("homedir", home_directory, HOME_DIRECTORY);
1337 SETSTR("homedrive", home_drive, HOME_DRIVE);
1338 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1339 SETSTR("profilepath", profile_path, PROFILE_PATH);
1340 SETSTR("description", description, DESCRIPTION);
1342 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1347 if (!NT_STATUS_IS_OK(status)) {
1353 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1354 ctx->thiscmd, oldval, argv[0]);
1361 #define HANDLEFLG(name, rec) \
1362 do { if (strequal(ctx->thiscmd, name)) { \
1363 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1365 newflags = oldflags | ACB_##rec; \
1367 newflags = oldflags & ~ACB_##rec; \
1370 static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1371 TALLOC_CTX *mem_ctx,
1372 struct rpc_sh_ctx *ctx,
1373 struct rpc_pipe_client *pipe_hnd,
1374 int argc, const char **argv)
1376 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1377 rpc_sh_user_str_edit_internals);
1380 static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1381 TALLOC_CTX *mem_ctx,
1382 struct rpc_sh_ctx *ctx,
1383 struct rpc_pipe_client *pipe_hnd,
1384 struct policy_handle *user_hnd,
1385 int argc, const char **argv)
1387 NTSTATUS status, result;
1388 const char *username;
1389 const char *oldval = "unknown";
1390 uint32 oldflags, newflags;
1392 union samr_UserInfo *info = NULL;
1393 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1396 ((argc == 1) && !strequal(argv[0], "yes") &&
1397 !strequal(argv[0], "no"))) {
1398 /* TRANSATORS: The yes|no here are program keywords. Please do
1400 d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1402 return NT_STATUS_INVALID_PARAMETER;
1405 newval = strequal(argv[0], "yes");
1407 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1412 if (!NT_STATUS_IS_OK(status)) {
1415 if (!NT_STATUS_IS_OK(result)) {
1419 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1420 oldflags = info->info21.acct_flags;
1421 newflags = info->info21.acct_flags;
1423 HANDLEFLG("disabled", DISABLED);
1424 HANDLEFLG("pwnotreq", PWNOTREQ);
1425 HANDLEFLG("autolock", AUTOLOCK);
1426 HANDLEFLG("pwnoexp", PWNOEXP);
1429 d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1434 ZERO_STRUCT(info->info21);
1436 info->info21.acct_flags = newflags;
1437 info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1439 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1444 if (!NT_STATUS_IS_OK(status)) {
1448 if (NT_STATUS_IS_OK(result)) {
1449 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1450 ctx->thiscmd, oldval, argv[0]);
1458 static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1459 TALLOC_CTX *mem_ctx,
1460 struct rpc_sh_ctx *ctx,
1461 struct rpc_pipe_client *pipe_hnd,
1462 int argc, const char **argv)
1464 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1465 rpc_sh_user_flag_edit_internals);
1468 struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1469 TALLOC_CTX *mem_ctx,
1470 struct rpc_sh_ctx *ctx)
1472 static struct rpc_sh_cmd cmds[] = {
1474 { "fullname", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1475 N_("Show/Set a user's full name") },
1477 { "homedir", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1478 N_("Show/Set a user's home directory") },
1480 { "homedrive", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1481 N_("Show/Set a user's home drive") },
1483 { "logonscript", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1484 N_("Show/Set a user's logon script") },
1486 { "profilepath", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1487 N_("Show/Set a user's profile path") },
1489 { "description", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1490 N_("Show/Set a user's description") },
1492 { "disabled", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1493 N_("Show/Set whether a user is disabled") },
1495 { "autolock", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1496 N_("Show/Set whether a user locked out") },
1498 { "pwnotreq", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1499 N_("Show/Set whether a user does not need a password") },
1501 { "pwnoexp", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1502 N_("Show/Set whether a user's password does not expire") },
1504 { NULL, NULL, 0, NULL, NULL }
1510 struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1511 TALLOC_CTX *mem_ctx,
1512 struct rpc_sh_ctx *ctx)
1514 static struct rpc_sh_cmd cmds[] = {
1516 { "list", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_list,
1517 N_("List available users") },
1519 { "info", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_info,
1520 N_("List the domain groups a user is member of") },
1522 { "show", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_show,
1523 N_("Show info about a user") },
1525 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1526 N_("Show/Modify a user's fields") },
1528 { NULL, NULL, 0, NULL, NULL }
1534 /****************************************************************************/
1537 * Basic usage function for 'net rpc group'.
1538 * @param argc Standard main() style argc.
1539 * @param argv Standard main() style argv. Initial components are already
1543 static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1545 return net_group_usage(c, argc, argv);
1549 * Delete group on a remote RPC server.
1551 * All parameters are provided by the run_rpc_command function, except for
1552 * argc, argv which are passed through.
1554 * @param domain_sid The domain sid acquired from the remote server.
1555 * @param cli A cli_state connected to the server.
1556 * @param mem_ctx Talloc context, destroyed on completion of the function.
1557 * @param argc Standard main() style argc.
1558 * @param argv Standard main() style argv. Initial components are already
1561 * @return Normal NTSTATUS return.
1564 static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1565 const struct dom_sid *domain_sid,
1566 const char *domain_name,
1567 struct cli_state *cli,
1568 struct rpc_pipe_client *pipe_hnd,
1569 TALLOC_CTX *mem_ctx,
1573 struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1574 bool group_is_primary = false;
1575 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1577 struct samr_RidAttrArray *rids = NULL;
1580 /* struct samr_RidWithAttribute *user_gids; */
1582 struct samr_Ids group_rids, name_types;
1583 struct lsa_String lsa_acct_name;
1584 union samr_UserInfo *info = NULL;
1586 if (argc < 1 || c->display_usage) {
1587 rpc_group_usage(c, argc,argv);
1588 return NT_STATUS_OK; /* ok? */
1591 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1593 MAXIMUM_ALLOWED_ACCESS,
1596 if (!NT_STATUS_IS_OK(result)) {
1597 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1601 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1603 MAXIMUM_ALLOWED_ACCESS,
1604 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1607 if (!NT_STATUS_IS_OK(result)) {
1608 d_fprintf(stderr, _("Request open_domain failed\n"));
1612 init_lsa_String(&lsa_acct_name, argv[0]);
1614 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1620 if (!NT_STATUS_IS_OK(result)) {
1621 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1625 switch (name_types.ids[0])
1627 case SID_NAME_DOM_GRP:
1628 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1630 MAXIMUM_ALLOWED_ACCESS,
1633 if (!NT_STATUS_IS_OK(result)) {
1634 d_fprintf(stderr, _("Request open_group failed"));
1638 group_rid = group_rids.ids[0];
1640 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
1644 if (!NT_STATUS_IS_OK(result)) {
1646 _("Unable to query group members of %s"),
1651 if (c->opt_verbose) {
1653 _("Domain Group %s (rid: %d) has %d members\n"),
1654 argv[0],group_rid, rids->count);
1657 /* Check if group is anyone's primary group */
1658 for (i = 0; i < rids->count; i++)
1660 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1662 MAXIMUM_ALLOWED_ACCESS,
1666 if (!NT_STATUS_IS_OK(result)) {
1668 _("Unable to open group member %d\n"),
1673 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1678 if (!NT_STATUS_IS_OK(result)) {
1680 _("Unable to lookup userinfo for group "
1686 if (info->info21.primary_gid == group_rid) {
1687 if (c->opt_verbose) {
1688 d_printf(_("Group is primary group "
1690 info->info21.account_name.string);
1692 group_is_primary = true;
1695 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1698 if (group_is_primary) {
1699 d_fprintf(stderr, _("Unable to delete group because "
1700 "some of it's members have it as primary "
1702 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1706 /* remove all group members */
1707 for (i = 0; i < rids->count; i++)
1710 d_printf(_("Remove group member %d..."),
1712 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
1716 if (NT_STATUS_IS_OK(result)) {
1718 d_printf(_("ok\n"));
1721 d_printf("%s\n", _("failed"));
1726 result = rpccli_samr_DeleteDomainGroup(pipe_hnd, mem_ctx,
1730 /* removing a local group is easier... */
1731 case SID_NAME_ALIAS:
1732 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1734 MAXIMUM_ALLOWED_ACCESS,
1738 if (!NT_STATUS_IS_OK(result)) {
1739 d_fprintf(stderr, _("Request open_alias failed\n"));
1743 result = rpccli_samr_DeleteDomAlias(pipe_hnd, mem_ctx,
1747 d_fprintf(stderr, _("%s is of type %s. This command is only "
1748 "for deleting local or global groups\n"),
1749 argv[0],sid_type_lookup(name_types.ids[0]));
1750 result = NT_STATUS_UNSUCCESSFUL;
1754 if (NT_STATUS_IS_OK(result)) {
1756 d_printf(_("Deleted %s '%s'\n"),
1757 sid_type_lookup(name_types.ids[0]), argv[0]);
1759 d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
1760 get_friendly_nt_error_msg(result));
1768 static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
1770 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
1771 rpc_group_delete_internals, argc,argv);
1774 static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
1776 NET_API_STATUS status;
1777 struct GROUP_INFO_1 info1;
1778 uint32_t parm_error = 0;
1780 if (argc != 1 || c->display_usage) {
1781 rpc_group_usage(c, argc, argv);
1787 info1.grpi1_name = argv[0];
1788 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1789 info1.grpi1_comment = c->opt_comment;
1792 status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1796 _("Failed to add group '%s' with error: %s.\n"),
1797 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1801 d_printf(_("Added group '%s'.\n"), argv[0]);
1807 static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
1809 NET_API_STATUS status;
1810 struct LOCALGROUP_INFO_1 info1;
1811 uint32_t parm_error = 0;
1813 if (argc != 1 || c->display_usage) {
1814 rpc_group_usage(c, argc, argv);
1820 info1.lgrpi1_name = argv[0];
1821 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1822 info1.lgrpi1_comment = c->opt_comment;
1825 status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1829 _("Failed to add alias '%s' with error: %s.\n"),
1830 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1834 d_printf(_("Added alias '%s'.\n"), argv[0]);
1840 static int rpc_group_add(struct net_context *c, int argc, const char **argv)
1842 if (c->opt_localgroup)
1843 return rpc_alias_add_internals(c, argc, argv);
1845 return rpc_group_add_internals(c, argc, argv);
1848 static NTSTATUS get_sid_from_name(struct cli_state *cli,
1849 TALLOC_CTX *mem_ctx,
1851 struct dom_sid *sid,
1852 enum lsa_SidType *type)
1854 struct dom_sid *sids = NULL;
1855 enum lsa_SidType *types = NULL;
1856 struct rpc_pipe_client *pipe_hnd = NULL;
1857 struct policy_handle lsa_pol;
1858 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1860 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
1862 if (!NT_STATUS_IS_OK(result)) {
1866 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
1867 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
1869 if (!NT_STATUS_IS_OK(result)) {
1873 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
1874 &name, NULL, 1, &sids, &types);
1876 if (NT_STATUS_IS_OK(result)) {
1877 sid_copy(sid, &sids[0]);
1881 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
1885 TALLOC_FREE(pipe_hnd);
1888 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
1890 /* Try as S-1-5-whatever */
1892 struct dom_sid tmp_sid;
1894 if (string_to_sid(&tmp_sid, name)) {
1895 sid_copy(sid, &tmp_sid);
1896 *type = SID_NAME_UNKNOWN;
1897 result = NT_STATUS_OK;
1904 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
1905 TALLOC_CTX *mem_ctx,
1906 const struct dom_sid *group_sid,
1909 struct policy_handle connect_pol, domain_pol;
1912 struct policy_handle group_pol;
1914 struct samr_Ids rids, rid_types;
1915 struct lsa_String lsa_acct_name;
1919 sid_copy(&sid, group_sid);
1921 if (!sid_split_rid(&sid, &group_rid)) {
1922 return NT_STATUS_UNSUCCESSFUL;
1925 /* Get sam policy handle */
1926 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1928 MAXIMUM_ALLOWED_ACCESS,
1930 if (!NT_STATUS_IS_OK(result)) {
1934 /* Get domain policy handle */
1935 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1937 MAXIMUM_ALLOWED_ACCESS,
1940 if (!NT_STATUS_IS_OK(result)) {
1944 init_lsa_String(&lsa_acct_name, member);
1946 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1953 if (!NT_STATUS_IS_OK(result)) {
1954 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
1959 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1961 MAXIMUM_ALLOWED_ACCESS,
1965 if (!NT_STATUS_IS_OK(result)) {
1969 result = rpccli_samr_AddGroupMember(pipe_hnd, mem_ctx,
1972 0x0005); /* unknown flags */
1975 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1979 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
1980 TALLOC_CTX *mem_ctx,
1981 const struct dom_sid *alias_sid,
1984 struct policy_handle connect_pol, domain_pol;
1987 struct policy_handle alias_pol;
1989 struct dom_sid member_sid;
1990 enum lsa_SidType member_type;
1994 sid_copy(&sid, alias_sid);
1996 if (!sid_split_rid(&sid, &alias_rid)) {
1997 return NT_STATUS_UNSUCCESSFUL;
2000 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2001 member, &member_sid, &member_type);
2003 if (!NT_STATUS_IS_OK(result)) {
2004 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2009 /* Get sam policy handle */
2010 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2012 MAXIMUM_ALLOWED_ACCESS,
2014 if (!NT_STATUS_IS_OK(result)) {
2018 /* Get domain policy handle */
2019 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2021 MAXIMUM_ALLOWED_ACCESS,
2024 if (!NT_STATUS_IS_OK(result)) {
2028 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2030 MAXIMUM_ALLOWED_ACCESS,
2034 if (!NT_STATUS_IS_OK(result)) {
2038 result = rpccli_samr_AddAliasMember(pipe_hnd, mem_ctx,
2042 if (!NT_STATUS_IS_OK(result)) {
2047 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2051 static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
2052 const struct dom_sid *domain_sid,
2053 const char *domain_name,
2054 struct cli_state *cli,
2055 struct rpc_pipe_client *pipe_hnd,
2056 TALLOC_CTX *mem_ctx,
2060 struct dom_sid group_sid;
2061 enum lsa_SidType group_type;
2063 if (argc != 2 || c->display_usage) {
2066 _("net rpc group addmem <group> <member>\n"
2067 " Add a member to a group\n"
2068 " group\tGroup to add member to\n"
2069 " member\tMember to add to group\n"));
2070 return NT_STATUS_UNSUCCESSFUL;
2073 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2074 &group_sid, &group_type))) {
2075 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2077 return NT_STATUS_UNSUCCESSFUL;
2080 if (group_type == SID_NAME_DOM_GRP) {
2081 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2082 &group_sid, argv[1]);
2084 if (!NT_STATUS_IS_OK(result)) {
2085 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2086 argv[1], argv[0], nt_errstr(result));
2091 if (group_type == SID_NAME_ALIAS) {
2092 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2093 &group_sid, argv[1]);
2095 if (!NT_STATUS_IS_OK(result)) {
2096 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2097 argv[1], argv[0], nt_errstr(result));
2102 d_fprintf(stderr, _("Can only add members to global or local groups "
2103 "which %s is not\n"), argv[0]);
2105 return NT_STATUS_UNSUCCESSFUL;
2108 static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2110 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2111 rpc_group_addmem_internals,
2115 static NTSTATUS rpc_del_groupmem(struct net_context *c,
2116 struct rpc_pipe_client *pipe_hnd,
2117 TALLOC_CTX *mem_ctx,
2118 const struct dom_sid *group_sid,
2121 struct policy_handle connect_pol, domain_pol;
2124 struct policy_handle group_pol;
2126 struct samr_Ids rids, rid_types;
2127 struct lsa_String lsa_acct_name;
2131 sid_copy(&sid, group_sid);
2133 if (!sid_split_rid(&sid, &group_rid))
2134 return NT_STATUS_UNSUCCESSFUL;
2136 /* Get sam policy handle */
2137 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2139 MAXIMUM_ALLOWED_ACCESS,
2141 if (!NT_STATUS_IS_OK(result))
2144 /* Get domain policy handle */
2145 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2147 MAXIMUM_ALLOWED_ACCESS,
2150 if (!NT_STATUS_IS_OK(result))
2153 init_lsa_String(&lsa_acct_name, member);
2155 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2161 if (!NT_STATUS_IS_OK(result)) {
2162 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2167 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2169 MAXIMUM_ALLOWED_ACCESS,
2173 if (!NT_STATUS_IS_OK(result))
2176 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
2181 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2185 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2186 TALLOC_CTX *mem_ctx,
2187 const struct dom_sid *alias_sid,
2190 struct policy_handle connect_pol, domain_pol;
2193 struct policy_handle alias_pol;
2195 struct dom_sid member_sid;
2196 enum lsa_SidType member_type;
2200 sid_copy(&sid, alias_sid);
2202 if (!sid_split_rid(&sid, &alias_rid))
2203 return NT_STATUS_UNSUCCESSFUL;
2205 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2206 member, &member_sid, &member_type);
2208 if (!NT_STATUS_IS_OK(result)) {
2209 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2214 /* Get sam policy handle */
2215 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2217 MAXIMUM_ALLOWED_ACCESS,
2219 if (!NT_STATUS_IS_OK(result)) {
2223 /* Get domain policy handle */
2224 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2226 MAXIMUM_ALLOWED_ACCESS,
2229 if (!NT_STATUS_IS_OK(result)) {
2233 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2235 MAXIMUM_ALLOWED_ACCESS,
2239 if (!NT_STATUS_IS_OK(result))
2242 result = rpccli_samr_DeleteAliasMember(pipe_hnd, mem_ctx,
2246 if (!NT_STATUS_IS_OK(result))
2250 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2254 static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2255 const struct dom_sid *domain_sid,
2256 const char *domain_name,
2257 struct cli_state *cli,
2258 struct rpc_pipe_client *pipe_hnd,
2259 TALLOC_CTX *mem_ctx,
2263 struct dom_sid group_sid;
2264 enum lsa_SidType group_type;
2266 if (argc != 2 || c->display_usage) {
2269 _("net rpc group delmem <group> <member>\n"
2270 " Delete a member from a group\n"
2271 " group\tGroup to delete member from\n"
2272 " member\tMember to delete from group\n"));
2273 return NT_STATUS_UNSUCCESSFUL;
2276 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2277 &group_sid, &group_type))) {
2278 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2280 return NT_STATUS_UNSUCCESSFUL;
2283 if (group_type == SID_NAME_DOM_GRP) {
2284 NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2285 &group_sid, argv[1]);
2287 if (!NT_STATUS_IS_OK(result)) {
2288 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2289 argv[1], argv[0], nt_errstr(result));
2294 if (group_type == SID_NAME_ALIAS) {
2295 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2296 &group_sid, argv[1]);
2298 if (!NT_STATUS_IS_OK(result)) {
2299 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2300 argv[1], argv[0], nt_errstr(result));
2305 d_fprintf(stderr, _("Can only delete members from global or local "
2306 "groups which %s is not\n"), argv[0]);
2308 return NT_STATUS_UNSUCCESSFUL;
2311 static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2313 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2314 rpc_group_delmem_internals,
2319 * List groups on a remote RPC server.
2321 * All parameters are provided by the run_rpc_command function, except for
2322 * argc, argv which are passes through.
2324 * @param domain_sid The domain sid acquired from the remote server.
2325 * @param cli A cli_state connected to the server.
2326 * @param mem_ctx Talloc context, destroyed on completion of the function.
2327 * @param argc Standard main() style argc.
2328 * @param argv Standard main() style argv. Initial components are already
2331 * @return Normal NTSTATUS return.
2334 static NTSTATUS rpc_group_list_internals(struct net_context *c,
2335 const struct dom_sid *domain_sid,
2336 const char *domain_name,
2337 struct cli_state *cli,
2338 struct rpc_pipe_client *pipe_hnd,
2339 TALLOC_CTX *mem_ctx,
2343 struct policy_handle connect_pol, domain_pol;
2344 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2345 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2346 struct samr_SamArray *groups = NULL;
2347 bool global = false;
2349 bool builtin = false;
2351 if (c->display_usage) {
2354 _("net rpc group list [global] [local] [builtin]\n"
2355 " List groups on RPC server\n"
2356 " global\tList global groups\n"
2357 " local\tList local groups\n"
2358 " builtin\tList builtin groups\n"
2359 " If none of global, local or builtin is "
2360 "specified, all three options are considered "
2362 return NT_STATUS_OK;
2371 for (i=0; i<argc; i++) {
2372 if (strequal(argv[i], "global"))
2375 if (strequal(argv[i], "local"))
2378 if (strequal(argv[i], "builtin"))
2382 /* Get sam policy handle */
2384 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2386 MAXIMUM_ALLOWED_ACCESS,
2388 if (!NT_STATUS_IS_OK(result)) {
2392 /* Get domain policy handle */
2394 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2396 MAXIMUM_ALLOWED_ACCESS,
2397 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2399 if (!NT_STATUS_IS_OK(result)) {
2403 /* Query domain groups */
2404 if (c->opt_long_list_entries)
2405 d_printf(_("\nGroup name Comment"
2406 "\n-----------------------------\n"));
2408 uint32_t max_size, total_size, returned_size;
2409 union samr_DispInfo info;
2413 dcerpc_get_query_dispinfo_params(
2414 loop_count, &max_entries, &max_size);
2416 result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx,
2425 num_entries = info.info3.count;
2426 start_idx += info.info3.count;
2428 if (!NT_STATUS_IS_OK(result) &&
2429 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2432 for (i = 0; i < num_entries; i++) {
2434 const char *group = NULL;
2435 const char *desc = NULL;
2437 group = info.info3.entries[i].account_name.string;
2438 desc = info.info3.entries[i].description.string;
2440 if (c->opt_long_list_entries)
2441 printf("%-21.21s %-50.50s\n",
2444 printf("%s\n", group);
2446 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2447 /* query domain aliases */
2452 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2458 if (!NT_STATUS_IS_OK(result) &&
2459 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2462 for (i = 0; i < num_entries; i++) {
2464 const char *description = NULL;
2466 if (c->opt_long_list_entries) {
2468 struct policy_handle alias_pol;
2469 union samr_AliasInfo *info = NULL;
2471 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2474 groups->entries[i].idx,
2476 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2480 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2482 description = info->description.string;
2486 if (description != NULL) {
2487 printf("%-21.21s %-50.50s\n",
2488 groups->entries[i].name.string,
2491 printf("%s\n", groups->entries[i].name.string);
2494 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2495 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2496 /* Get builtin policy handle */
2498 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2500 MAXIMUM_ALLOWED_ACCESS,
2501 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
2503 if (!NT_STATUS_IS_OK(result)) {
2506 /* query builtin aliases */
2509 if (!builtin) break;
2511 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2517 if (!NT_STATUS_IS_OK(result) &&
2518 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2521 for (i = 0; i < num_entries; i++) {
2523 const char *description = NULL;
2525 if (c->opt_long_list_entries) {
2527 struct policy_handle alias_pol;
2528 union samr_AliasInfo *info = NULL;
2530 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2533 groups->entries[i].idx,
2535 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2539 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2541 description = info->description.string;
2545 if (description != NULL) {
2546 printf("%-21.21s %-50.50s\n",
2547 groups->entries[i].name.string,
2550 printf("%s\n", groups->entries[i].name.string);
2553 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2559 static int rpc_group_list(struct net_context *c, int argc, const char **argv)
2561 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2562 rpc_group_list_internals,
2566 static NTSTATUS rpc_list_group_members(struct net_context *c,
2567 struct rpc_pipe_client *pipe_hnd,
2568 TALLOC_CTX *mem_ctx,
2569 const char *domain_name,
2570 const struct dom_sid *domain_sid,
2571 struct policy_handle *domain_pol,
2575 struct policy_handle group_pol;
2576 uint32 num_members, *group_rids;
2578 struct samr_RidAttrArray *rids = NULL;
2579 struct lsa_Strings names;
2580 struct samr_Ids types;
2583 sid_to_fstring(sid_str, domain_sid);
2585 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2587 MAXIMUM_ALLOWED_ACCESS,
2591 if (!NT_STATUS_IS_OK(result))
2594 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
2598 if (!NT_STATUS_IS_OK(result))
2601 num_members = rids->count;
2602 group_rids = rids->rids;
2604 while (num_members > 0) {
2605 int this_time = 512;
2607 if (num_members < this_time)
2608 this_time = num_members;
2610 result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx,
2617 if (!NT_STATUS_IS_OK(result))
2620 /* We only have users as members, but make the output
2621 the same as the output of alias members */
2623 for (i = 0; i < this_time; i++) {
2625 if (c->opt_long_list_entries) {
2626 printf("%s-%d %s\\%s %d\n", sid_str,
2627 group_rids[i], domain_name,
2628 names.names[i].string,
2631 printf("%s\\%s\n", domain_name,
2632 names.names[i].string);
2636 num_members -= this_time;
2640 return NT_STATUS_OK;
2643 static NTSTATUS rpc_list_alias_members(struct net_context *c,
2644 struct rpc_pipe_client *pipe_hnd,
2645 TALLOC_CTX *mem_ctx,
2646 struct policy_handle *domain_pol,
2650 struct rpc_pipe_client *lsa_pipe;
2651 struct policy_handle alias_pol, lsa_pol;
2653 struct dom_sid *alias_sids;
2656 enum lsa_SidType *types;
2658 struct lsa_SidArray sid_array;
2660 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2662 MAXIMUM_ALLOWED_ACCESS,
2666 if (!NT_STATUS_IS_OK(result))
2669 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
2673 if (!NT_STATUS_IS_OK(result)) {
2674 d_fprintf(stderr, _("Couldn't list alias members\n"));
2678 num_members = sid_array.num_sids;
2680 if (num_members == 0) {
2681 return NT_STATUS_OK;
2684 result = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd),
2685 &ndr_table_lsarpc.syntax_id,
2687 if (!NT_STATUS_IS_OK(result)) {
2688 d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
2689 nt_errstr(result) );
2693 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
2694 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2696 if (!NT_STATUS_IS_OK(result)) {
2697 d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
2698 TALLOC_FREE(lsa_pipe);
2702 alias_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);
2704 d_fprintf(stderr, _("Out of memory\n"));
2705 TALLOC_FREE(lsa_pipe);
2706 return NT_STATUS_NO_MEMORY;
2709 for (i=0; i<num_members; i++) {
2710 sid_copy(&alias_sids[i], sid_array.sids[i].sid);
2713 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
2714 num_members, alias_sids,
2715 &domains, &names, &types);
2717 if (!NT_STATUS_IS_OK(result) &&
2718 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2719 d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
2720 TALLOC_FREE(lsa_pipe);
2724 for (i = 0; i < num_members; i++) {
2726 sid_to_fstring(sid_str, &alias_sids[i]);
2728 if (c->opt_long_list_entries) {
2729 printf("%s %s\\%s %d\n", sid_str,
2730 domains[i] ? domains[i] : _("*unknown*"),
2731 names[i] ? names[i] : _("*unknown*"), types[i]);
2734 printf("%s\\%s\n", domains[i], names[i]);
2736 printf("%s\n", sid_str);
2740 TALLOC_FREE(lsa_pipe);
2741 return NT_STATUS_OK;
2744 static NTSTATUS rpc_group_members_internals(struct net_context *c,
2745 const struct dom_sid *domain_sid,
2746 const char *domain_name,
2747 struct cli_state *cli,
2748 struct rpc_pipe_client *pipe_hnd,
2749 TALLOC_CTX *mem_ctx,
2754 struct policy_handle connect_pol, domain_pol;
2755 struct samr_Ids rids, rid_types;
2756 struct lsa_String lsa_acct_name;
2758 /* Get sam policy handle */
2760 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2762 MAXIMUM_ALLOWED_ACCESS,
2765 if (!NT_STATUS_IS_OK(result))
2768 /* Get domain policy handle */
2770 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2772 MAXIMUM_ALLOWED_ACCESS,
2773 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2776 if (!NT_STATUS_IS_OK(result))
2779 init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
2781 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2788 if (!NT_STATUS_IS_OK(result)) {
2790 /* Ok, did not find it in the global sam, try with builtin */
2792 struct dom_sid sid_Builtin;
2794 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2796 sid_copy(&sid_Builtin, &global_sid_Builtin);
2798 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2800 MAXIMUM_ALLOWED_ACCESS,
2804 if (!NT_STATUS_IS_OK(result)) {
2805 d_fprintf(stderr, _("Couldn't find group %s\n"),
2810 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2817 if (!NT_STATUS_IS_OK(result)) {
2818 d_fprintf(stderr, _("Couldn't find group %s\n"),
2824 if (rids.count != 1) {
2825 d_fprintf(stderr, _("Couldn't find group %s\n"),
2830 if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
2831 return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
2832 domain_sid, &domain_pol,
2836 if (rid_types.ids[0] == SID_NAME_ALIAS) {
2837 return rpc_list_alias_members(c, pipe_hnd, mem_ctx, &domain_pol,
2841 return NT_STATUS_NO_SUCH_GROUP;
2844 static int rpc_group_members(struct net_context *c, int argc, const char **argv)
2846 if (argc != 1 || c->display_usage) {
2847 return rpc_group_usage(c, argc, argv);
2850 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2851 rpc_group_members_internals,
2855 static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
2857 NET_API_STATUS status;
2858 struct GROUP_INFO_0 g0;
2862 d_printf(_("Usage:\n"));
2863 d_printf("net rpc group rename group newname\n");
2867 g0.grpi0_name = argv[1];
2869 status = NetGroupSetInfo(c->opt_host,
2876 d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
2877 argv[0], libnetapi_get_error_string(c->netapi_ctx,
2885 static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
2887 if (argc != 2 || c->display_usage) {
2888 return rpc_group_usage(c, argc, argv);
2891 return rpc_group_rename_internals(c, argc, argv);
2895 * 'net rpc group' entrypoint.
2896 * @param argc Standard main() style argc.
2897 * @param argv Standard main() style argv. Initial components are already
2901 int net_rpc_group(struct net_context *c, int argc, const char **argv)
2903 NET_API_STATUS status;
2905 struct functable func[] = {
2910 N_("Create specified group"),
2911 N_("net rpc group add\n"
2912 " Create specified group")
2918 N_("Delete specified group"),
2919 N_("net rpc group delete\n"
2920 " Delete specified group")
2926 N_("Add member to group"),
2927 N_("net rpc group addmem\n"
2928 " Add member to group")
2934 N_("Remove member from group"),
2935 N_("net rpc group delmem\n"
2936 " Remove member from group")
2943 N_("net rpc group list\n"
2950 N_("List group members"),
2951 N_("net rpc group members\n"
2952 " List group members")
2959 N_("net rpc group rename\n"
2962 {NULL, NULL, 0, NULL, NULL}
2965 status = libnetapi_net_init(&c->netapi_ctx);
2969 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
2970 libnetapi_set_password(c->netapi_ctx, c->opt_password);
2971 if (c->opt_kerberos) {
2972 libnetapi_set_use_kerberos(c->netapi_ctx);
2976 if (c->display_usage) {
2977 d_printf(_("Usage:\n"));
2978 d_printf(_("net rpc group\n"
2979 " Alias for net rpc group list global "
2980 "local builtin\n"));
2981 net_display_usage_from_functable(func);
2985 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2986 rpc_group_list_internals,
2990 return net_run_function(c, argc, argv, "net rpc group", func);
2993 /****************************************************************************/
2995 static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
2997 return net_share_usage(c, argc, argv);
3001 * Add a share on a remote RPC server.
3003 * @param argc Standard main() style argc.
3004 * @param argv Standard main() style argv. Initial components are already
3007 * @return A shell status integer (0 for success).
3010 static int rpc_share_add(struct net_context *c, int argc, const char **argv)
3012 NET_API_STATUS status;
3015 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3016 uint32 num_users=0, perms=0;
3017 char *password=NULL; /* don't allow a share password */
3018 struct SHARE_INFO_2 i2;
3019 uint32_t parm_error = 0;
3021 if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
3022 return rpc_share_usage(c, argc, argv);
3025 if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
3029 path = strchr(sharename, '=');
3036 i2.shi2_netname = sharename;
3037 i2.shi2_type = type;
3038 i2.shi2_remark = c->opt_comment;
3039 i2.shi2_permissions = perms;
3040 i2.shi2_max_uses = c->opt_maxusers;
3041 i2.shi2_current_uses = num_users;
3042 i2.shi2_path = path;
3043 i2.shi2_passwd = password;
3045 status = NetShareAdd(c->opt_host,
3050 printf(_("NetShareAdd failed with: %s\n"),
3051 libnetapi_get_error_string(c->netapi_ctx, status));
3058 * Delete a share on a remote RPC server.
3060 * @param domain_sid The domain sid acquired from the remote server.
3061 * @param argc Standard main() style argc.
3062 * @param argv Standard main() style argv. Initial components are already
3065 * @return A shell status integer (0 for success).
3067 static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
3069 if (argc < 1 || c->display_usage) {
3070 return rpc_share_usage(c, argc, argv);
3073 return NetShareDel(c->opt_host, argv[0], 0);
3077 * Formatted print of share info
3079 * @param r pointer to SHARE_INFO_1 to format
3082 static void display_share_info_1(struct net_context *c,
3083 struct SHARE_INFO_1 *r)
3085 if (c->opt_long_list_entries) {
3086 d_printf("%-12s %-8.8s %-50s\n",
3088 net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3091 d_printf("%s\n", r->shi1_netname);
3095 static WERROR get_share_info(struct net_context *c,
3096 struct rpc_pipe_client *pipe_hnd,
3097 TALLOC_CTX *mem_ctx,
3101 struct srvsvc_NetShareInfoCtr *info_ctr)
3105 union srvsvc_NetShareInfo info;
3106 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3108 /* no specific share requested, enumerate all */
3111 uint32_t preferred_len = 0xffffffff;
3112 uint32_t total_entries = 0;
3113 uint32_t resume_handle = 0;
3115 info_ctr->level = level;
3117 status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx,
3124 if (!NT_STATUS_IS_OK(status)) {
3125 return ntstatus_to_werror(status);
3130 /* request just one share */
3131 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
3138 if (!NT_STATUS_IS_OK(status)) {
3139 result = ntstatus_to_werror(status);
3143 if (!W_ERROR_IS_OK(result)) {
3148 ZERO_STRUCTP(info_ctr);
3150 info_ctr->level = level;
3155 struct srvsvc_NetShareCtr1 *ctr1;
3157 ctr1 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr1);
3158 W_ERROR_HAVE_NO_MEMORY(ctr1);
3161 ctr1->array = info.info1;
3163 info_ctr->ctr.ctr1 = ctr1;
3169 struct srvsvc_NetShareCtr2 *ctr2;
3171 ctr2 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr2);
3172 W_ERROR_HAVE_NO_MEMORY(ctr2);
3175 ctr2->array = info.info2;
3177 info_ctr->ctr.ctr2 = ctr2;
3183 struct srvsvc_NetShareCtr502 *ctr502;
3185 ctr502 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr502);
3186 W_ERROR_HAVE_NO_MEMORY(ctr502);
3189 ctr502->array = info.info502;
3191 info_ctr->ctr.ctr502 = ctr502;
3201 * 'net rpc share list' entrypoint.
3202 * @param argc Standard main() style argc.
3203 * @param argv Standard main() style argv. Initial components are already
3206 static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3208 NET_API_STATUS status;
3209 struct SHARE_INFO_1 *i1 = NULL;
3210 uint32_t entries_read = 0;
3211 uint32_t total_entries = 0;
3212 uint32_t resume_handle = 0;
3213 uint32_t i, level = 1;
3215 if (c->display_usage) {
3217 "net rpc share list\n"
3220 _("List shares on remote server"));
3224 status = NetShareEnum(c->opt_host,
3226 (uint8_t **)(void *)&i1,
3235 /* Display results */
3237 if (c->opt_long_list_entries) {
3239 "\nEnumerating shared resources (exports) on remote server:\n\n"
3240 "\nShare name Type Description\n"
3241 "---------- ---- -----------\n"));
3243 for (i = 0; i < entries_read; i++)
3244 display_share_info_1(c, &i1[i]);
3249 static bool check_share_availability(struct cli_state *cli, const char *netname)
3253 status = cli_tcon_andx(cli, netname, "A:", "", 0);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 d_printf(_("skipping [%s]: not a file share.\n"), netname);
3259 status = cli_tdis(cli);
3260 if (!NT_STATUS_IS_OK(status)) {
3261 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3268 static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3269 const char *netname, uint32 type)
3271 /* only support disk shares */
3272 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3273 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3278 /* skip builtin shares */
3279 /* FIXME: should print$ be added too ? */
3280 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3281 strequal(netname,"global"))
3284 if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3285 printf(_("excluding [%s]\n"), netname);
3289 return check_share_availability(cli, netname);
3293 * Migrate shares from a remote RPC server to the local RPC server.
3295 * All parameters are provided by the run_rpc_command function, except for
3296 * argc, argv which are passed through.
3298 * @param domain_sid The domain sid acquired from the remote server.
3299 * @param cli A cli_state connected to the server.
3300 * @param mem_ctx Talloc context, destroyed on completion of the function.
3301 * @param argc Standard main() style argc.
3302 * @param argv Standard main() style argv. Initial components are already
3305 * @return Normal NTSTATUS return.
3308 static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3309 const struct dom_sid *domain_sid,
3310 const char *domain_name,
3311 struct cli_state *cli,
3312 struct rpc_pipe_client *pipe_hnd,
3313 TALLOC_CTX *mem_ctx,
3318 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3319 struct srvsvc_NetShareInfoCtr ctr_src;
3321 struct rpc_pipe_client *srvsvc_pipe = NULL;
3322 struct cli_state *cli_dst = NULL;
3323 uint32 level = 502; /* includes secdesc */
3324 uint32_t parm_error = 0;
3325 struct dcerpc_binding_handle *b;
3327 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3329 if (!W_ERROR_IS_OK(result))
3332 /* connect destination PI_SRVSVC */
3333 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3334 &ndr_table_srvsvc.syntax_id);
3335 if (!NT_STATUS_IS_OK(nt_status))
3338 b = srvsvc_pipe->binding_handle;
3340 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3342 union srvsvc_NetShareInfo info;
3343 struct srvsvc_NetShareInfo502 info502 =
3344 ctr_src.ctr.ctr502->array[i];
3346 /* reset error-code */
3347 nt_status = NT_STATUS_UNSUCCESSFUL;
3349 if (!check_share_sanity(c, cli, info502.name, info502.type))
3352 /* finally add the share on the dst server */
3354 printf(_("migrating: [%s], path: %s, comment: %s, without "
3356 info502.name, info502.path, info502.comment);
3358 info.info502 = &info502;
3360 nt_status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
3361 srvsvc_pipe->desthost,
3366 if (!NT_STATUS_IS_OK(nt_status)) {
3367 printf(_("cannot add share: %s\n"),
3368 nt_errstr(nt_status));
3371 if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3372 printf(_(" [%s] does already exist\n"),
3377 if (!W_ERROR_IS_OK(result)) {
3378 nt_status = werror_to_ntstatus(result);
3379 printf(_("cannot add share: %s\n"),
3380 win_errstr(result));
3386 nt_status = NT_STATUS_OK;
3390 cli_shutdown(cli_dst);
3398 * Migrate shares from a RPC server to another.
3400 * @param argc Standard main() style argc.
3401 * @param argv Standard main() style argv. Initial components are already
3404 * @return A shell status integer (0 for success).
3406 static int rpc_share_migrate_shares(struct net_context *c, int argc,
3409 if (c->display_usage) {
3411 "net rpc share migrate shares\n"
3414 _("Migrate shares to local server"));
3419 printf(_("no server to migrate\n"));
3423 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3424 rpc_share_migrate_shares_internals,
3431 * @param f file_info
3432 * @param mask current search mask
3433 * @param state arg-pointer
3436 static NTSTATUS copy_fn(const char *mnt, struct file_info *f,
3437 const char *mask, void *state)
3439 static NTSTATUS nt_status;
3440 static struct copy_clistate *local_state;
3441 static fstring filename, new_mask;
3444 struct net_context *c;
3446 local_state = (struct copy_clistate *)state;
3447 nt_status = NT_STATUS_UNSUCCESSFUL;
3451 if (strequal(f->name, ".") || strequal(f->name, ".."))
3452 return NT_STATUS_OK;
3454 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3457 if (f->mode & aDIR) {
3459 DEBUG(3,("got dir: %s\n", f->name));
3461 fstrcpy(dir, local_state->cwd);
3463 fstrcat(dir, f->name);
3465 switch (net_mode_share)
3467 case NET_MODE_SHARE_MIGRATE:
3468 /* create that directory */
3469 nt_status = net_copy_file(c, local_state->mem_ctx,
3470 local_state->cli_share_src,
3471 local_state->cli_share_dst,
3473 c->opt_acls? true : false,
3474 c->opt_attrs? true : false,
3475 c->opt_timestamps? true:false,
3479 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3480 return NT_STATUS_INTERNAL_ERROR;
3483 if (!NT_STATUS_IS_OK(nt_status)) {
3484 printf(_("could not handle dir %s: %s\n"),
3485 dir, nt_errstr(nt_status));
3489 /* search below that directory */
3490 fstrcpy(new_mask, dir);
3491 fstrcat(new_mask, "\\*");
3493 old_dir = local_state->cwd;
3494 local_state->cwd = dir;
3495 nt_status = sync_files(local_state, new_mask);
3496 if (!NT_STATUS_IS_OK(nt_status)) {
3497 printf(_("could not handle files\n"));
3499 local_state->cwd = old_dir;
3506 fstrcpy(filename, local_state->cwd);
3507 fstrcat(filename, "\\");
3508 fstrcat(filename, f->name);
3510 DEBUG(3,("got file: %s\n", filename));
3512 switch (net_mode_share)
3514 case NET_MODE_SHARE_MIGRATE:
3515 nt_status = net_copy_file(c, local_state->mem_ctx,
3516 local_state->cli_share_src,
3517 local_state->cli_share_dst,
3519 c->opt_acls? true : false,
3520 c->opt_attrs? true : false,
3521 c->opt_timestamps? true: false,
3525 d_fprintf(stderr, _("Unsupported file mode %d\n"),
3527 return NT_STATUS_INTERNAL_ERROR;
3530 if (!NT_STATUS_IS_OK(nt_status))
3531 printf(_("could not handle file %s: %s\n"),
3532 filename, nt_errstr(nt_status));
3537 * sync files, can be called recursivly to list files
3538 * and then call copy_fn for each file
3540 * @param cp_clistate pointer to the copy_clistate we work with
3541 * @param mask the current search mask
3543 * @return Boolean result
3545 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask)
3547 struct cli_state *targetcli;
3548 char *targetpath = NULL;
3551 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3553 if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
3554 mask, &targetcli, &targetpath ) ) {
3555 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
3557 mask, cli_errstr(cp_clistate->cli_share_src));
3558 return cli_nt_error(cp_clistate->cli_share_src);
3561 status = cli_list(targetcli, targetpath, cp_clistate->attribute,
3562 copy_fn, cp_clistate);
3563 if (!NT_STATUS_IS_OK(status)) {
3564 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
3565 mask, nt_errstr(status));
3573 * Set the top level directory permissions before we do any further copies.
3574 * Should set up ACL inheritance.
3577 bool copy_top_level_perms(struct net_context *c,
3578 struct copy_clistate *cp_clistate,
3579 const char *sharename)
3581 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3583 switch (net_mode_share) {
3584 case NET_MODE_SHARE_MIGRATE:
3585 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3586 nt_status = net_copy_fileattr(c,
3587 cp_clistate->mem_ctx,
3588 cp_clistate->cli_share_src,
3589 cp_clistate->cli_share_dst,
3591 c->opt_acls? true : false,
3592 c->opt_attrs? true : false,
3593 c->opt_timestamps? true: false,
3597 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3601 if (!NT_STATUS_IS_OK(nt_status)) {
3602 printf(_("Could handle directory attributes for top level "
3603 "directory of share %s. Error %s\n"),
3604 sharename, nt_errstr(nt_status));
3612 * Sync all files inside a remote share to another share (over smb).
3614 * All parameters are provided by the run_rpc_command function, except for
3615 * argc, argv which are passed through.
3617 * @param domain_sid The domain sid acquired from the remote server.
3618 * @param cli A cli_state connected to the server.
3619 * @param mem_ctx Talloc context, destroyed on completion of the function.
3620 * @param argc Standard main() style argc.
3621 * @param argv Standard main() style argv. Initial components are already
3624 * @return Normal NTSTATUS return.
3627 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
3628 const struct dom_sid *domain_sid,
3629 const char *domain_name,
3630 struct cli_state *cli,
3631 struct rpc_pipe_client *pipe_hnd,
3632 TALLOC_CTX *mem_ctx,
3637 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3638 struct srvsvc_NetShareInfoCtr ctr_src;
3641 struct copy_clistate cp_clistate;
3642 bool got_src_share = false;
3643 bool got_dst_share = false;
3644 const char *mask = "\\*";
3647 dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
3649 nt_status = NT_STATUS_NO_MEMORY;
3653 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3656 if (!W_ERROR_IS_OK(result))
3659 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3661 struct srvsvc_NetShareInfo502 info502 =
3662 ctr_src.ctr.ctr502->array[i];
3664 if (!check_share_sanity(c, cli, info502.name, info502.type))
3667 /* one might not want to mirror whole discs :) */
3668 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
3669 d_printf(_("skipping [%s]: builtin/hidden share\n"),
3674 switch (net_mode_share)
3676 case NET_MODE_SHARE_MIGRATE:
3680 d_fprintf(stderr, _("Unsupported mode %d\n"),
3684 printf(_(" [%s] files and directories %s ACLs, %s DOS "
3687 c->opt_acls ? _("including") : _("without"),
3688 c->opt_attrs ? _("including") : _("without"),
3689 c->opt_timestamps ? _("(preserving timestamps)") : "");
3691 cp_clistate.mem_ctx = mem_ctx;
3692 cp_clistate.cli_share_src = NULL;
3693 cp_clistate.cli_share_dst = NULL;
3694 cp_clistate.cwd = NULL;
3695 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3698 /* open share source */
3699 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
3700 &cli->dest_ss, cli->desthost,
3701 info502.name, "A:");
3702 if (!NT_STATUS_IS_OK(nt_status))
3705 got_src_share = true;
3707 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3708 /* open share destination */
3709 nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
3710 NULL, dst, info502.name, "A:");
3711 if (!NT_STATUS_IS_OK(nt_status))
3714 got_dst_share = true;
3717 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
3718 d_fprintf(stderr, _("Could not handle the top level "
3719 "directory permissions for the "
3720 "share: %s\n"), info502.name);
3721 nt_status = NT_STATUS_UNSUCCESSFUL;
3725 nt_status = sync_files(&cp_clistate, mask);
3726 if (!NT_STATUS_IS_OK(nt_status)) {
3727 d_fprintf(stderr, _("could not handle files for share: "
3728 "%s\n"), info502.name);
3733 nt_status = NT_STATUS_OK;
3738 cli_shutdown(cp_clistate.cli_share_src);
3741 cli_shutdown(cp_clistate.cli_share_dst);
3748 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
3750 if (c->display_usage) {
3752 "net share migrate files\n"
3755 _("Migrate files to local server"));
3760 d_printf(_("no server to migrate\n"));
3764 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3765 rpc_share_migrate_files_internals,
3770 * Migrate share-ACLs from a remote RPC server to the local RPC server.
3772 * All parameters are provided by the run_rpc_command function, except for
3773 * argc, argv which are passed through.
3775 * @param domain_sid The domain sid acquired from the remote server.
3776 * @param cli A cli_state connected to the server.
3777 * @param mem_ctx Talloc context, destroyed on completion of the function.
3778 * @param argc Standard main() style argc.
3779 * @param argv Standard main() style argv. Initial components are already
3782 * @return Normal NTSTATUS return.
3785 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
3786 const struct dom_sid *domain_sid,
3787 const char *domain_name,
3788 struct cli_state *cli,
3789 struct rpc_pipe_client *pipe_hnd,
3790 TALLOC_CTX *mem_ctx,
3795 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3796 struct srvsvc_NetShareInfoCtr ctr_src;
3797 union srvsvc_NetShareInfo info;
3799 struct rpc_pipe_client *srvsvc_pipe = NULL;
3800 struct cli_state *cli_dst = NULL;
3801 uint32 level = 502; /* includes secdesc */
3802 uint32_t parm_error = 0;
3803 struct dcerpc_binding_handle *b;
3805 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3808 if (!W_ERROR_IS_OK(result))
3811 /* connect destination PI_SRVSVC */
3812 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3813 &ndr_table_srvsvc.syntax_id);
3814 if (!NT_STATUS_IS_OK(nt_status))
3817 b = srvsvc_pipe->binding_handle;
3819 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3821 struct srvsvc_NetShareInfo502 info502 =
3822 ctr_src.ctr.ctr502->array[i];
3824 /* reset error-code */
3825 nt_status = NT_STATUS_UNSUCCESSFUL;
3827 if (!check_share_sanity(c, cli, info502.name, info502.type))
3830 printf(_("migrating: [%s], path: %s, comment: %s, including "
3832 info502.name, info502.path, info502.comment);
3835 display_sec_desc(info502.sd_buf.sd);
3837 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3838 info.info502 = &info502;
3840 /* finally modify the share on the dst server */
3841 nt_status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx,
3842 srvsvc_pipe->desthost,
3848 if (!NT_STATUS_IS_OK(nt_status)) {
3849 printf(_("cannot set share-acl: %s\n"),
3850 nt_errstr(nt_status));
3853 if (!W_ERROR_IS_OK(result)) {
3854 nt_status = werror_to_ntstatus(result);
3855 printf(_("cannot set share-acl: %s\n"),
3856 win_errstr(result));
3862 nt_status = NT_STATUS_OK;
3866 cli_shutdown(cli_dst);
3874 * Migrate share-acls from a RPC server to another.
3876 * @param argc Standard main() style argc.
3877 * @param argv Standard main() style argv. Initial components are already
3880 * @return A shell status integer (0 for success).
3882 static int rpc_share_migrate_security(struct net_context *c, int argc,
3885 if (c->display_usage) {
3887 "net rpc share migrate security\n"
3890 _("Migrate share-acls to local server"));
3895 d_printf(_("no server to migrate\n"));
3899 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3900 rpc_share_migrate_security_internals,
3905 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3906 * from one server to another.
3908 * @param argc Standard main() style argc.
3909 * @param argv Standard main() style argv. Initial components are already
3912 * @return A shell status integer (0 for success).
3915 static int rpc_share_migrate_all(struct net_context *c, int argc,
3920 if (c->display_usage) {
3922 "net rpc share migrate all\n"
3925 _("Migrates shares including all share settings"));
3930 d_printf(_("no server to migrate\n"));
3934 /* order is important. we don't want to be locked out by the share-acl
3935 * before copying files - gd */
3937 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3938 rpc_share_migrate_shares_internals, argc, argv);
3942 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3943 rpc_share_migrate_files_internals, argc, argv);
3947 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3948 rpc_share_migrate_security_internals, argc,
3954 * 'net rpc share migrate' entrypoint.
3955 * @param argc Standard main() style argc.
3956 * @param argv Standard main() style argv. Initial components are already
3959 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
3962 struct functable func[] = {
3965 rpc_share_migrate_all,
3967 N_("Migrate shares from remote to local server"),
3968 N_("net rpc share migrate all\n"
3969 " Migrate shares from remote to local server")
3973 rpc_share_migrate_files,
3975 N_("Migrate files from remote to local server"),
3976 N_("net rpc share migrate files\n"
3977 " Migrate files from remote to local server")
3981 rpc_share_migrate_security,
3983 N_("Migrate share-ACLs from remote to local server"),
3984 N_("net rpc share migrate security\n"
3985 " Migrate share-ACLs from remote to local server")
3989 rpc_share_migrate_shares,
3991 N_("Migrate shares from remote to local server"),
3992 N_("net rpc share migrate shares\n"
3993 " Migrate shares from remote to local server")
3995 {NULL, NULL, 0, NULL, NULL}
3998 net_mode_share = NET_MODE_SHARE_MIGRATE;
4000 return net_run_function(c, argc, argv, "net rpc share migrate", func);
4006 struct dom_sid *members;
4009 static int num_server_aliases;
4010 static struct full_alias *server_aliases;
4013 * Add an alias to the static list.
4015 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
4017 if (server_aliases == NULL)
4018 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
4020 server_aliases[num_server_aliases] = *alias;
4021 num_server_aliases += 1;
4025 * For a specific domain on the server, fetch all the aliases
4026 * and their members. Add all of them to the server_aliases.
4029 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4030 TALLOC_CTX *mem_ctx,
4031 struct policy_handle *connect_pol,
4032 const struct dom_sid *domain_sid)
4034 uint32 start_idx, max_entries, num_entries, i;
4035 struct samr_SamArray *groups = NULL;
4037 struct policy_handle domain_pol;
4039 /* Get domain policy handle */
4041 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
4043 MAXIMUM_ALLOWED_ACCESS,
4044 CONST_DISCARD(struct dom_sid2 *, domain_sid),
4046 if (!NT_STATUS_IS_OK(result))
4053 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
4059 for (i = 0; i < num_entries; i++) {
4061 struct policy_handle alias_pol;
4062 struct full_alias alias;
4063 struct lsa_SidArray sid_array;
4066 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
4068 MAXIMUM_ALLOWED_ACCESS,
4069 groups->entries[i].idx,
4071 if (!NT_STATUS_IS_OK(result))
4074 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
4077 if (!NT_STATUS_IS_OK(result))
4080 alias.num_members = sid_array.num_sids;
4082 result = rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol);
4083 if (!NT_STATUS_IS_OK(result))
4086 alias.members = NULL;
4088 if (alias.num_members > 0) {
4089 alias.members = SMB_MALLOC_ARRAY(struct dom_sid, alias.num_members);
4091 for (j = 0; j < alias.num_members; j++)
4092 sid_copy(&alias.members[j],
4093 sid_array.sids[j].sid);
4096 sid_compose(&alias.sid, domain_sid,
4097 groups->entries[i].idx);
4099 push_alias(mem_ctx, &alias);
4101 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4103 result = NT_STATUS_OK;
4106 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
4112 * Dump server_aliases as names for debugging purposes.
4115 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4116 const struct dom_sid *domain_sid,
4117 const char *domain_name,
4118 struct cli_state *cli,
4119 struct rpc_pipe_client *pipe_hnd,
4120 TALLOC_CTX *mem_ctx,
4126 struct policy_handle lsa_pol;
4128 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4129 SEC_FLAG_MAXIMUM_ALLOWED,
4131 if (!NT_STATUS_IS_OK(result))
4134 for (i=0; i<num_server_aliases; i++) {
4137 enum lsa_SidType *types;
4140 struct full_alias *alias = &server_aliases[i];
4142 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4144 &domains, &names, &types);
4145 if (!NT_STATUS_IS_OK(result))
4148 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4150 if (alias->num_members == 0) {
4155 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4158 &domains, &names, &types);
4160 if (!NT_STATUS_IS_OK(result) &&
4161 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4164 for (j=0; j<alias->num_members; j++)
4165 DEBUG(1, ("%s\\%s (%d); ",
4166 domains[j] ? domains[j] : "*unknown*",
4167 names[j] ? names[j] : "*unknown*",types[j]));
4171 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4173 return NT_STATUS_OK;
4177 * Fetch a list of all server aliases and their members into
4181 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4182 const struct dom_sid *domain_sid,
4183 const char *domain_name,
4184 struct cli_state *cli,
4185 struct rpc_pipe_client *pipe_hnd,
4186 TALLOC_CTX *mem_ctx,
4191 struct policy_handle connect_pol;
4193 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
4195 MAXIMUM_ALLOWED_ACCESS,
4198 if (!NT_STATUS_IS_OK(result))
4201 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4202 &global_sid_Builtin);
4204 if (!NT_STATUS_IS_OK(result))
4207 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4210 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
4215 static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4217 token->num_sids = 4;
4219 if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4220 d_fprintf(stderr, "malloc %s\n",_("failed"));
4221 token->num_sids = 0;
4225 token->sids[0] = *user_sid;
4226 sid_copy(&token->sids[1], &global_sid_World);
4227 sid_copy(&token->sids[2], &global_sid_Network);
4228 sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4231 static void free_user_token(struct security_token *token)
4233 SAFE_FREE(token->sids);
4236 static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4238 if (security_token_has_sid(token, sid))
4241 token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4246 sid_copy(&token->sids[token->num_sids], sid);
4248 token->num_sids += 1;
4253 struct security_token token;
4256 static void dump_user_token(struct user_token *token)
4260 d_printf("%s\n", token->name);
4262 for (i=0; i<token->token.num_sids; i++) {
4263 d_printf(" %s\n", sid_string_tos(&token->token.sids[i]));
4267 static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4271 for (i=0; i<alias->num_members; i++) {
4272 if (dom_sid_compare(sid, &alias->members[i]) == 0)
4279 static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4283 for (i=0; i<num_server_aliases; i++) {
4284 if (is_alias_member(&sid, &server_aliases[i]))
4285 add_sid_to_token(token, &server_aliases[i].sid);
4290 * We got a user token with all the SIDs we can know about without asking the
4291 * server directly. These are the user and domain group sids. All of these can
4292 * be members of aliases. So scan the list of aliases for each of the SIDs and
4293 * add them to the token.
4296 static void collect_alias_memberships(struct security_token *token)
4298 int num_global_sids = token->num_sids;
4301 for (i=0; i<num_global_sids; i++) {
4302 collect_sid_memberships(token, token->sids[i]);
4306 static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4308 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4309 enum wbcSidType type;
4311 struct wbcDomainSid wsid;
4312 char *sid_str = NULL;
4313 struct dom_sid user_sid;
4314 uint32_t num_groups;
4315 gid_t *groups = NULL;
4318 fstr_sprintf(full_name, "%s%c%s",
4319 domain, *lp_winbind_separator(), user);
4321 /* First let's find out the user sid */
4323 wbc_status = wbcLookupName(domain, user, &wsid, &type);
4325 if (!WBC_ERROR_IS_OK(wbc_status)) {
4326 DEBUG(1, ("winbind could not find %s: %s\n",
4327 full_name, wbcErrorString(wbc_status)));
4331 wbc_status = wbcSidToString(&wsid, &sid_str);
4332 if (!WBC_ERROR_IS_OK(wbc_status)) {
4336 if (type != WBC_SID_NAME_USER) {
4337 wbcFreeMemory(sid_str);
4338 DEBUG(1, ("%s is not a user\n", full_name));
4342 if (!string_to_sid(&user_sid, sid_str)) {
4343 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4347 wbcFreeMemory(sid_str);
4350 init_user_token(token, &user_sid);
4352 /* And now the groups winbind knows about */
4354 wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4355 if (!WBC_ERROR_IS_OK(wbc_status)) {
4356 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4357 full_name, wbcErrorString(wbc_status)));
4361 for (i = 0; i < num_groups; i++) {
4362 gid_t gid = groups[i];
4365 wbc_status = wbcGidToSid(gid, &wsid);
4366 if (!WBC_ERROR_IS_OK(wbc_status)) {
4367 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4368 (unsigned int)gid, wbcErrorString(wbc_status)));
4369 wbcFreeMemory(groups);
4373 wbc_status = wbcSidToString(&wsid, &sid_str);
4374 if (!WBC_ERROR_IS_OK(wbc_status)) {
4375 wbcFreeMemory(groups);
4379 DEBUG(3, (" %s\n", sid_str));
4381 string_to_sid(&sid, sid_str);
4382 wbcFreeMemory(sid_str);
4385 add_sid_to_token(token, &sid);
4387 wbcFreeMemory(groups);
4393 * Get a list of all user tokens we want to look at
4396 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4397 struct user_token **user_tokens)
4399 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4400 uint32_t i, num_users;
4402 struct user_token *result;
4403 TALLOC_CTX *frame = NULL;
4405 if (lp_winbind_use_default_domain() &&
4406 (c->opt_target_workgroup == NULL)) {
4407 d_fprintf(stderr, _("winbind use default domain = yes set, "
4408 "please specify a workgroup\n"));
4412 /* Send request to winbind daemon */
4414 wbc_status = wbcListUsers(NULL, &num_users, &users);
4415 if (!WBC_ERROR_IS_OK(wbc_status)) {
4416 DEBUG(1, (_("winbind could not list users: %s\n"),
4417 wbcErrorString(wbc_status)));
4421 result = SMB_MALLOC_ARRAY(struct user_token, num_users);
4423 if (result == NULL) {
4424 DEBUG(1, ("Could not malloc sid array\n"));
4425 wbcFreeMemory(users);
4429 frame = talloc_stackframe();
4430 for (i=0; i < num_users; i++) {
4431 fstring domain, user;
4434 fstrcpy(result[i].name, users[i]);
4436 p = strchr(users[i], *lp_winbind_separator());
4438 DEBUG(3, ("%s\n", users[i]));
4441 fstrcpy(domain, c->opt_target_workgroup);
4442 fstrcpy(user, users[i]);
4445 fstrcpy(domain, users[i]);
4450 get_user_sids(domain, user, &(result[i].token));
4453 wbcFreeMemory(users);
4455 *num_tokens = num_users;
4456 *user_tokens = result;
4461 static bool get_user_tokens_from_file(FILE *f,
4463 struct user_token **tokens)
4465 struct user_token *token = NULL;
4470 if (fgets(line, sizeof(line)-1, f) == NULL) {
4474 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
4475 line[strlen(line)-1] = '\0';
4478 if (line[0] == ' ') {
4482 if(!string_to_sid(&sid, &line[1])) {
4483 DEBUG(1,("get_user_tokens_from_file: Could "
4484 "not convert sid %s \n",&line[1]));
4488 if (token == NULL) {
4489 DEBUG(0, ("File does not begin with username"));
4493 add_sid_to_token(&token->token, &sid);
4497 /* And a new user... */
4500 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4501 if (*tokens == NULL) {
4502 DEBUG(0, ("Could not realloc tokens\n"));
4506 token = &((*tokens)[*num_tokens-1]);
4508 fstrcpy(token->name, line);
4509 token->token.num_sids = 0;
4510 token->token.sids = NULL;
4519 * Show the list of all users that have access to a share
4522 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4523 TALLOC_CTX *mem_ctx,
4524 const char *netname,
4526 struct user_token *tokens)
4529 struct security_descriptor *share_sd = NULL;
4530 struct security_descriptor *root_sd = NULL;
4531 struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
4533 union srvsvc_NetShareInfo info;
4537 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4539 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
4546 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4547 DEBUG(1, ("Coult not query secdesc for share %s\n",
4552 share_sd = info.info502->sd_buf.sd;
4553 if (share_sd == NULL) {
4554 DEBUG(1, ("Got no secdesc for share %s\n",
4560 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
4564 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
4565 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
4566 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4569 for (i=0; i<num_tokens; i++) {
4572 if (share_sd != NULL) {
4573 status = se_access_check(share_sd, &tokens[i].token,
4576 if (!NT_STATUS_IS_OK(status)) {
4577 DEBUG(1, ("Could not check share_sd for "
4584 if (root_sd == NULL) {
4585 d_printf(" %s\n", tokens[i].name);
4589 status = se_access_check(root_sd, &tokens[i].token,
4591 if (!NT_STATUS_IS_OK(status)) {
4592 DEBUG(1, ("Could not check root_sd for user %s\n",
4596 d_printf(" %s\n", tokens[i].name);
4599 if (fnum != (uint16_t)-1)
4600 cli_close(cli, fnum);
4612 static void collect_share(const char *name, uint32 m,
4613 const char *comment, void *state)
4615 struct share_list *share_list = (struct share_list *)state;
4617 if (m != STYPE_DISKTREE)
4620 share_list->num_shares += 1;
4621 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4622 if (!share_list->shares) {
4623 share_list->num_shares = 0;
4626 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4630 * List shares on a remote RPC server, including the security descriptors.
4632 * All parameters are provided by the run_rpc_command function, except for
4633 * argc, argv which are passed through.
4635 * @param domain_sid The domain sid acquired from the remote server.
4636 * @param cli A cli_state connected to the server.
4637 * @param mem_ctx Talloc context, destroyed on completion of the function.
4638 * @param argc Standard main() style argc.
4639 * @param argv Standard main() style argv. Initial components are already
4642 * @return Normal NTSTATUS return.
4645 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
4646 const struct dom_sid *domain_sid,
4647 const char *domain_name,
4648 struct cli_state *cli,
4649 struct rpc_pipe_client *pipe_hnd,
4650 TALLOC_CTX *mem_ctx,
4659 struct user_token *tokens = NULL;
4662 struct share_list share_list;
4667 f = fopen(argv[0], "r");
4671 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4672 return NT_STATUS_UNSUCCESSFUL;
4675 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4681 DEBUG(0, ("Could not read users from file\n"));
4682 return NT_STATUS_UNSUCCESSFUL;
4685 for (i=0; i<num_tokens; i++)
4686 collect_alias_memberships(&tokens[i].token);
4688 share_list.num_shares = 0;
4689 share_list.shares = NULL;
4691 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4694 DEBUG(0, ("Error returning browse list: %s\n",
4699 for (i = 0; i < share_list.num_shares; i++) {
4700 char *netname = share_list.shares[i];
4702 if (netname[strlen(netname)-1] == '$')
4705 d_printf("%s\n", netname);
4707 show_userlist(pipe_hnd, mem_ctx, netname,
4708 num_tokens, tokens);
4711 for (i=0; i<num_tokens; i++) {
4712 free_user_token(&tokens[i].token);
4715 SAFE_FREE(share_list.shares);
4717 return NT_STATUS_OK;
4720 static int rpc_share_allowedusers(struct net_context *c, int argc,
4725 if (c->display_usage) {
4727 "net rpc share allowedusers\n"
4730 _("List allowed users"));
4734 result = run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
4735 rpc_aliaslist_internals,
4740 result = run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0,
4746 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4747 rpc_share_allowedusers_internals,
4751 int net_usersidlist(struct net_context *c, int argc, const char **argv)
4754 struct user_token *tokens = NULL;
4758 net_usersidlist_usage(c, argc, argv);
4762 if (!get_user_tokens(c, &num_tokens, &tokens)) {
4763 DEBUG(0, ("Could not get the user/sid list\n"));
4767 for (i=0; i<num_tokens; i++) {
4768 dump_user_token(&tokens[i]);
4769 free_user_token(&tokens[i].token);
4776 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
4778 d_printf(_("net usersidlist\n"
4779 "\tprints out a list of all users the running winbind knows\n"
4780 "\tabout, together with all their SIDs. This is used as\n"
4781 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
4783 net_common_flags_usage(c, argc, argv);
4788 * 'net rpc share' entrypoint.
4789 * @param argc Standard main() style argc.
4790 * @param argv Standard main() style argv. Initial components are already
4794 int net_rpc_share(struct net_context *c, int argc, const char **argv)
4796 NET_API_STATUS status;
4798 struct functable func[] = {
4804 N_("net rpc share add\n"
4812 N_("net rpc share delete\n"
4817 rpc_share_allowedusers,
4819 N_("Modify allowed users"),
4820 N_("net rpc share allowedusers\n"
4821 " Modify allowed users")
4827 N_("Migrate share to local server"),
4828 N_("net rpc share migrate\n"
4829 " Migrate share to local server")
4836 N_("net rpc share list\n"
4839 {NULL, NULL, 0, NULL, NULL}
4842 status = libnetapi_net_init(&c->netapi_ctx);
4846 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
4847 libnetapi_set_password(c->netapi_ctx, c->opt_password);
4848 if (c->opt_kerberos) {
4849 libnetapi_set_use_kerberos(c->netapi_ctx);
4853 if (c->display_usage) {
4858 " Alias for net rpc share list\n"));
4859 net_display_usage_from_functable(func);
4863 return rpc_share_list(c, argc, argv);
4866 return net_run_function(c, argc, argv, "net rpc share", func);
4869 static NTSTATUS rpc_sh_share_list(struct net_context *c,
4870 TALLOC_CTX *mem_ctx,
4871 struct rpc_sh_ctx *ctx,
4872 struct rpc_pipe_client *pipe_hnd,
4873 int argc, const char **argv)
4876 return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
4879 static NTSTATUS rpc_sh_share_add(struct net_context *c,
4880 TALLOC_CTX *mem_ctx,
4881 struct rpc_sh_ctx *ctx,
4882 struct rpc_pipe_client *pipe_hnd,
4883 int argc, const char **argv)
4885 NET_API_STATUS status;
4886 uint32_t parm_err = 0;
4887 struct SHARE_INFO_2 i2;
4889 if ((argc < 2) || (argc > 3)) {
4890 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
4892 return NT_STATUS_INVALID_PARAMETER;
4895 i2.shi2_netname = argv[0];
4896 i2.shi2_type = STYPE_DISKTREE;
4897 i2.shi2_remark = (argc == 3) ? argv[2] : "";
4898 i2.shi2_permissions = 0;
4899 i2.shi2_max_uses = 0;
4900 i2.shi2_current_uses = 0;
4901 i2.shi2_path = argv[1];
4902 i2.shi2_passwd = NULL;
4904 status = NetShareAdd(pipe_hnd->desthost,
4909 return werror_to_ntstatus(W_ERROR(status));
4912 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
4913 TALLOC_CTX *mem_ctx,
4914 struct rpc_sh_ctx *ctx,
4915 struct rpc_pipe_client *pipe_hnd,
4916 int argc, const char **argv)
4919 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4920 return NT_STATUS_INVALID_PARAMETER;
4923 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
4926 static NTSTATUS rpc_sh_share_info(struct net_context *c,
4927 TALLOC_CTX *mem_ctx,
4928 struct rpc_sh_ctx *ctx,
4929 struct rpc_pipe_client *pipe_hnd,
4930 int argc, const char **argv)
4932 union srvsvc_NetShareInfo info;
4935 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4938 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4939 return NT_STATUS_INVALID_PARAMETER;
4942 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
4948 if (!NT_STATUS_IS_OK(status)) {
4949 result = ntstatus_to_werror(status);
4952 if (!W_ERROR_IS_OK(result)) {
4956 d_printf(_("Name: %s\n"), info.info2->name);
4957 d_printf(_("Comment: %s\n"), info.info2->comment);
4958 d_printf(_("Path: %s\n"), info.info2->path);
4959 d_printf(_("Password: %s\n"), info.info2->password);
4962 return werror_to_ntstatus(result);
4965 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
4966 struct rpc_sh_ctx *ctx)
4968 static struct rpc_sh_cmd cmds[] = {
4970 { "list", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_list,
4971 N_("List available shares") },
4973 { "add", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_add,
4974 N_("Add a share") },
4976 { "delete", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_delete,
4977 N_("Delete a share") },
4979 { "info", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_info,
4980 N_("Get information about a share") },
4982 { NULL, NULL, 0, NULL, NULL }
4988 /****************************************************************************/
4990 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
4992 return net_file_usage(c, argc, argv);
4996 * Close a file on a remote RPC server.
4998 * @param argc Standard main() style argc.
4999 * @param argv Standard main() style argv. Initial components are already
5002 * @return A shell status integer (0 for success).
5004 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5006 if (argc < 1 || c->display_usage) {
5007 return rpc_file_usage(c, argc, argv);
5010 return NetFileClose(c->opt_host, atoi(argv[0]));
5014 * Formatted print of open file info
5016 * @param r struct FILE_INFO_3 contents
5019 static void display_file_info_3(struct FILE_INFO_3 *r)
5021 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5022 r->fi3_id, r->fi3_username, r->fi3_permissions,
5023 r->fi3_num_locks, r->fi3_pathname);
5027 * List files for a user on a remote RPC server.
5029 * @param argc Standard main() style argc.
5030 * @param argv Standard main() style argv. Initial components are already
5033 * @return A shell status integer (0 for success)..
5036 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5038 NET_API_STATUS status;
5039 uint32 preferred_len = 0xffffffff, i;
5040 const char *username=NULL;
5041 uint32_t total_entries = 0;
5042 uint32_t entries_read = 0;
5043 uint32_t resume_handle = 0;
5044 struct FILE_INFO_3 *i3 = NULL;
5046 if (c->display_usage) {
5047 return rpc_file_usage(c, argc, argv);
5050 /* if argc > 0, must be user command */
5052 username = smb_xstrdup(argv[0]);
5055 status = NetFileEnum(c->opt_host,
5059 (uint8_t **)(void *)&i3,
5069 /* Display results */
5072 "\nEnumerating open files on remote server:\n\n"
5073 "\nFileId Opened by Perms Locks Path"
5074 "\n------ --------- ----- ----- ---- \n"));
5075 for (i = 0; i < entries_read; i++) {
5076 display_file_info_3(&i3[i]);
5083 * 'net rpc file' entrypoint.
5084 * @param argc Standard main() style argc.
5085 * @param argv Standard main() style argv. Initial components are already
5089 int net_rpc_file(struct net_context *c, int argc, const char **argv)
5091 NET_API_STATUS status;
5093 struct functable func[] = {
5098 N_("Close opened file"),
5099 N_("net rpc file close\n"
5100 " Close opened file")
5106 N_("List files opened by user"),
5107 N_("net rpc file user\n"
5108 " List files opened by user")
5115 N_("Display information about opened file"),
5116 N_("net rpc file info\n"
5117 " Display information about opened file")
5120 {NULL, NULL, 0, NULL, NULL}
5123 status = libnetapi_net_init(&c->netapi_ctx);
5127 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5128 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5129 if (c->opt_kerberos) {
5130 libnetapi_set_use_kerberos(c->netapi_ctx);
5134 if (c->display_usage) {
5135 d_printf(_("Usage:\n"));
5136 d_printf(_("net rpc file\n"
5137 " List opened files\n"));
5138 net_display_usage_from_functable(func);
5142 return rpc_file_user(c, argc, argv);
5145 return net_run_function(c, argc, argv, "net rpc file", func);
5149 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5151 * All parameters are provided by the run_rpc_command function, except for
5152 * argc, argv which are passed through.
5154 * @param c A net_context structure.
5155 * @param domain_sid The domain sid acquired from the remote server.
5156 * @param cli A cli_state connected to the server.
5157 * @param mem_ctx Talloc context, destroyed on completion of the function.
5158 * @param argc Standard main() style argc.
5159 * @param argv Standard main() style argv. Initial components are already
5162 * @return Normal NTSTATUS return.
5165 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5166 const struct dom_sid *domain_sid,
5167 const char *domain_name,
5168 struct cli_state *cli,
5169 struct rpc_pipe_client *pipe_hnd,
5170 TALLOC_CTX *mem_ctx,
5174 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5176 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5178 status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5179 if (!NT_STATUS_IS_OK(status)) {
5182 if (W_ERROR_IS_OK(result)) {
5183 d_printf(_("\nShutdown successfully aborted\n"));
5184 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5186 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5188 return werror_to_ntstatus(result);
5192 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5194 * All parameters are provided by the run_rpc_command function, except for
5195 * argc, argv which are passed through.
5197 * @param c A net_context structure.
5198 * @param domain_sid The domain sid acquired from the remote server.
5199 * @param cli A cli_state connected to the server.
5200 * @param mem_ctx Talloc context, destroyed on completion of the function.
5201 * @param argc Standard main() style argc.
5202 * @param argv Standard main() style argv. Initial components are already
5205 * @return Normal NTSTATUS return.
5208 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5209 const struct dom_sid *domain_sid,
5210 const char *domain_name,
5211 struct cli_state *cli,
5212 struct rpc_pipe_client *pipe_hnd,
5213 TALLOC_CTX *mem_ctx,
5217 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5219 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5221 result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5223 if (!NT_STATUS_IS_OK(result)) {
5224 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5227 if (W_ERROR_IS_OK(werr)) {
5228 d_printf(_("\nShutdown successfully aborted\n"));
5229 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5231 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5233 return werror_to_ntstatus(werr);
5237 * ABORT the shutdown of a remote RPC server.
5239 * @param argc Standard main() style argc.
5240 * @param argv Standard main() style argv. Initial components are already
5243 * @return A shell status integer (0 for success).
5246 static int rpc_shutdown_abort(struct net_context *c, int argc,
5251 if (c->display_usage) {
5253 "net rpc abortshutdown\n"
5256 _("Abort a scheduled shutdown"));
5260 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5261 rpc_shutdown_abort_internals, argc, argv);
5266 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5268 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5269 rpc_reg_shutdown_abort_internals,
5274 * Shut down a remote RPC Server via initshutdown pipe.
5276 * All parameters are provided by the run_rpc_command function, except for
5277 * argc, argv which are passed through.
5279 * @param c A net_context structure.
5280 * @param domain_sid The domain sid acquired from the remote server.
5281 * @param cli A cli_state connected to the server.
5282 * @param mem_ctx Talloc context, destroyed on completion of the function.
5283 * @param argc Standard main() style argc.
5284 * @param argv Standard main() style argv. Initial components are already
5287 * @return Normal NTSTATUS return.
5290 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5291 const struct dom_sid *domain_sid,
5292 const char *domain_name,
5293 struct cli_state *cli,
5294 struct rpc_pipe_client *pipe_hnd,
5295 TALLOC_CTX *mem_ctx,
5299 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5301 const char *msg = N_("This machine will be shutdown shortly");
5302 uint32 timeout = 20;
5303 struct lsa_StringLarge msg_string;
5304 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5306 if (c->opt_comment) {
5307 msg = c->opt_comment;
5309 if (c->opt_timeout) {
5310 timeout = c->opt_timeout;
5313 msg_string.string = msg;
5315 /* create an entry */
5316 status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5317 &msg_string, timeout, c->opt_force, c->opt_reboot,
5319 if (!NT_STATUS_IS_OK(status)) {
5322 if (W_ERROR_IS_OK(result)) {
5323 d_printf(_("\nShutdown of remote machine succeeded\n"));
5324 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5326 DEBUG(1,("Shutdown of remote machine failed!\n"));
5328 return werror_to_ntstatus(result);
5332 * Shut down a remote RPC Server via winreg pipe.
5334 * All parameters are provided by the run_rpc_command function, except for
5335 * argc, argv which are passed through.
5337 * @param c A net_context structure.
5338 * @param domain_sid The domain sid acquired from the remote server.
5339 * @param cli A cli_state connected to the server.
5340 * @param mem_ctx Talloc context, destroyed on completion of the function.
5341 * @param argc Standard main() style argc.
5342 * @param argv Standard main() style argv. Initial components are already
5345 * @return Normal NTSTATUS return.
5348 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5349 const struct dom_sid *domain_sid,
5350 const char *domain_name,
5351 struct cli_state *cli,
5352 struct rpc_pipe_client *pipe_hnd,
5353 TALLOC_CTX *mem_ctx,
5357 const char *msg = N_("This machine will be shutdown shortly");
5358 uint32 timeout = 20;
5359 struct lsa_StringLarge msg_string;
5362 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5364 if (c->opt_comment) {
5365 msg = c->opt_comment;
5367 msg_string.string = msg;
5369 if (c->opt_timeout) {
5370 timeout = c->opt_timeout;
5373 /* create an entry */
5374 result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
5375 &msg_string, timeout, c->opt_force, c->opt_reboot,
5377 if (!NT_STATUS_IS_OK(result)) {
5378 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5382 if (W_ERROR_IS_OK(werr)) {
5383 d_printf(_("\nShutdown of remote machine succeeded\n"));
5385 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5386 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5387 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5389 d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
5392 return werror_to_ntstatus(werr);
5396 * Shut down a remote RPC server.
5398 * @param argc Standard main() style argc.
5399 * @param argv Standard main() style argv. Initial components are already
5402 * @return A shell status integer (0 for success).
5405 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
5409 if (c->display_usage) {
5411 "net rpc shutdown\n"
5414 _("Shut down a remote RPC server"));
5418 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5419 rpc_init_shutdown_internals, argc, argv);
5422 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5423 rc = run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5424 rpc_reg_shutdown_internals, argc, argv);
5430 /***************************************************************************
5431 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5432 ***************************************************************************/
5435 * Add interdomain trust account to the RPC server.
5436 * All parameters (except for argc and argv) are passed by run_rpc_command
5439 * @param c A net_context structure.
5440 * @param domain_sid The domain sid acquired from the server.
5441 * @param cli A cli_state connected to the server.
5442 * @param mem_ctx Talloc context, destroyed on completion of the function.
5443 * @param argc Standard main() style argc.
5444 * @param argv Standard main() style argv. Initial components are already
5447 * @return normal NTSTATUS return code.
5450 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
5451 const struct dom_sid *domain_sid,
5452 const char *domain_name,
5453 struct cli_state *cli,
5454 struct rpc_pipe_client *pipe_hnd,
5455 TALLOC_CTX *mem_ctx,
5459 struct policy_handle connect_pol, domain_pol, user_pol;
5460 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5462 struct lsa_String lsa_acct_name;
5464 uint32 acct_flags=0;
5466 uint32_t access_granted = 0;
5467 union samr_UserInfo info;
5468 unsigned int orig_timeout;
5473 _(" net rpc trustdom add <domain_name> "
5474 "<trust password>\n"));
5475 return NT_STATUS_INVALID_PARAMETER;
5479 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5482 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5483 return NT_STATUS_NO_MEMORY;
5486 strupper_m(acct_name);
5488 init_lsa_String(&lsa_acct_name, acct_name);
5490 /* Get samr policy handle */
5491 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5493 MAXIMUM_ALLOWED_ACCESS,
5495 if (!NT_STATUS_IS_OK(result)) {
5499 /* Get domain policy handle */
5500 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5502 MAXIMUM_ALLOWED_ACCESS,
5503 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5505 if (!NT_STATUS_IS_OK(result)) {
5509 /* This call can take a long time - allow the server to time out.
5510 * 35 seconds should do it. */
5512 orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
5514 /* Create trusting domain's account */
5515 acb_info = ACB_NORMAL;
5516 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5517 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5518 SAMR_USER_ACCESS_SET_PASSWORD |
5519 SAMR_USER_ACCESS_GET_ATTRIBUTES |
5520 SAMR_USER_ACCESS_SET_ATTRIBUTES;
5522 result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx,
5531 /* And restore our original timeout. */
5532 rpccli_set_timeout(pipe_hnd, orig_timeout);
5534 if (!NT_STATUS_IS_OK(result)) {
5535 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
5536 acct_name, nt_errstr(result));
5541 struct samr_CryptPassword crypt_pwd;
5543 ZERO_STRUCT(info.info23);
5545 init_samr_CryptPassword(argv[1],
5546 &cli->user_session_key,
5549 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
5550 SAMR_FIELD_NT_PASSWORD_PRESENT;
5551 info.info23.info.acct_flags = ACB_DOMTRUST;
5552 info.info23.password = crypt_pwd;
5554 result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
5559 if (!NT_STATUS_IS_OK(result)) {
5560 DEBUG(0,("Could not set trust account password: %s\n",
5561 nt_errstr(result)));
5567 SAFE_FREE(acct_name);
5572 * Create interdomain trust account for a remote domain.
5574 * @param argc Standard argc.
5575 * @param argv Standard argv without initial components.
5577 * @return Integer status (0 means success).
5580 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
5582 if (argc > 0 && !c->display_usage) {
5583 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5584 rpc_trustdom_add_internals, argc, argv);
5588 _("net rpc trustdom add <domain_name> <trust "
5596 * Remove interdomain trust account from the RPC server.
5597 * All parameters (except for argc and argv) are passed by run_rpc_command
5600 * @param c A net_context structure.
5601 * @param domain_sid The domain sid acquired from the server.
5602 * @param cli A cli_state connected to the server.
5603 * @param mem_ctx Talloc context, destroyed on completion of the function.
5604 * @param argc Standard main() style argc.
5605 * @param argv Standard main() style argv. Initial components are already
5608 * @return normal NTSTATUS return code.
5611 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
5612 const struct dom_sid *domain_sid,
5613 const char *domain_name,
5614 struct cli_state *cli,
5615 struct rpc_pipe_client *pipe_hnd,
5616 TALLOC_CTX *mem_ctx,
5620 struct policy_handle connect_pol, domain_pol, user_pol;
5621 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5623 struct dom_sid trust_acct_sid;
5624 struct samr_Ids user_rids, name_types;
5625 struct lsa_String lsa_acct_name;
5630 _(" net rpc trustdom del <domain_name>\n"));
5631 return NT_STATUS_INVALID_PARAMETER;
5635 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5637 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5639 if (acct_name == NULL)
5640 return NT_STATUS_NO_MEMORY;
5642 strupper_m(acct_name);
5644 /* Get samr policy handle */
5645 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5647 MAXIMUM_ALLOWED_ACCESS,
5649 if (!NT_STATUS_IS_OK(result)) {
5653 /* Get domain policy handle */
5654 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5656 MAXIMUM_ALLOWED_ACCESS,
5657 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5659 if (!NT_STATUS_IS_OK(result)) {
5663 init_lsa_String(&lsa_acct_name, acct_name);
5665 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
5672 if (!NT_STATUS_IS_OK(result)) {
5673 d_printf(_("net rpc trustdom del: LookupNames on user %s "
5675 acct_name, nt_errstr(result) );
5679 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
5681 MAXIMUM_ALLOWED_ACCESS,
5685 if (!NT_STATUS_IS_OK(result)) {
5686 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
5688 acct_name, nt_errstr(result) );
5692 /* append the rid to the domain sid */
5693 if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
5697 /* remove the sid */
5699 result = rpccli_samr_RemoveMemberFromForeignDomain(pipe_hnd, mem_ctx,
5702 if (!NT_STATUS_IS_OK(result)) {
5703 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
5704 " on user %s failed %s\n"),
5705 acct_name, nt_errstr(result) );
5711 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
5714 if (!NT_STATUS_IS_OK(result)) {
5715 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
5717 acct_name, nt_errstr(result) );
5721 if (!NT_STATUS_IS_OK(result)) {
5722 d_printf(_("Could not set trust account password: %s\n"),
5732 * Delete interdomain trust account for a remote domain.
5734 * @param argc Standard argc.
5735 * @param argv Standard argv without initial components.
5737 * @return Integer status (0 means success).
5740 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
5742 if (argc > 0 && !c->display_usage) {
5743 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5744 rpc_trustdom_del_internals, argc, argv);
5748 _("net rpc trustdom del <domain>\n"));
5753 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
5754 struct cli_state *cli,
5755 TALLOC_CTX *mem_ctx,
5756 const char *domain_name)
5758 char *dc_name = NULL;
5759 const char *buffer = NULL;
5760 struct rpc_pipe_client *netr;
5763 struct dcerpc_binding_handle *b;
5765 /* Use NetServerEnum2 */
5767 if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
5769 return NT_STATUS_OK;
5772 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
5773 for domain %s\n", domain_name));
5775 /* Try netr_GetDcName */
5777 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
5779 if (!NT_STATUS_IS_OK(status)) {
5783 b = netr->binding_handle;
5785 status = dcerpc_netr_GetDcName(b, mem_ctx,
5792 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
5796 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
5797 for domain %s\n", domain_name));
5799 if (!NT_STATUS_IS_OK(status)) {
5803 return werror_to_ntstatus(result);
5807 * Establish trust relationship to a trusting domain.
5808 * Interdomain account must already be created on remote PDC.
5810 * @param c A net_context structure.
5811 * @param argc Standard argc.
5812 * @param argv Standard argv without initial components.
5814 * @return Integer status (0 means success).
5817 static int rpc_trustdom_establish(struct net_context *c, int argc,
5820 struct cli_state *cli = NULL;
5821 struct sockaddr_storage server_ss;
5822 struct rpc_pipe_client *pipe_hnd = NULL;
5823 struct policy_handle connect_hnd;
5824 TALLOC_CTX *mem_ctx;
5826 struct dom_sid *domain_sid;
5831 union lsa_PolicyInformation *info = NULL;
5834 * Connect to \\server\ipc$ as 'our domain' account with password
5837 if (argc != 1 || c->display_usage) {
5840 _("net rpc trustdom establish <domain_name>\n"));
5844 domain_name = smb_xstrdup(argv[0]);
5845 strupper_m(domain_name);
5847 /* account name used at first is our domain's name with '$' */
5848 if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
5851 strupper_m(acct_name);
5854 * opt_workgroup will be used by connection functions further,
5855 * hence it should be set to remote domain name instead of ours
5857 if (c->opt_workgroup) {
5858 c->opt_workgroup = smb_xstrdup(domain_name);
5861 c->opt_user_name = acct_name;
5863 /* find the domain controller */
5864 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5865 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5869 /* connect to ipc$ as username/password */
5870 nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
5871 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5873 /* Is it trusting domain account for sure ? */
5874 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5875 nt_errstr(nt_status)));
5879 /* store who we connected to */
5881 saf_store( domain_name, pdc_name );
5884 * Connect to \\server\ipc$ again (this time anonymously)
5887 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
5890 if (NT_STATUS_IS_ERR(nt_status)) {
5891 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5892 domain_name, nt_errstr(nt_status)));
5896 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5897 "domain %s", domain_name))) {
5898 DEBUG(0, ("talloc_init() failed\n"));
5903 /* Make sure we're talking to a proper server */
5905 nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
5906 if (!NT_STATUS_IS_OK(nt_status)) {
5908 talloc_destroy(mem_ctx);
5913 * Call LsaOpenPolicy and LsaQueryInfo
5916 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
5918 if (!NT_STATUS_IS_OK(nt_status)) {
5919 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5921 talloc_destroy(mem_ctx);
5925 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
5927 if (NT_STATUS_IS_ERR(nt_status)) {
5928 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5929 nt_errstr(nt_status)));
5931 talloc_destroy(mem_ctx);
5935 /* Querying info level 5 */
5937 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
5939 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
5941 if (NT_STATUS_IS_ERR(nt_status)) {
5942 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5943 nt_errstr(nt_status)));
5945 talloc_destroy(mem_ctx);
5949 domain_sid = info->account_domain.sid;
5951 /* There should be actually query info level 3 (following nt serv behaviour),
5952 but I still don't know if it's _really_ necessary */
5955 * Store the password in secrets db
5958 if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
5959 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5961 talloc_destroy(mem_ctx);
5966 * Close the pipes and clean up
5969 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5970 if (NT_STATUS_IS_ERR(nt_status)) {
5971 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5972 nt_errstr(nt_status)));
5974 talloc_destroy(mem_ctx);
5980 talloc_destroy(mem_ctx);
5982 d_printf(_("Trust to domain %s established\n"), domain_name);
5987 * Revoke trust relationship to the remote domain.
5989 * @param c A net_context structure.
5990 * @param argc Standard argc.
5991 * @param argv Standard argv without initial components.
5993 * @return Integer status (0 means success).
5996 static int rpc_trustdom_revoke(struct net_context *c, int argc,
6002 if (argc < 1 || c->display_usage) {
6005 _("net rpc trustdom revoke <domain_name>\n"
6006 " Revoke trust relationship\n"
6007 " domain_name\tName of domain to revoke trust\n"));
6011 /* generate upper cased domain name */
6012 domain_name = smb_xstrdup(argv[0]);
6013 strupper_m(domain_name);
6015 /* delete password of the trust */
6016 if (!pdb_del_trusteddom_pw(domain_name)) {
6017 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6024 SAFE_FREE(domain_name);
6028 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6029 const struct dom_sid *domain_sid,
6030 const char *domain_name,
6031 struct cli_state *cli,
6032 struct rpc_pipe_client *pipe_hnd,
6033 TALLOC_CTX *mem_ctx,
6038 if (!sid_to_fstring(str_sid, domain_sid)) {
6039 return NT_STATUS_UNSUCCESSFUL;
6041 d_printf("%s\n", str_sid);
6042 return NT_STATUS_OK;
6045 static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6049 /* convert sid into ascii string */
6050 sid_to_fstring(ascii_sid, dom_sid);
6052 d_printf("%-20s%s\n", trusted_dom_name, ascii_sid);
6055 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6056 TALLOC_CTX *mem_ctx,
6057 struct policy_handle *pol,
6058 struct dom_sid dom_sid,
6059 const char *trusted_dom_name)
6062 union lsa_TrustedDomainInfo *info = NULL;
6063 char *cleartextpwd = NULL;
6064 uint8_t session_key[16];
6065 DATA_BLOB session_key_blob;
6066 DATA_BLOB data = data_blob_null;
6068 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
6071 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6073 if (NT_STATUS_IS_ERR(nt_status)) {
6074 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6075 nt_errstr(nt_status)));
6079 data = data_blob(info->password.password->data,
6080 info->password.password->length);
6082 if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) {
6083 DEBUG(0, ("Could not retrieve password hash\n"));
6087 session_key_blob = data_blob_const(session_key, sizeof(session_key));
6088 cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob);
6090 if (cleartextpwd == NULL) {
6091 DEBUG(0,("retrieved NULL password\n"));
6092 nt_status = NT_STATUS_UNSUCCESSFUL;
6096 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6097 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6098 nt_status = NT_STATUS_UNSUCCESSFUL;
6102 #ifdef DEBUG_PASSWORD
6103 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6104 "password: [%s]\n", trusted_dom_name,
6105 sid_string_dbg(&dom_sid), cleartextpwd));
6109 SAFE_FREE(cleartextpwd);
6110 data_blob_free(&data);
6115 static int rpc_trustdom_vampire(struct net_context *c, int argc,
6118 /* common variables */
6119 TALLOC_CTX* mem_ctx;
6120 struct cli_state *cli = NULL;
6121 struct rpc_pipe_client *pipe_hnd = NULL;
6123 const char *domain_name = NULL;
6124 struct dom_sid *queried_dom_sid;
6125 struct policy_handle connect_hnd;
6126 union lsa_PolicyInformation *info = NULL;
6128 /* trusted domains listing variables */
6129 unsigned int enum_ctx = 0;
6131 struct lsa_DomainList dom_list;
6134 if (c->display_usage) {
6136 "net rpc trustdom vampire\n"
6139 _("Vampire trust relationship from remote server"));
6144 * Listing trusted domains (stored in secrets.tdb, if local)
6147 mem_ctx = talloc_init("trust relationships vampire");
6150 * set domain and pdc name to local samba server (default)
6151 * or to remote one given in command line
6154 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6155 domain_name = c->opt_workgroup;
6156 c->opt_target_workgroup = c->opt_workgroup;
6158 fstrcpy(pdc_name, global_myname());
6159 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6160 c->opt_target_workgroup = domain_name;
6163 /* open \PIPE\lsarpc and open policy handle */
6164 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6165 if (!NT_STATUS_IS_OK(nt_status)) {
6166 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6167 nt_errstr(nt_status)));
6168 talloc_destroy(mem_ctx);
6172 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6174 if (!NT_STATUS_IS_OK(nt_status)) {
6175 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6176 nt_errstr(nt_status) ));
6178 talloc_destroy(mem_ctx);
6182 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6184 if (NT_STATUS_IS_ERR(nt_status)) {
6185 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6186 nt_errstr(nt_status)));
6188 talloc_destroy(mem_ctx);
6192 /* query info level 5 to obtain sid of a domain being queried */
6193 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6195 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6198 if (NT_STATUS_IS_ERR(nt_status)) {
6199 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6200 nt_errstr(nt_status)));
6202 talloc_destroy(mem_ctx);
6206 queried_dom_sid = info->account_domain.sid;
6209 * Keep calling LsaEnumTrustdom over opened pipe until
6210 * the end of enumeration is reached
6213 d_printf(_("Vampire trusted domains:\n\n"));
6216 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6221 if (NT_STATUS_IS_ERR(nt_status)) {
6222 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6223 nt_errstr(nt_status)));
6225 talloc_destroy(mem_ctx);
6229 for (i = 0; i < dom_list.count; i++) {
6231 print_trusted_domain(dom_list.domains[i].sid,
6232 dom_list.domains[i].name.string);
6234 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6235 *dom_list.domains[i].sid,
6236 dom_list.domains[i].name.string);
6237 if (!NT_STATUS_IS_OK(nt_status)) {
6239 talloc_destroy(mem_ctx);
6245 * in case of no trusted domains say something rather
6246 * than just display blank line
6248 if (!dom_list.count) d_printf(_("none\n"));
6250 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6252 /* close this connection before doing next one */
6253 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6254 if (NT_STATUS_IS_ERR(nt_status)) {
6255 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6256 nt_errstr(nt_status)));
6258 talloc_destroy(mem_ctx);
6262 /* close lsarpc pipe and connection to IPC$ */
6265 talloc_destroy(mem_ctx);
6269 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
6271 /* common variables */
6272 TALLOC_CTX* mem_ctx;
6273 struct cli_state *cli = NULL, *remote_cli = NULL;
6274 struct rpc_pipe_client *pipe_hnd = NULL;
6276 const char *domain_name = NULL;
6277 struct dom_sid *queried_dom_sid;
6278 int ascii_dom_name_len;
6279 struct policy_handle connect_hnd;
6280 union lsa_PolicyInformation *info = NULL;
6282 /* trusted domains listing variables */
6283 unsigned int num_domains, enum_ctx = 0;
6285 struct lsa_DomainList dom_list;
6289 /* trusting domains listing variables */
6290 struct policy_handle domain_hnd;
6291 struct samr_SamArray *trusts = NULL;
6293 if (c->display_usage) {
6295 "net rpc trustdom list\n"
6298 _("List incoming and outgoing trust relationships"));
6303 * Listing trusted domains (stored in secrets.tdb, if local)
6306 mem_ctx = talloc_init("trust relationships listing");
6309 * set domain and pdc name to local samba server (default)
6310 * or to remote one given in command line
6313 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6314 domain_name = c->opt_workgroup;
6315 c->opt_target_workgroup = c->opt_workgroup;
6317 fstrcpy(pdc_name, global_myname());
6318 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6319 c->opt_target_workgroup = domain_name;
6322 /* open \PIPE\lsarpc and open policy handle */
6323 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6324 if (!NT_STATUS_IS_OK(nt_status)) {
6325 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6326 nt_errstr(nt_status)));
6327 talloc_destroy(mem_ctx);
6331 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6333 if (!NT_STATUS_IS_OK(nt_status)) {
6334 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6335 nt_errstr(nt_status) ));
6337 talloc_destroy(mem_ctx);
6341 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6343 if (NT_STATUS_IS_ERR(nt_status)) {
6344 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6345 nt_errstr(nt_status)));
6347 talloc_destroy(mem_ctx);
6351 /* query info level 5 to obtain sid of a domain being queried */
6352 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6354 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6357 if (NT_STATUS_IS_ERR(nt_status)) {
6358 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6359 nt_errstr(nt_status)));
6361 talloc_destroy(mem_ctx);
6365 queried_dom_sid = info->account_domain.sid;
6368 * Keep calling LsaEnumTrustdom over opened pipe until
6369 * the end of enumeration is reached
6372 d_printf(_("Trusted domains list:\n\n"));
6374 found_domain = false;
6377 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6382 if (NT_STATUS_IS_ERR(nt_status)) {
6383 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6384 nt_errstr(nt_status)));
6386 talloc_destroy(mem_ctx);
6390 for (i = 0; i < dom_list.count; i++) {
6391 print_trusted_domain(dom_list.domains[i].sid,
6392 dom_list.domains[i].name.string);
6393 found_domain = true;
6397 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6400 * in case of no trusted domains say something rather
6401 * than just display blank line
6403 if (!found_domain) {
6404 d_printf(_("none\n"));
6407 /* close this connection before doing next one */
6408 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6409 if (NT_STATUS_IS_ERR(nt_status)) {
6410 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6411 nt_errstr(nt_status)));
6413 talloc_destroy(mem_ctx);
6417 TALLOC_FREE(pipe_hnd);
6420 * Listing trusting domains (stored in passdb backend, if local)
6423 d_printf(_("\nTrusting domains list:\n\n"));
6426 * Open \PIPE\samr and get needed policy handles
6428 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
6430 if (!NT_STATUS_IS_OK(nt_status)) {
6431 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6433 talloc_destroy(mem_ctx);
6438 nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
6440 SAMR_ACCESS_LOOKUP_DOMAIN,
6442 if (!NT_STATUS_IS_OK(nt_status)) {
6443 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6444 nt_errstr(nt_status)));
6446 talloc_destroy(mem_ctx);
6450 /* SamrOpenDomain - we have to open domain policy handle in order to be
6451 able to enumerate accounts*/
6452 nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
6454 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6457 if (!NT_STATUS_IS_OK(nt_status)) {
6458 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6459 nt_errstr(nt_status)));
6461 talloc_destroy(mem_ctx);
6466 * perform actual enumeration
6469 found_domain = false;
6471 enum_ctx = 0; /* reset enumeration context from last enumeration */
6474 nt_status = rpccli_samr_EnumDomainUsers(pipe_hnd, mem_ctx,
6481 if (NT_STATUS_IS_ERR(nt_status)) {
6482 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6483 nt_errstr(nt_status)));
6485 talloc_destroy(mem_ctx);
6489 for (i = 0; i < num_domains; i++) {
6491 char *str = CONST_DISCARD(char *, trusts->entries[i].name.string);
6493 found_domain = true;
6496 * get each single domain's sid (do we _really_ need this ?):
6497 * 1) connect to domain's pdc
6498 * 2) query the pdc for domain's sid
6501 /* get rid of '$' tail */
6502 ascii_dom_name_len = strlen(str);
6503 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6504 str[ascii_dom_name_len - 1] = '\0';
6506 /* set opt_* variables to remote domain */
6508 c->opt_workgroup = talloc_strdup(mem_ctx, str);
6509 c->opt_target_workgroup = c->opt_workgroup;
6511 d_printf("%-20s", str);
6513 /* connect to remote domain controller */
6514 nt_status = net_make_ipc_connection(c,
6515 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6517 if (NT_STATUS_IS_OK(nt_status)) {
6518 /* query for domain's sid */
6519 if (run_rpc_command(
6521 &ndr_table_lsarpc.syntax_id, 0,
6522 rpc_query_domain_sid, argc,
6524 d_printf(_("strange - couldn't get domain's sid\n"));
6526 cli_shutdown(remote_cli);
6529 d_fprintf(stderr, _("domain controller is not "
6530 "responding: %s\n"),
6531 nt_errstr(nt_status));
6532 d_printf(_("couldn't get domain's sid\n"));
6536 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6538 if (!found_domain) {
6542 /* close opened samr and domain policy handles */
6543 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_hnd);
6544 if (!NT_STATUS_IS_OK(nt_status)) {
6545 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6548 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_hnd);
6549 if (!NT_STATUS_IS_OK(nt_status)) {
6550 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6553 /* close samr pipe and connection to IPC$ */
6556 talloc_destroy(mem_ctx);
6561 * Entrypoint for 'net rpc trustdom' code.
6563 * @param argc Standard argc.
6564 * @param argv Standard argv without initial components.
6566 * @return Integer status (0 means success).
6569 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
6571 struct functable func[] = {
6576 N_("Add trusting domain's account"),
6577 N_("net rpc trustdom add\n"
6578 " Add trusting domain's account")
6584 N_("Remove trusting domain's account"),
6585 N_("net rpc trustdom del\n"
6586 " Remove trusting domain's account")
6590 rpc_trustdom_establish,
6592 N_("Establish outgoing trust relationship"),
6593 N_("net rpc trustdom establish\n"
6594 " Establish outgoing trust relationship")
6598 rpc_trustdom_revoke,
6600 N_("Revoke outgoing trust relationship"),
6601 N_("net rpc trustdom revoke\n"
6602 " Revoke outgoing trust relationship")
6608 N_("List in- and outgoing domain trusts"),
6609 N_("net rpc trustdom list\n"
6610 " List in- and outgoing domain trusts")
6614 rpc_trustdom_vampire,
6616 N_("Vampire trusts from remote server"),
6617 N_("net rpc trustdom vampire\n"
6618 " Vampire trusts from remote server")
6620 {NULL, NULL, 0, NULL, NULL}
6623 return net_run_function(c, argc, argv, "net rpc trustdom", func);
6627 * Check if a server will take rpc commands
6628 * @param flags Type of server to connect to (PDC, DMB, localhost)
6629 * if the host is not explicitly specified
6630 * @return bool (true means rpc supported)
6632 bool net_rpc_check(struct net_context *c, unsigned flags)
6634 struct cli_state *cli;
6636 struct sockaddr_storage server_ss;
6637 char *server_name = NULL;
6640 /* flags (i.e. server type) may depend on command */
6641 if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
6644 if ((cli = cli_initialise()) == NULL) {
6648 status = cli_connect(cli, server_name, &server_ss);
6649 if (!NT_STATUS_IS_OK(status))
6651 if (!attempt_netbios_session_request(&cli, global_myname(),
6652 server_name, &server_ss))
6654 status = cli_negprot(cli);
6655 if (!NT_STATUS_IS_OK(status))
6657 if (cli->protocol < PROTOCOL_NT1)
6666 /* dump sam database via samsync rpc calls */
6667 static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
6668 if (c->display_usage) {
6673 _("Dump remote SAM database"));
6677 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6678 NET_FLAGS_ANONYMOUS,
6679 rpc_samdump_internals, argc, argv);
6682 /* syncronise sam database via samsync rpc calls */
6683 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
6685 struct functable func[] = {
6690 N_("Dump remote SAM database to ldif"),
6691 N_("net rpc vampire ldif\n"
6692 " Dump remote SAM database to LDIF file or "
6699 N_("Dump remote SAM database to Kerberos Keytab"),
6700 N_("net rpc vampire keytab\n"
6701 " Dump remote SAM database to Kerberos keytab "
6708 N_("Dump remote SAM database to passdb"),
6709 N_("net rpc vampire passdb\n"
6710 " Dump remote SAM database to passdb")
6713 {NULL, NULL, 0, NULL, NULL}
6717 if (c->display_usage) {
6722 _("Vampire remote SAM database"));
6726 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6727 NET_FLAGS_ANONYMOUS,
6728 rpc_vampire_internals,
6732 return net_run_function(c, argc, argv, "net rpc vampire", func);
6736 * Migrate everything from a print server.
6738 * @param c A net_context structure.
6739 * @param argc Standard main() style argc.
6740 * @param argv Standard main() style argv. Initial components are already
6743 * @return A shell status integer (0 for success).
6745 * The order is important !
6746 * To successfully add drivers the print queues have to exist !
6747 * Applying ACLs should be the last step, because you're easily locked out.
6750 static int rpc_printer_migrate_all(struct net_context *c, int argc,
6755 if (c->display_usage) {
6757 "net rpc printer migrate all\n"
6760 _("Migrate everything from a print server"));
6765 d_printf(_("no server to migrate\n"));
6769 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6770 rpc_printer_migrate_printers_internals, argc,
6775 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6776 rpc_printer_migrate_drivers_internals, argc,
6781 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6782 rpc_printer_migrate_forms_internals, argc, argv);
6786 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6787 rpc_printer_migrate_settings_internals, argc,
6792 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6793 rpc_printer_migrate_security_internals, argc,
6799 * Migrate print drivers from a print server.
6801 * @param c A net_context structure.
6802 * @param argc Standard main() style argc.
6803 * @param argv Standard main() style argv. Initial components are already
6806 * @return A shell status integer (0 for success).
6808 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
6811 if (c->display_usage) {
6813 "net rpc printer migrate drivers\n"
6816 _("Migrate print-drivers from a print-server"));
6821 d_printf(_("no server to migrate\n"));
6825 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6826 rpc_printer_migrate_drivers_internals,
6831 * Migrate print-forms from a print-server.
6833 * @param c A net_context structure.
6834 * @param argc Standard main() style argc.
6835 * @param argv Standard main() style argv. Initial components are already
6838 * @return A shell status integer (0 for success).
6840 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
6843 if (c->display_usage) {
6845 "net rpc printer migrate forms\n"
6848 _("Migrate print-forms from a print-server"));
6853 d_printf(_("no server to migrate\n"));
6857 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6858 rpc_printer_migrate_forms_internals,
6863 * Migrate printers from a print-server.
6865 * @param c A net_context structure.
6866 * @param argc Standard main() style argc.
6867 * @param argv Standard main() style argv. Initial components are already
6870 * @return A shell status integer (0 for success).
6872 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
6875 if (c->display_usage) {
6877 "net rpc printer migrate printers\n"
6880 _("Migrate printers from a print-server"));
6885 d_printf(_("no server to migrate\n"));
6889 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6890 rpc_printer_migrate_printers_internals,
6895 * Migrate printer-ACLs from a print-server
6897 * @param c A net_context structure.
6898 * @param argc Standard main() style argc.
6899 * @param argv Standard main() style argv. Initial components are already
6902 * @return A shell status integer (0 for success).
6904 static int rpc_printer_migrate_security(struct net_context *c, int argc,
6907 if (c->display_usage) {
6909 "net rpc printer migrate security\n"
6912 _("Migrate printer-ACLs from a print-server"));
6917 d_printf(_("no server to migrate\n"));
6921 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6922 rpc_printer_migrate_security_internals,
6927 * Migrate printer-settings from a print-server.
6929 * @param c A net_context structure.
6930 * @param argc Standard main() style argc.
6931 * @param argv Standard main() style argv. Initial components are already
6934 * @return A shell status integer (0 for success).
6936 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
6939 if (c->display_usage) {
6941 "net rpc printer migrate settings\n"
6944 _("Migrate printer-settings from a "
6950 d_printf(_("no server to migrate\n"));
6954 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6955 rpc_printer_migrate_settings_internals,
6960 * 'net rpc printer' entrypoint.
6962 * @param c A net_context structure.
6963 * @param argc Standard main() style argc.
6964 * @param argv Standard main() style argv. Initial components are already
6968 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
6971 /* ouch: when addriver and setdriver are called from within
6972 rpc_printer_migrate_drivers_internals, the printer-queue already
6975 struct functable func[] = {
6978 rpc_printer_migrate_all,
6980 N_("Migrate all from remote to local print server"),
6981 N_("net rpc printer migrate all\n"
6982 " Migrate all from remote to local print server")
6986 rpc_printer_migrate_drivers,
6988 N_("Migrate drivers to local server"),
6989 N_("net rpc printer migrate drivers\n"
6990 " Migrate drivers to local server")
6994 rpc_printer_migrate_forms,
6996 N_("Migrate froms to local server"),
6997 N_("net rpc printer migrate forms\n"
6998 " Migrate froms to local server")
7002 rpc_printer_migrate_printers,
7004 N_("Migrate printers to local server"),
7005 N_("net rpc printer migrate printers\n"
7006 " Migrate printers to local server")
7010 rpc_printer_migrate_security,
7012 N_("Mirgate printer ACLs to local server"),
7013 N_("net rpc printer migrate security\n"
7014 " Mirgate printer ACLs to local server")
7018 rpc_printer_migrate_settings,
7020 N_("Migrate printer settings to local server"),
7021 N_("net rpc printer migrate settings\n"
7022 " Migrate printer settings to local server")
7024 {NULL, NULL, 0, NULL, NULL}
7027 return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7032 * List printers on a remote RPC server.
7034 * @param c A net_context structure.
7035 * @param argc Standard main() style argc.
7036 * @param argv Standard main() style argv. Initial components are already
7039 * @return A shell status integer (0 for success).
7041 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7043 if (c->display_usage) {
7045 "net rpc printer list\n"
7048 _("List printers on a remote RPC server"));
7052 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7053 rpc_printer_list_internals,
7058 * List printer-drivers on a remote RPC server.
7060 * @param c A net_context structure.
7061 * @param argc Standard main() style argc.
7062 * @param argv Standard main() style argv. Initial components are already
7065 * @return A shell status integer (0 for success).
7067 static int rpc_printer_driver_list(struct net_context *c, int argc,
7070 if (c->display_usage) {
7072 "net rpc printer driver\n"
7075 _("List printer-drivers on a remote RPC server"));
7079 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7080 rpc_printer_driver_list_internals,
7085 * Publish printer in ADS via MSRPC.
7087 * @param c A net_context structure.
7088 * @param argc Standard main() style argc.
7089 * @param argv Standard main() style argv. Initial components are already
7092 * @return A shell status integer (0 for success).
7094 static int rpc_printer_publish_publish(struct net_context *c, int argc,
7097 if (c->display_usage) {
7099 "net rpc printer publish publish\n"
7102 _("Publish printer in ADS via MSRPC"));
7106 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7107 rpc_printer_publish_publish_internals,
7112 * Update printer in ADS via MSRPC.
7114 * @param c A net_context structure.
7115 * @param argc Standard main() style argc.
7116 * @param argv Standard main() style argv. Initial components are already
7119 * @return A shell status integer (0 for success).
7121 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7123 if (c->display_usage) {
7125 "net rpc printer publish update\n"
7128 _("Update printer in ADS via MSRPC"));
7132 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7133 rpc_printer_publish_update_internals,
7138 * UnPublish printer in ADS via MSRPC.
7140 * @param c A net_context structure.
7141 * @param argc Standard main() style argc.
7142 * @param argv Standard main() style argv. Initial components are already
7145 * @return A shell status integer (0 for success).
7147 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7150 if (c->display_usage) {
7152 "net rpc printer publish unpublish\n"
7155 _("UnPublish printer in ADS via MSRPC"));
7159 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7160 rpc_printer_publish_unpublish_internals,
7165 * List published printers via MSRPC.
7167 * @param c A net_context structure.
7168 * @param argc Standard main() style argc.
7169 * @param argv Standard main() style argv. Initial components are already
7172 * @return A shell status integer (0 for success).
7174 static int rpc_printer_publish_list(struct net_context *c, int argc,
7177 if (c->display_usage) {
7179 "net rpc printer publish list\n"
7182 _("List published printers via MSRPC"));
7186 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7187 rpc_printer_publish_list_internals,
7193 * Publish printer in ADS.
7195 * @param c A net_context structure.
7196 * @param argc Standard main() style argc.
7197 * @param argv Standard main() style argv. Initial components are already
7200 * @return A shell status integer (0 for success).
7202 static int rpc_printer_publish(struct net_context *c, int argc,
7206 struct functable func[] = {
7209 rpc_printer_publish_publish,
7211 N_("Publish printer in AD"),
7212 N_("net rpc printer publish publish\n"
7213 " Publish printer in AD")
7217 rpc_printer_publish_update,
7219 N_("Update printer in AD"),
7220 N_("net rpc printer publish update\n"
7221 " Update printer in AD")
7225 rpc_printer_publish_unpublish,
7227 N_("Unpublish printer"),
7228 N_("net rpc printer publish unpublish\n"
7229 " Unpublish printer")
7233 rpc_printer_publish_list,
7235 N_("List published printers"),
7236 N_("net rpc printer publish list\n"
7237 " List published printers")
7239 {NULL, NULL, 0, NULL, NULL}
7243 if (c->display_usage) {
7244 d_printf(_("Usage:\n"));
7245 d_printf(_("net rpc printer publish\n"
7246 " List published printers\n"
7247 " Alias of net rpc printer publish "
7249 net_display_usage_from_functable(func);
7252 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7253 rpc_printer_publish_list_internals,
7257 return net_run_function(c, argc, argv, "net rpc printer publish",func);
7263 * Display rpc printer help page.
7265 * @param c A net_context structure.
7266 * @param argc Standard main() style argc.
7267 * @param argv Standard main() style argv. Initial components are already
7270 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
7272 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
7273 "\tlists all printers on print-server\n\n"));
7274 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7275 "\tlists all printer-drivers on print-server\n\n"));
7276 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7277 "\tpublishes printer settings in Active Directory\n"
7278 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
7279 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7280 "\n\tmigrates printers from remote to local server\n\n"));
7281 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7282 "\n\tmigrates printer-settings from remote to local server\n\n"));
7283 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7284 "\n\tmigrates printer-drivers from remote to local server\n\n"));
7285 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7286 "\n\tmigrates printer-forms from remote to local server\n\n"));
7287 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7288 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
7289 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7290 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7291 "\tremote to local print-server\n\n"));
7292 net_common_methods_usage(c, argc, argv);
7293 net_common_flags_usage(c, argc, argv);
7295 "\t-v or --verbose\t\t\tgive verbose output\n"
7296 "\t --destination\t\tmigration target server (default: localhost)\n"));
7302 * 'net rpc printer' entrypoint.
7304 * @param c A net_context structure.
7305 * @param argc Standard main() style argc.
7306 * @param argv Standard main() style argv. Initial components are already
7309 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
7311 struct functable func[] = {
7316 N_("List all printers on print server"),
7317 N_("net rpc printer list\n"
7318 " List all printers on print server")
7322 rpc_printer_migrate,
7324 N_("Migrate printer to local server"),
7325 N_("net rpc printer migrate\n"
7326 " Migrate printer to local server")
7330 rpc_printer_driver_list,
7332 N_("List printer drivers"),
7333 N_("net rpc printer driver\n"
7334 " List printer drivers")
7338 rpc_printer_publish,
7340 N_("Publish printer in AD"),
7341 N_("net rpc printer publish\n"
7342 " Publish printer in AD")
7344 {NULL, NULL, 0, NULL, NULL}
7348 if (c->display_usage) {
7349 d_printf(_("Usage:\n"));
7350 d_printf(_("net rpc printer\n"
7351 " List printers\n"));
7352 net_display_usage_from_functable(func);
7355 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7356 rpc_printer_list_internals,
7360 return net_run_function(c, argc, argv, "net rpc printer", func);
7364 * 'net rpc' entrypoint.
7366 * @param c A net_context structure.
7367 * @param argc Standard main() style argc.
7368 * @param argv Standard main() style argv. Initial components are already
7372 int net_rpc(struct net_context *c, int argc, const char **argv)
7374 NET_API_STATUS status;
7376 struct functable func[] = {
7381 N_("Modify global audit settings"),
7382 N_("net rpc audit\n"
7383 " Modify global audit settings")
7389 N_("Show basic info about a domain"),
7391 " Show basic info about a domain")
7397 N_("Join a domain"),
7405 N_("Join a domain created in server manager"),
7406 N_("net rpc oldjoin\n"
7407 " Join a domain created in server manager")
7413 N_("Test that a join is valid"),
7414 N_("net rpc testjoin\n"
7415 " Test that a join is valid")
7421 N_("List/modify users"),
7423 " List/modify users")
7429 N_("Change a user password"),
7430 N_("net rpc password\n"
7431 " Change a user password\n"
7432 " Alias for net rpc user password")
7438 N_("List/modify groups"),
7439 N_("net rpc group\n"
7440 " List/modify groups")
7446 N_("List/modify shares"),
7447 N_("net rpc share\n"
7448 " List/modify shares")
7454 N_("List open files"),
7462 N_("List/modify printers"),
7463 N_("net rpc printer\n"
7464 " List/modify printers")
7468 net_rpc_changetrustpw,
7470 N_("Change trust account password"),
7471 N_("net rpc changetrustpw\n"
7472 " Change trust account password")
7478 N_("Modify domain trusts"),
7479 N_("net rpc trustdom\n"
7480 " Modify domain trusts")
7486 N_("Abort a remote shutdown"),
7487 N_("net rpc abortshutdown\n"
7488 " Abort a remote shutdown")
7494 N_("Shutdown a remote server"),
7495 N_("net rpc shutdown\n"
7496 " Shutdown a remote server")
7502 N_("Dump SAM data of remote NT PDC"),
7503 N_("net rpc samdump\n"
7504 " Dump SAM data of remote NT PDC")
7510 N_("Sync a remote NT PDC's data into local passdb"),
7511 N_("net rpc vampire\n"
7512 " Sync a remote NT PDC's data into local passdb")
7518 N_("Fetch the domain sid into local secrets.tdb"),
7519 N_("net rpc getsid\n"
7520 " Fetch the domain sid into local secrets.tdb")
7526 N_("Manage privileges assigned to SID"),
7527 N_("net rpc rights\n"
7528 " Manage privileges assigned to SID")
7534 N_("Start/stop/query remote services"),
7535 N_("net rpc service\n"
7536 " Start/stop/query remote services")
7542 N_("Manage registry hives"),
7543 N_("net rpc registry\n"
7544 " Manage registry hives")
7550 N_("Open interactive shell on remote server"),
7551 N_("net rpc shell\n"
7552 " Open interactive shell on remote server")
7554 {NULL, NULL, 0, NULL, NULL}
7557 status = libnetapi_net_init(&c->netapi_ctx);
7561 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
7562 libnetapi_set_password(c->netapi_ctx, c->opt_password);
7563 if (c->opt_kerberos) {
7564 libnetapi_set_use_kerberos(c->netapi_ctx);
7566 if (c->opt_ccache) {
7567 libnetapi_set_use_ccache(c->netapi_ctx);
7570 return net_run_function(c, argc, argv, "net rpc", func);