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 "libsmb/namequery.h"
26 #include "rpc_client/cli_pipe.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/ndr_samr_c.h"
29 #include "rpc_client/cli_samr.h"
30 #include "rpc_client/init_samr.h"
31 #include "../librpc/gen_ndr/ndr_lsa_c.h"
32 #include "rpc_client/cli_lsarpc.h"
33 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
34 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
35 #include "../librpc/gen_ndr/ndr_spoolss.h"
36 #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
37 #include "../librpc/gen_ndr/ndr_winreg_c.h"
39 #include "lib/netapi/netapi.h"
40 #include "lib/netapi/netapi_net.h"
41 #include "librpc/gen_ndr/libnet_join.h"
42 #include "libnet/libnet_join.h"
43 #include "rpc_client/init_lsa.h"
44 #include "../libcli/security/security.h"
45 #include "libsmb/libsmb.h"
46 #include "libsmb/clirap.h"
47 #include "nsswitch/libwbclient/wbclient.h"
49 #include "../libcli/smb/smbXcli_base.h"
50 #include "libsmb/dsgetdcname.h"
52 static int net_mode_share;
53 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask);
58 * @brief RPC based subcommands for the 'net' utility.
60 * This file should contain much of the functionality that used to
61 * be found in rpcclient, except that the commands should change
62 * less often, and the functionality should be sane (the user is not
63 * expected to know a rid/sid before they conduct an operation etc.)
65 * @todo Perhaps eventually these should be split out into a number
66 * of files, as this could get quite big.
71 * Many of the RPC functions need the domain sid. This function gets
72 * it at the start of every run
74 * @param cli A cli_state already connected to the remote machine
76 * @return The Domain SID of the remote machine.
79 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
80 struct dom_sid **domain_sid,
81 const char **domain_name)
83 struct rpc_pipe_client *lsa_pipe = NULL;
84 struct policy_handle pol;
85 NTSTATUS status, result;
86 union lsa_PolicyInformation *info = NULL;
87 struct dcerpc_binding_handle *b;
89 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
91 if (!NT_STATUS_IS_OK(status)) {
92 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
96 b = lsa_pipe->binding_handle;
98 status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
99 SEC_FLAG_MAXIMUM_ALLOWED,
101 if (!NT_STATUS_IS_OK(status)) {
102 d_fprintf(stderr, "open_policy %s: %s\n",
108 status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
110 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
113 if (!NT_STATUS_IS_OK(status)) {
114 d_fprintf(stderr, "lsaquery %s: %s\n",
119 if (!NT_STATUS_IS_OK(result)) {
120 d_fprintf(stderr, "lsaquery %s: %s\n",
126 *domain_name = info->account_domain.name.string;
127 *domain_sid = info->account_domain.sid;
129 dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
130 TALLOC_FREE(lsa_pipe);
136 * Run a single RPC command, from start to finish.
138 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
139 * @param conn_flag a NET_FLAG_ combination. Passed to
140 * net_make_ipc_connection.
141 * @param argc Standard main() style argc.
142 * @param argv Standard main() style argv. Initial components are already
144 * @return A shell status integer (0 for success).
147 int run_rpc_command(struct net_context *c,
148 struct cli_state *cli_arg,
149 const struct ndr_interface_table *table,
155 struct cli_state *cli = NULL;
156 struct rpc_pipe_client *pipe_hnd = NULL;
159 struct dom_sid *domain_sid;
160 const char *domain_name;
163 /* make use of cli_state handed over as an argument, if possible */
165 nt_status = net_make_ipc_connection(c, conn_flags, &cli);
166 if (!NT_STATUS_IS_OK(nt_status)) {
167 DEBUG(1, ("failed to make ipc connection: %s\n",
168 nt_errstr(nt_status)));
181 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
182 DEBUG(0, ("talloc_init() failed\n"));
186 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
188 if (!NT_STATUS_IS_OK(nt_status)) {
192 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
193 if (lp_client_schannel()
194 && (ndr_syntax_id_equal(&table->syntax_id,
195 &ndr_table_netlogon.syntax_id))) {
196 /* Always try and create an schannel netlogon pipe. */
197 TALLOC_FREE(c->netlogon_creds);
198 nt_status = cli_rpc_pipe_open_schannel(
199 cli, c->msg_ctx, table, NCACN_NP,
201 &pipe_hnd, c, &c->netlogon_creds);
202 if (!NT_STATUS_IS_OK(nt_status)) {
203 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
204 nt_errstr(nt_status) ));
208 if (conn_flags & NET_FLAGS_SEAL) {
209 nt_status = cli_rpc_pipe_open_generic_auth(
211 (conn_flags & NET_FLAGS_TCP) ?
212 NCACN_IP_TCP : NCACN_NP,
213 CRED_DONT_USE_KERBEROS,
214 DCERPC_AUTH_TYPE_NTLMSSP,
215 DCERPC_AUTH_LEVEL_PRIVACY,
216 smbXcli_conn_remote_name(cli->conn),
217 lp_workgroup(), c->opt_user_name,
218 c->opt_password, &pipe_hnd);
220 nt_status = cli_rpc_pipe_open_noauth(
224 if (!NT_STATUS_IS_OK(nt_status)) {
225 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
227 nt_errstr(nt_status) ));
233 nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
235 if (!NT_STATUS_IS_OK(nt_status)) {
236 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
239 DEBUG(5, ("rpc command function succedded\n"));
242 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
244 TALLOC_FREE(pipe_hnd);
249 /* close the connection only if it was opened here */
254 talloc_destroy(mem_ctx);
259 * Force a change of the trust account password.
261 * All parameters are provided by the run_rpc_command function, except for
262 * argc, argv which are passed through.
264 * @param domain_sid The domain sid acquired from the remote server.
265 * @param cli A cli_state connected to the server.
266 * @param mem_ctx Talloc context, destroyed on completion of the function.
267 * @param argc Standard main() style argc.
268 * @param argv Standard main() style argv. Initial components are already
271 * @return Normal NTSTATUS return.
274 static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
275 const struct dom_sid *domain_sid,
276 const char *domain_name,
277 struct cli_state *cli,
278 struct rpc_pipe_client *pipe_hnd,
284 const char *dcname = NULL;
287 return NT_STATUS_INTERNAL_ERROR;
290 dcname = smbXcli_conn_remote_name(cli->conn);
292 status = trust_pw_change(c->netlogon_creds,
294 pipe_hnd->binding_handle,
295 c->opt_target_workgroup,
298 if (!NT_STATUS_IS_OK(status)) {
299 d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
308 * Force a change of the trust account password.
310 * @param argc Standard main() style argc.
311 * @param argv Standard main() style argv. Initial components are already
314 * @return A shell status integer (0 for success).
317 int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
319 int conn_flags = NET_FLAGS_PDC;
321 if (!c->opt_user_specified && !c->opt_kerberos) {
322 conn_flags |= NET_FLAGS_ANONYMOUS;
325 if (c->display_usage) {
327 "net rpc changetrustpw\n"
330 _("Change the machine trust password"));
334 return run_rpc_command(c, NULL, &ndr_table_netlogon,
336 rpc_changetrustpw_internals,
341 * Join a domain, the old way. This function exists to allow
342 * the message to be displayed when oldjoin was explicitly
343 * requested, but not when it was implied by "net rpc join".
345 * This uses 'machinename' as the initial password, and changes it.
347 * The password should be created with 'server manager' or equiv first.
349 * @param argc Standard main() style argc.
350 * @param argv Standard main() style argv. Initial components are already
353 * @return A shell status integer (0 for success).
356 static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
358 struct libnet_JoinCtx *r = NULL;
361 const char *domain = lp_workgroup(); /* FIXME */
362 bool modify_config = lp_config_backend_is_registry();
363 enum netr_SchannelType sec_chan_type;
366 if (c->display_usage) {
369 " Join a domain the old way\n");
373 mem_ctx = talloc_init("net_rpc_oldjoin");
378 werr = libnet_init_JoinCtx(mem_ctx, &r);
379 if (!W_ERROR_IS_OK(werr)) {
384 check what type of join - if the user wants to join as
385 a BDC, the server must agree that we are a BDC.
388 sec_chan_type = get_sec_channel_type(argv[0]);
390 sec_chan_type = get_sec_channel_type(NULL);
394 d_fprintf(stderr, _("Could not initialise message context. "
395 "Try running as root\n"));
396 werr = WERR_ACCESS_DENIED;
400 pw = talloc_strndup(r, lp_netbios_name(), 14);
402 werr = WERR_NOT_ENOUGH_MEMORY;
406 r->in.msg_ctx = c->msg_ctx;
407 r->in.domain_name = domain;
408 r->in.secure_channel_type = sec_chan_type;
409 r->in.dc_name = c->opt_host;
410 r->in.admin_account = "";
411 r->in.admin_password = strlower_talloc(r, pw);
412 if (r->in.admin_password == NULL) {
413 werr = WERR_NOT_ENOUGH_MEMORY;
417 r->in.modify_config = modify_config;
418 r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
419 WKSSVC_JOIN_FLAGS_JOIN_UNSECURE |
420 WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
422 werr = libnet_Join(mem_ctx, r);
423 if (!W_ERROR_IS_OK(werr)) {
427 /* Check the short name of the domain */
429 if (!modify_config && !strequal(lp_workgroup(), r->out.netbios_domain_name)) {
430 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
431 d_printf("domain name obtained from the server.\n");
432 d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name);
433 d_printf("You should set \"workgroup = %s\" in %s.\n",
434 r->out.netbios_domain_name, get_dyn_CONFIGFILE());
437 d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
439 if (r->out.dns_domain_name) {
440 d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name,
441 r->out.dns_domain_name);
443 d_printf("Joined '%s' to domain '%s'\n", r->in.machine_name,
444 r->out.netbios_domain_name);
447 /* print out informative error string in case there is one */
448 if (r->out.error_string != NULL) {
449 d_printf("%s\n", r->out.error_string);
452 TALLOC_FREE(mem_ctx);
457 if (c->opt_flags & NET_FLAGS_EXPECT_FALLBACK) {
461 /* issue an overall failure message at the end. */
462 d_fprintf(stderr, _("Failed to join domain: %s\n"),
463 r && r->out.error_string ? r->out.error_string :
464 get_friendly_werror_msg(werr));
467 TALLOC_FREE(mem_ctx);
473 * check that a join is OK
475 * @return A shell status integer (0 for success)
478 int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
482 const char *domain = c->opt_target_workgroup;
483 const char *dc = c->opt_host;
485 if (c->display_usage) {
488 " Test if a join is OK\n");
492 mem_ctx = talloc_init("net_rpc_testjoin");
498 struct netr_DsRGetDCNameInfo *info;
501 d_fprintf(stderr, _("Could not initialise message context. "
502 "Try running as root\n"));
503 talloc_destroy(mem_ctx);
507 status = dsgetdcname(mem_ctx,
514 if (!NT_STATUS_IS_OK(status)) {
515 talloc_destroy(mem_ctx);
519 dc = strip_hostname(info->dc_unc);
522 /* Display success or failure */
523 status = libnet_join_ok(c->msg_ctx,
527 if (!NT_STATUS_IS_OK(status)) {
528 fprintf(stderr,"Join to domain '%s' is not valid: %s\n",
529 domain, nt_errstr(status));
530 talloc_destroy(mem_ctx);
534 printf("Join to '%s' is OK\n",domain);
535 talloc_destroy(mem_ctx);
541 * Join a domain using the administrator username and password
543 * @param argc Standard main() style argc
544 * @param argc Standard main() style argv. Initial components are already
545 * stripped. Currently not used.
546 * @return A shell status integer (0 for success)
550 static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
552 struct libnet_JoinCtx *r = NULL;
555 const char *domain = lp_workgroup(); /* FIXME */
556 bool modify_config = lp_config_backend_is_registry();
557 enum netr_SchannelType sec_chan_type;
559 if (c->display_usage) {
562 " Join a domain the new way\n");
566 mem_ctx = talloc_init("net_rpc_join_newstyle");
571 werr = libnet_init_JoinCtx(mem_ctx, &r);
572 if (!W_ERROR_IS_OK(werr)) {
577 check what type of join - if the user wants to join as
578 a BDC, the server must agree that we are a BDC.
581 sec_chan_type = get_sec_channel_type(argv[0]);
583 sec_chan_type = get_sec_channel_type(NULL);
587 d_fprintf(stderr, _("Could not initialise message context. "
588 "Try running as root\n"));
589 werr = WERR_ACCESS_DENIED;
593 r->in.msg_ctx = c->msg_ctx;
594 r->in.domain_name = domain;
595 r->in.secure_channel_type = sec_chan_type;
596 r->in.dc_name = c->opt_host;
597 r->in.admin_account = c->opt_user_name;
598 r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
600 r->in.use_kerberos = c->opt_kerberos;
601 r->in.modify_config = modify_config;
602 r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
603 WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
604 WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
606 werr = libnet_Join(mem_ctx, r);
607 if (!W_ERROR_IS_OK(werr)) {
611 /* Check the short name of the domain */
613 if (!modify_config && !strequal(lp_workgroup(), r->out.netbios_domain_name)) {
614 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
615 d_printf("domain name obtained from the server.\n");
616 d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name);
617 d_printf("You should set \"workgroup = %s\" in %s.\n",
618 r->out.netbios_domain_name, get_dyn_CONFIGFILE());
621 d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
623 if (r->out.dns_domain_name) {
624 d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name,
625 r->out.dns_domain_name);
627 d_printf("Joined '%s' to domain '%s'\n", r->in.machine_name,
628 r->out.netbios_domain_name);
631 /* print out informative error string in case there is one */
632 if (r->out.error_string != NULL) {
633 d_printf("%s\n", r->out.error_string);
636 TALLOC_FREE(mem_ctx);
641 /* issue an overall failure message at the end. */
642 d_printf("Failed to join domain: %s\n",
643 r && r->out.error_string ? r->out.error_string :
644 get_friendly_werror_msg(werr));
646 TALLOC_FREE(mem_ctx);
652 * 'net rpc join' entrypoint.
653 * @param argc Standard main() style argc.
654 * @param argv Standard main() style argv. Initial components are already
657 * Main 'net_rpc_join()' (where the admin username/password is used) is
659 * Try to just change the password, but if that doesn't work, use/prompt
660 * for a username/password.
663 int net_rpc_join(struct net_context *c, int argc, const char **argv)
667 if (c->display_usage) {
670 _("net rpc join -U <username>[%%password] <type>\n"
672 " username\tName of the admin user"
673 " password\tPassword of the admin user, will "
674 "prompt if not specified\n"
675 " type\tCan be one of the following:\n"
676 "\t\tMEMBER\tJoin as member server (default)\n"
677 "\t\tBDC\tJoin as BDC\n"
678 "\t\tPDC\tJoin as PDC\n"));
682 if (lp_server_role() == ROLE_STANDALONE) {
683 d_printf(_("cannot join as standalone machine\n"));
687 if (strlen(lp_netbios_name()) > 15) {
688 d_printf(_("Our netbios name can be at most 15 chars long, "
689 "\"%s\" is %u chars long\n"),
690 lp_netbios_name(), (unsigned int)strlen(lp_netbios_name()));
694 c->opt_flags |= NET_FLAGS_EXPECT_FALLBACK;
695 ret = net_rpc_oldjoin(c, argc, argv);
696 c->opt_flags &= ~NET_FLAGS_EXPECT_FALLBACK;
701 return net_rpc_join_newstyle(c, argc, argv);
705 * display info about a rpc domain
707 * All parameters are provided by the run_rpc_command function, except for
708 * argc, argv which are passed through.
710 * @param domain_sid The domain sid acquired from the remote server
711 * @param cli A cli_state connected to the server.
712 * @param mem_ctx Talloc context, destroyed on completion of the function.
713 * @param argc Standard main() style argc.
714 * @param argv Standard main() style argv. Initial components are already
717 * @return Normal NTSTATUS return.
720 NTSTATUS rpc_info_internals(struct net_context *c,
721 const struct dom_sid *domain_sid,
722 const char *domain_name,
723 struct cli_state *cli,
724 struct rpc_pipe_client *pipe_hnd,
729 struct policy_handle connect_pol, domain_pol;
730 NTSTATUS status, result;
731 union samr_DomainInfo *info = NULL;
732 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
734 /* Get sam policy handle */
735 status = dcerpc_samr_Connect2(b, mem_ctx,
737 MAXIMUM_ALLOWED_ACCESS,
740 if (!NT_STATUS_IS_OK(status)) {
741 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
746 if (!NT_STATUS_IS_OK(result)) {
748 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
753 /* Get domain policy handle */
754 status = dcerpc_samr_OpenDomain(b, mem_ctx,
756 MAXIMUM_ALLOWED_ACCESS,
757 discard_const_p(struct dom_sid2, domain_sid),
760 if (!NT_STATUS_IS_OK(status)) {
761 d_fprintf(stderr, _("Could not open domain: %s\n"),
765 if (!NT_STATUS_IS_OK(result)) {
767 d_fprintf(stderr, _("Could not open domain: %s\n"),
772 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
777 if (!NT_STATUS_IS_OK(status)) {
781 if (NT_STATUS_IS_OK(result)) {
782 struct dom_sid_buf sid_str;
784 d_printf(_("Domain Name: %s\n"),
785 info->general.domain_name.string);
786 d_printf(_("Domain SID: %s\n"),
787 dom_sid_str_buf(domain_sid, &sid_str));
788 d_printf(_("Sequence number: %llu\n"),
789 (unsigned long long)info->general.sequence_num);
790 d_printf(_("Num users: %u\n"), info->general.num_users);
791 d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
792 d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
800 * 'net rpc info' entrypoint.
801 * @param argc Standard main() style argc.
802 * @param argv Standard main() style argv. Initial components are already
806 int net_rpc_info(struct net_context *c, int argc, const char **argv)
808 if (c->display_usage) {
813 _("Display information about the domain"));
817 return run_rpc_command(c, NULL, &ndr_table_samr,
818 NET_FLAGS_PDC, rpc_info_internals,
823 * Fetch domain SID into the local secrets.tdb.
825 * All parameters are provided by the run_rpc_command function, except for
826 * argc, argv which are passed through.
828 * @param domain_sid The domain sid acquired from the remote server.
829 * @param cli A cli_state connected to the server.
830 * @param mem_ctx Talloc context, destroyed on completion of the function.
831 * @param argc Standard main() style argc.
832 * @param argv Standard main() style argv. Initial components are already
835 * @return Normal NTSTATUS return.
838 static NTSTATUS rpc_getsid_internals(struct net_context *c,
839 const struct dom_sid *domain_sid,
840 const char *domain_name,
841 struct cli_state *cli,
842 struct rpc_pipe_client *pipe_hnd,
847 struct dom_sid_buf sid_str;
849 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
850 dom_sid_str_buf(domain_sid, &sid_str),
853 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
854 DEBUG(0,("Can't store domain SID\n"));
855 return NT_STATUS_UNSUCCESSFUL;
862 * 'net rpc getsid' entrypoint.
863 * @param argc Standard main() style argc.
864 * @param argv Standard main() style argv. Initial components are already
868 int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
870 int conn_flags = NET_FLAGS_PDC;
872 if (!c->opt_user_specified && !c->opt_kerberos) {
873 conn_flags |= NET_FLAGS_ANONYMOUS;
876 if (c->display_usage) {
881 _("Fetch domain SID into local secrets.tdb"));
885 return run_rpc_command(c, NULL, &ndr_table_samr,
887 rpc_getsid_internals,
891 /****************************************************************************/
894 * Basic usage function for 'net rpc user'.
895 * @param argc Standard main() style argc.
896 * @param argv Standard main() style argv. Initial components are already
900 static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
902 return net_user_usage(c, argc, argv);
906 * Add a new user to a remote RPC server.
908 * @param argc Standard main() style argc.
909 * @param argv Standard main() style argv. Initial components are already
912 * @return A shell status integer (0 for success).
915 static int rpc_user_add(struct net_context *c, int argc, const char **argv)
917 NET_API_STATUS status;
918 struct USER_INFO_1 info1;
919 uint32_t parm_error = 0;
921 if (argc < 1 || c->display_usage) {
922 rpc_user_usage(c, argc, argv);
928 info1.usri1_name = argv[0];
930 info1.usri1_password = argv[1];
933 status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
936 d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
937 argv[0], libnetapi_get_error_string(c->netapi_ctx,
941 d_printf(_("Added user '%s'.\n"), argv[0]);
948 * Rename a user on a remote RPC server.
950 * @param argc Standard main() style argc.
951 * @param argv Standard main() style argv. Initial components are already
954 * @return A shell status integer (0 for success).
957 static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
959 NET_API_STATUS status;
960 struct USER_INFO_0 u0;
961 uint32_t parm_err = 0;
963 if (argc != 2 || c->display_usage) {
964 rpc_user_usage(c, argc, argv);
968 u0.usri0_name = argv[1];
970 status = NetUserSetInfo(c->opt_host, argv[0],
971 0, (uint8_t *)&u0, &parm_err);
974 _("Failed to rename user from %s to %s - %s\n"),
976 libnetapi_get_error_string(c->netapi_ctx, status));
978 d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
985 * Set a user's primary group
987 * @param argc Standard main() style argc.
988 * @param argv Standard main() style argv. Initial components are already
991 * @return A shell status integer (0 for success).
994 static int rpc_user_setprimarygroup(struct net_context *c, int argc,
997 NET_API_STATUS status;
999 struct GROUP_INFO_2 *g2;
1000 struct USER_INFO_1051 u1051;
1001 uint32_t parm_err = 0;
1003 if (argc != 2 || c->display_usage) {
1004 rpc_user_usage(c, argc, argv);
1008 status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
1010 d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
1012 libnetapi_get_error_string(c->netapi_ctx, status));
1015 g2 = (struct GROUP_INFO_2 *)buffer;
1017 u1051.usri1051_primary_group_id = g2->grpi2_group_id;
1019 NetApiBufferFree(buffer);
1021 status = NetUserSetInfo(c->opt_host, argv[0], 1051,
1022 (uint8_t *)&u1051, &parm_err);
1025 _("Failed to set user's primary group %s to %s - "
1026 "%s\n"), argv[0], argv[1],
1027 libnetapi_get_error_string(c->netapi_ctx, status));
1029 d_printf(_("Set primary group of user %s to %s\n"), argv[0],
1036 * Delete a user from a remote RPC server.
1038 * @param argc Standard main() style argc.
1039 * @param argv Standard main() style argv. Initial components are already
1042 * @return A shell status integer (0 for success).
1045 static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
1047 NET_API_STATUS status;
1049 if (argc < 1 || c->display_usage) {
1050 rpc_user_usage(c, argc, argv);
1054 status = NetUserDel(c->opt_host, argv[0]);
1057 d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
1059 libnetapi_get_error_string(c->netapi_ctx, status));
1062 d_printf(_("Deleted user '%s'.\n"), argv[0]);
1069 * Set a user's password on a remote RPC server.
1071 * @param argc Standard main() style argc.
1072 * @param argv Standard main() style argv. Initial components are already
1075 * @return A shell status integer (0 for success).
1078 static int rpc_user_password(struct net_context *c, int argc, const char **argv)
1080 NET_API_STATUS status;
1081 char *prompt = NULL;
1082 struct USER_INFO_1003 u1003;
1083 uint32_t parm_err = 0;
1086 if (argc < 1 || c->display_usage) {
1087 rpc_user_usage(c, argc, argv);
1092 u1003.usri1003_password = argv[1];
1094 char pwd[256] = {0};
1095 ret = asprintf(&prompt, _("Enter new password for %s:"),
1101 ret = samba_getpass(prompt, pwd, sizeof(pwd), false, false);
1107 u1003.usri1003_password = talloc_strdup(c, pwd);
1108 if (u1003.usri1003_password == NULL) {
1113 status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
1115 /* Display results */
1118 _("Failed to set password for '%s' with error: %s.\n"),
1119 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1128 * List a user's groups from a remote RPC server.
1130 * @param argc Standard main() style argc.
1131 * @param argv Standard main() style argv. Initial components are already
1134 * @return A shell status integer (0 for success)
1137 static int rpc_user_info(struct net_context *c, int argc, const char **argv)
1140 NET_API_STATUS status;
1141 struct GROUP_USERS_INFO_0 *u0 = NULL;
1142 uint32_t entries_read = 0;
1143 uint32_t total_entries = 0;
1147 if (argc < 1 || c->display_usage) {
1148 rpc_user_usage(c, argc, argv);
1152 status = NetUserGetGroups(c->opt_host,
1155 (uint8_t **)(void *)&u0,
1161 _("Failed to get groups for '%s' with error: %s.\n"),
1162 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1167 for (i=0; i < entries_read; i++) {
1168 printf("%s\n", u0->grui0_name);
1176 * List users on a remote RPC server.
1178 * All parameters are provided by the run_rpc_command function, except for
1179 * argc, argv which are passed through.
1181 * @param domain_sid The domain sid acquired from the remote server.
1182 * @param cli A cli_state connected to the server.
1183 * @param mem_ctx Talloc context, destroyed on completion of the function.
1184 * @param argc Standard main() style argc.
1185 * @param argv Standard main() style argv. Initial components are already
1188 * @return Normal NTSTATUS return.
1191 static int rpc_user_list(struct net_context *c, int argc, const char **argv)
1193 NET_API_STATUS status;
1194 uint32_t start_idx=0, num_entries, i, loop_count = 0;
1195 struct NET_DISPLAY_USER *info = NULL;
1196 void *buffer = NULL;
1198 /* Query domain users */
1199 if (c->opt_long_list_entries)
1200 d_printf(_("\nUser name Comment"
1201 "\n-----------------------------\n"));
1203 uint32_t max_entries, max_size;
1205 dcerpc_get_query_dispinfo_params(
1206 loop_count, &max_entries, &max_size);
1208 status = NetQueryDisplayInformation(c->opt_host,
1215 if (status != 0 && status != ERROR_MORE_DATA) {
1219 info = (struct NET_DISPLAY_USER *)buffer;
1221 for (i = 0; i < num_entries; i++) {
1223 if (c->opt_long_list_entries)
1224 printf("%-21.21s %s\n", info->usri1_name,
1225 info->usri1_comment);
1227 printf("%s\n", info->usri1_name);
1231 NetApiBufferFree(buffer);
1234 start_idx += num_entries;
1236 } while (status == ERROR_MORE_DATA);
1242 * 'net rpc user' entrypoint.
1243 * @param argc Standard main() style argc.
1244 * @param argv Standard main() style argv. Initial components are already
1248 int net_rpc_user(struct net_context *c, int argc, const char **argv)
1250 NET_API_STATUS status;
1252 struct functable func[] = {
1257 N_("Add specified user"),
1258 N_("net rpc user add\n"
1259 " Add specified user")
1265 N_("List domain groups of user"),
1266 N_("net rpc user info\n"
1267 " List domain groups of user")
1273 N_("Remove specified user"),
1274 N_("net rpc user delete\n"
1275 " Remove specified user")
1281 N_("Change user password"),
1282 N_("net rpc user password\n"
1283 " Change user password")
1289 N_("Rename specified user"),
1290 N_("net rpc user rename\n"
1291 " Rename specified user")
1295 rpc_user_setprimarygroup,
1297 "Set a user's primary group",
1298 "net rpc user setprimarygroup\n"
1299 " Set a user's primary group"
1301 {NULL, NULL, 0, NULL, NULL}
1304 status = libnetapi_net_init(&c->netapi_ctx);
1308 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
1309 libnetapi_set_password(c->netapi_ctx, c->opt_password);
1310 if (c->opt_kerberos) {
1311 libnetapi_set_use_kerberos(c->netapi_ctx);
1315 if (c->display_usage) {
1320 _("List all users"));
1321 net_display_usage_from_functable(func);
1325 return rpc_user_list(c, argc, argv);
1328 return net_run_function(c, argc, argv, "net rpc user", func);
1331 static NTSTATUS rpc_sh_user_list(struct net_context *c,
1332 TALLOC_CTX *mem_ctx,
1333 struct rpc_sh_ctx *ctx,
1334 struct rpc_pipe_client *pipe_hnd,
1335 int argc, const char **argv)
1337 return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1340 static NTSTATUS rpc_sh_user_info(struct net_context *c,
1341 TALLOC_CTX *mem_ctx,
1342 struct rpc_sh_ctx *ctx,
1343 struct rpc_pipe_client *pipe_hnd,
1344 int argc, const char **argv)
1346 return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1349 static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1350 TALLOC_CTX *mem_ctx,
1351 struct rpc_sh_ctx *ctx,
1352 struct rpc_pipe_client *pipe_hnd,
1353 int argc, const char **argv,
1355 struct net_context *c,
1356 TALLOC_CTX *mem_ctx,
1357 struct rpc_sh_ctx *ctx,
1358 struct rpc_pipe_client *pipe_hnd,
1359 struct policy_handle *user_hnd,
1360 int argc, const char **argv))
1362 struct policy_handle connect_pol, domain_pol, user_pol;
1363 NTSTATUS status, result;
1366 enum lsa_SidType type;
1367 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1370 d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1372 return NT_STATUS_INVALID_PARAMETER;
1375 ZERO_STRUCT(connect_pol);
1376 ZERO_STRUCT(domain_pol);
1377 ZERO_STRUCT(user_pol);
1379 status = net_rpc_lookup_name(c, mem_ctx, ctx->cli,
1380 argv[0], NULL, NULL, &sid, &type);
1381 if (!NT_STATUS_IS_OK(status)) {
1382 d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1387 if (type != SID_NAME_USER) {
1388 d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1389 sid_type_lookup(type));
1390 status = NT_STATUS_NO_SUCH_USER;
1394 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1395 d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1396 status = NT_STATUS_NO_SUCH_USER;
1400 status = dcerpc_samr_Connect2(b, mem_ctx,
1402 MAXIMUM_ALLOWED_ACCESS,
1405 if (!NT_STATUS_IS_OK(status)) {
1408 if (!NT_STATUS_IS_OK(result)) {
1413 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1415 MAXIMUM_ALLOWED_ACCESS,
1419 if (!NT_STATUS_IS_OK(status)) {
1422 if (!NT_STATUS_IS_OK(result)) {
1427 status = dcerpc_samr_OpenUser(b, mem_ctx,
1429 MAXIMUM_ALLOWED_ACCESS,
1433 if (!NT_STATUS_IS_OK(status)) {
1436 if (!NT_STATUS_IS_OK(result)) {
1441 status = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1444 if (is_valid_policy_hnd(&user_pol)) {
1445 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1447 if (is_valid_policy_hnd(&domain_pol)) {
1448 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1450 if (is_valid_policy_hnd(&connect_pol)) {
1451 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1456 static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1457 TALLOC_CTX *mem_ctx,
1458 struct rpc_sh_ctx *ctx,
1459 struct rpc_pipe_client *pipe_hnd,
1460 struct policy_handle *user_hnd,
1461 int argc, const char **argv)
1463 NTSTATUS status, result;
1464 union samr_UserInfo *info = NULL;
1465 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1468 d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1470 return NT_STATUS_INVALID_PARAMETER;
1473 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1478 if (!NT_STATUS_IS_OK(status)) {
1481 if (!NT_STATUS_IS_OK(result)) {
1485 d_printf(_("user rid: %d, group rid: %d\n"),
1487 info->info21.primary_gid);
1492 static NTSTATUS rpc_sh_user_show(struct net_context *c,
1493 TALLOC_CTX *mem_ctx,
1494 struct rpc_sh_ctx *ctx,
1495 struct rpc_pipe_client *pipe_hnd,
1496 int argc, const char **argv)
1498 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1499 rpc_sh_user_show_internals);
1502 #define FETCHSTR(name, rec) \
1503 do { if (strequal(ctx->thiscmd, name)) { \
1504 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1507 #define SETSTR(name, rec, flag) \
1508 do { if (strequal(ctx->thiscmd, name)) { \
1509 init_lsa_String(&(info->info21.rec), argv[0]); \
1510 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1513 static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1514 TALLOC_CTX *mem_ctx,
1515 struct rpc_sh_ctx *ctx,
1516 struct rpc_pipe_client *pipe_hnd,
1517 struct policy_handle *user_hnd,
1518 int argc, const char **argv)
1520 NTSTATUS status, result;
1521 const char *username;
1522 const char *oldval = "";
1523 union samr_UserInfo *info = NULL;
1524 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1527 d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1528 _("Usage:"), ctx->whoami);
1529 return NT_STATUS_INVALID_PARAMETER;
1532 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1537 if (!NT_STATUS_IS_OK(status)) {
1540 if (!NT_STATUS_IS_OK(result)) {
1544 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1546 FETCHSTR("fullname", full_name);
1547 FETCHSTR("homedir", home_directory);
1548 FETCHSTR("homedrive", home_drive);
1549 FETCHSTR("logonscript", logon_script);
1550 FETCHSTR("profilepath", profile_path);
1551 FETCHSTR("description", description);
1554 d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1558 if (strcmp(argv[0], "NULL") == 0) {
1562 ZERO_STRUCT(info->info21);
1564 SETSTR("fullname", full_name, FULL_NAME);
1565 SETSTR("homedir", home_directory, HOME_DIRECTORY);
1566 SETSTR("homedrive", home_drive, HOME_DRIVE);
1567 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1568 SETSTR("profilepath", profile_path, PROFILE_PATH);
1569 SETSTR("description", description, DESCRIPTION);
1571 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1576 if (!NT_STATUS_IS_OK(status)) {
1582 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1583 ctx->thiscmd, oldval, argv[0]);
1590 #define HANDLEFLG(name, rec) \
1591 do { if (strequal(ctx->thiscmd, name)) { \
1592 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1594 newflags = oldflags | ACB_##rec; \
1596 newflags = oldflags & ~ACB_##rec; \
1599 static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1600 TALLOC_CTX *mem_ctx,
1601 struct rpc_sh_ctx *ctx,
1602 struct rpc_pipe_client *pipe_hnd,
1603 int argc, const char **argv)
1605 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1606 rpc_sh_user_str_edit_internals);
1609 static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1610 TALLOC_CTX *mem_ctx,
1611 struct rpc_sh_ctx *ctx,
1612 struct rpc_pipe_client *pipe_hnd,
1613 struct policy_handle *user_hnd,
1614 int argc, const char **argv)
1616 NTSTATUS status, result;
1617 const char *username;
1618 const char *oldval = "unknown";
1619 uint32_t oldflags, newflags;
1621 union samr_UserInfo *info = NULL;
1622 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1625 ((argc == 1) && !strequal(argv[0], "yes") &&
1626 !strequal(argv[0], "no"))) {
1627 /* TRANSATORS: The yes|no here are program keywords. Please do
1629 d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1631 return NT_STATUS_INVALID_PARAMETER;
1634 newval = strequal(argv[0], "yes");
1636 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1641 if (!NT_STATUS_IS_OK(status)) {
1644 if (!NT_STATUS_IS_OK(result)) {
1648 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1649 oldflags = info->info21.acct_flags;
1650 newflags = info->info21.acct_flags;
1652 HANDLEFLG("disabled", DISABLED);
1653 HANDLEFLG("pwnotreq", PWNOTREQ);
1654 HANDLEFLG("autolock", AUTOLOCK);
1655 HANDLEFLG("pwnoexp", PWNOEXP);
1658 d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1663 ZERO_STRUCT(info->info21);
1665 info->info21.acct_flags = newflags;
1666 info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1668 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1673 if (!NT_STATUS_IS_OK(status)) {
1677 if (NT_STATUS_IS_OK(result)) {
1678 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1679 ctx->thiscmd, oldval, argv[0]);
1687 static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1688 TALLOC_CTX *mem_ctx,
1689 struct rpc_sh_ctx *ctx,
1690 struct rpc_pipe_client *pipe_hnd,
1691 int argc, const char **argv)
1693 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1694 rpc_sh_user_flag_edit_internals);
1697 struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1698 TALLOC_CTX *mem_ctx,
1699 struct rpc_sh_ctx *ctx)
1701 static struct rpc_sh_cmd cmds[] = {
1703 { "fullname", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1704 N_("Show/Set a user's full name") },
1706 { "homedir", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1707 N_("Show/Set a user's home directory") },
1709 { "homedrive", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1710 N_("Show/Set a user's home drive") },
1712 { "logonscript", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1713 N_("Show/Set a user's logon script") },
1715 { "profilepath", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1716 N_("Show/Set a user's profile path") },
1718 { "description", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1719 N_("Show/Set a user's description") },
1721 { "disabled", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1722 N_("Show/Set whether a user is disabled") },
1724 { "autolock", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1725 N_("Show/Set whether a user locked out") },
1727 { "pwnotreq", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1728 N_("Show/Set whether a user does not need a password") },
1730 { "pwnoexp", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1731 N_("Show/Set whether a user's password does not expire") },
1733 { NULL, NULL, 0, NULL, NULL }
1739 struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1740 TALLOC_CTX *mem_ctx,
1741 struct rpc_sh_ctx *ctx)
1743 static struct rpc_sh_cmd cmds[] = {
1745 { "list", NULL, &ndr_table_samr, rpc_sh_user_list,
1746 N_("List available users") },
1748 { "info", NULL, &ndr_table_samr, rpc_sh_user_info,
1749 N_("List the domain groups a user is member of") },
1751 { "show", NULL, &ndr_table_samr, rpc_sh_user_show,
1752 N_("Show info about a user") },
1754 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1755 N_("Show/Modify a user's fields") },
1757 { NULL, NULL, 0, NULL, NULL }
1763 /****************************************************************************/
1766 * Basic usage function for 'net rpc group'.
1767 * @param argc Standard main() style argc.
1768 * @param argv Standard main() style argv. Initial components are already
1772 static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1774 return net_group_usage(c, argc, argv);
1778 * Delete group on a remote RPC server.
1780 * All parameters are provided by the run_rpc_command function, except for
1781 * argc, argv which are passed through.
1783 * @param domain_sid The domain sid acquired from the remote server.
1784 * @param cli A cli_state connected to the server.
1785 * @param mem_ctx Talloc context, destroyed on completion of the function.
1786 * @param argc Standard main() style argc.
1787 * @param argv Standard main() style argv. Initial components are already
1790 * @return Normal NTSTATUS return.
1793 static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1794 const struct dom_sid *domain_sid,
1795 const char *domain_name,
1796 struct cli_state *cli,
1797 struct rpc_pipe_client *pipe_hnd,
1798 TALLOC_CTX *mem_ctx,
1802 struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1803 bool group_is_primary = false;
1804 NTSTATUS status, result;
1806 struct samr_RidAttrArray *rids = NULL;
1809 /* struct samr_RidWithAttribute *user_gids; */
1810 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1812 struct samr_Ids group_rids, name_types;
1813 struct lsa_String lsa_acct_name;
1814 union samr_UserInfo *info = NULL;
1816 if (argc < 1 || c->display_usage) {
1817 rpc_group_usage(c, argc,argv);
1818 return NT_STATUS_OK; /* ok? */
1821 status = dcerpc_samr_Connect2(b, mem_ctx,
1823 MAXIMUM_ALLOWED_ACCESS,
1826 if (!NT_STATUS_IS_OK(status)) {
1827 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1831 if (!NT_STATUS_IS_OK(result)) {
1833 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1837 status = dcerpc_samr_OpenDomain(b, mem_ctx,
1839 MAXIMUM_ALLOWED_ACCESS,
1840 discard_const_p(struct dom_sid2, domain_sid),
1843 if (!NT_STATUS_IS_OK(status)) {
1844 d_fprintf(stderr, _("Request open_domain failed\n"));
1848 if (!NT_STATUS_IS_OK(result)) {
1850 d_fprintf(stderr, _("Request open_domain failed\n"));
1854 init_lsa_String(&lsa_acct_name, argv[0]);
1856 status = dcerpc_samr_LookupNames(b, mem_ctx,
1863 if (!NT_STATUS_IS_OK(status)) {
1864 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1868 if (!NT_STATUS_IS_OK(result)) {
1870 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1873 if (group_rids.count != 1) {
1874 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1877 if (name_types.count != 1) {
1878 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1882 switch (name_types.ids[0])
1884 case SID_NAME_DOM_GRP:
1885 status = dcerpc_samr_OpenGroup(b, mem_ctx,
1887 MAXIMUM_ALLOWED_ACCESS,
1891 if (!NT_STATUS_IS_OK(status)) {
1892 d_fprintf(stderr, _("Request open_group failed"));
1896 if (!NT_STATUS_IS_OK(result)) {
1898 d_fprintf(stderr, _("Request open_group failed"));
1902 group_rid = group_rids.ids[0];
1904 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
1908 if (!NT_STATUS_IS_OK(status)) {
1910 _("Unable to query group members of %s"),
1915 if (!NT_STATUS_IS_OK(result)) {
1918 _("Unable to query group members of %s"),
1923 if (c->opt_verbose) {
1925 _("Domain Group %s (rid: %d) has %d members\n"),
1926 argv[0],group_rid, rids->count);
1929 /* Check if group is anyone's primary group */
1930 for (i = 0; i < rids->count; i++)
1932 status = dcerpc_samr_OpenUser(b, mem_ctx,
1934 MAXIMUM_ALLOWED_ACCESS,
1938 if (!NT_STATUS_IS_OK(status)) {
1940 _("Unable to open group member %d\n"),
1945 if (!NT_STATUS_IS_OK(result)) {
1948 _("Unable to open group member %d\n"),
1953 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1958 if (!NT_STATUS_IS_OK(status)) {
1960 _("Unable to lookup userinfo for group "
1966 if (!NT_STATUS_IS_OK(result)) {
1969 _("Unable to lookup userinfo for group "
1975 if (info->info21.primary_gid == group_rid) {
1976 if (c->opt_verbose) {
1977 d_printf(_("Group is primary group "
1979 info->info21.account_name.string);
1981 group_is_primary = true;
1984 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1987 if (group_is_primary) {
1988 d_fprintf(stderr, _("Unable to delete group because "
1989 "some of it's members have it as primary "
1991 status = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1995 /* remove all group members */
1996 for (i = 0; i < rids->count; i++)
1999 d_printf(_("Remove group member %d..."),
2001 status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
2005 if (!NT_STATUS_IS_OK(status)) {
2009 if (NT_STATUS_IS_OK(result)) {
2011 d_printf(_("ok\n"));
2014 d_printf("%s\n", _("failed"));
2019 status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2022 if (!NT_STATUS_IS_OK(status)) {
2029 /* removing a local group is easier... */
2030 case SID_NAME_ALIAS:
2031 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2033 MAXIMUM_ALLOWED_ACCESS,
2037 if (!NT_STATUS_IS_OK(status)) {
2038 d_fprintf(stderr, _("Request open_alias failed\n"));
2041 if (!NT_STATUS_IS_OK(result)) {
2043 d_fprintf(stderr, _("Request open_alias failed\n"));
2047 status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
2050 if (!NT_STATUS_IS_OK(status)) {
2058 d_fprintf(stderr, _("%s is of type %s. This command is only "
2059 "for deleting local or global groups\n"),
2060 argv[0],sid_type_lookup(name_types.ids[0]));
2061 status = NT_STATUS_UNSUCCESSFUL;
2065 if (NT_STATUS_IS_OK(status)) {
2067 d_printf(_("Deleted %s '%s'\n"),
2068 sid_type_lookup(name_types.ids[0]), argv[0]);
2070 d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
2071 get_friendly_nt_error_msg(status));
2079 static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
2081 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2082 rpc_group_delete_internals, argc,argv);
2085 static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
2087 NET_API_STATUS status;
2088 struct GROUP_INFO_1 info1;
2089 uint32_t parm_error = 0;
2091 if (argc != 1 || c->display_usage) {
2092 rpc_group_usage(c, argc, argv);
2098 info1.grpi1_name = argv[0];
2099 if (c->opt_comment && strlen(c->opt_comment) > 0) {
2100 info1.grpi1_comment = c->opt_comment;
2103 status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
2107 _("Failed to add group '%s' with error: %s.\n"),
2108 argv[0], libnetapi_get_error_string(c->netapi_ctx,
2112 d_printf(_("Added group '%s'.\n"), argv[0]);
2118 static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
2120 NET_API_STATUS status;
2121 struct LOCALGROUP_INFO_1 info1;
2122 uint32_t parm_error = 0;
2124 if (argc != 1 || c->display_usage) {
2125 rpc_group_usage(c, argc, argv);
2131 info1.lgrpi1_name = argv[0];
2132 if (c->opt_comment && strlen(c->opt_comment) > 0) {
2133 info1.lgrpi1_comment = c->opt_comment;
2136 status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
2140 _("Failed to add alias '%s' with error: %s.\n"),
2141 argv[0], libnetapi_get_error_string(c->netapi_ctx,
2145 d_printf(_("Added alias '%s'.\n"), argv[0]);
2151 static int rpc_group_add(struct net_context *c, int argc, const char **argv)
2153 if (c->opt_localgroup)
2154 return rpc_alias_add_internals(c, argc, argv);
2156 return rpc_group_add_internals(c, argc, argv);
2159 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2160 TALLOC_CTX *mem_ctx,
2162 struct dom_sid *sid,
2163 enum lsa_SidType *type)
2165 struct dom_sid *sids = NULL;
2166 enum lsa_SidType *types = NULL;
2167 struct rpc_pipe_client *pipe_hnd = NULL;
2168 struct policy_handle lsa_pol;
2169 NTSTATUS status, result;
2170 struct dcerpc_binding_handle *b;
2172 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
2174 if (!NT_STATUS_IS_OK(status)) {
2178 b = pipe_hnd->binding_handle;
2180 status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
2181 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2183 if (!NT_STATUS_IS_OK(status)) {
2187 status = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2188 &name, NULL, 1, &sids, &types);
2190 if (NT_STATUS_IS_OK(status)) {
2191 sid_copy(sid, &sids[0]);
2195 dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
2199 TALLOC_FREE(pipe_hnd);
2202 if (!NT_STATUS_IS_OK(status) && (strncasecmp_m(name, "S-", 2) == 0)) {
2204 /* Try as S-1-5-whatever */
2206 struct dom_sid tmp_sid;
2208 if (string_to_sid(&tmp_sid, name)) {
2209 sid_copy(sid, &tmp_sid);
2210 *type = SID_NAME_UNKNOWN;
2211 status = NT_STATUS_OK;
2218 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2219 TALLOC_CTX *mem_ctx,
2220 const struct dom_sid *group_sid,
2223 struct policy_handle connect_pol, domain_pol;
2224 NTSTATUS status, result;
2226 struct policy_handle group_pol;
2227 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2229 struct samr_Ids rids, rid_types;
2230 struct lsa_String lsa_acct_name;
2234 sid_copy(&sid, group_sid);
2236 if (!sid_split_rid(&sid, &group_rid)) {
2237 return NT_STATUS_UNSUCCESSFUL;
2240 /* Get sam policy handle */
2241 status = dcerpc_samr_Connect2(b, mem_ctx,
2243 MAXIMUM_ALLOWED_ACCESS,
2246 if (!NT_STATUS_IS_OK(status)) {
2249 if (!NT_STATUS_IS_OK(result)) {
2253 /* Get domain policy handle */
2254 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2256 MAXIMUM_ALLOWED_ACCESS,
2260 if (!NT_STATUS_IS_OK(status)) {
2263 if (!NT_STATUS_IS_OK(result)) {
2267 init_lsa_String(&lsa_acct_name, member);
2269 status = dcerpc_samr_LookupNames(b, mem_ctx,
2276 if (!NT_STATUS_IS_OK(status)) {
2277 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2282 if (!NT_STATUS_IS_OK(result)) {
2284 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2288 if (rids.count != 1) {
2289 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2292 if (rid_types.count != 1) {
2293 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2297 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2299 MAXIMUM_ALLOWED_ACCESS,
2303 if (!NT_STATUS_IS_OK(status)) {
2307 if (!NT_STATUS_IS_OK(result)) {
2312 status = dcerpc_samr_AddGroupMember(b, mem_ctx,
2315 0x0005, /* unknown flags */
2317 if (!NT_STATUS_IS_OK(status)) {
2324 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2328 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2329 struct cli_state *cli,
2330 TALLOC_CTX *mem_ctx,
2331 const struct dom_sid *alias_sid,
2334 struct policy_handle connect_pol, domain_pol;
2335 NTSTATUS status, result;
2337 struct policy_handle alias_pol;
2338 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2340 struct dom_sid member_sid;
2341 enum lsa_SidType member_type;
2345 sid_copy(&sid, alias_sid);
2347 if (!sid_split_rid(&sid, &alias_rid)) {
2348 return NT_STATUS_UNSUCCESSFUL;
2351 result = get_sid_from_name(cli, mem_ctx,
2352 member, &member_sid, &member_type);
2354 if (!NT_STATUS_IS_OK(result)) {
2355 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2360 /* Get sam policy handle */
2361 status = dcerpc_samr_Connect2(b, mem_ctx,
2363 MAXIMUM_ALLOWED_ACCESS,
2366 if (!NT_STATUS_IS_OK(status)) {
2369 if (!NT_STATUS_IS_OK(result)) {
2374 /* Get domain policy handle */
2375 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2377 MAXIMUM_ALLOWED_ACCESS,
2381 if (!NT_STATUS_IS_OK(status)) {
2384 if (!NT_STATUS_IS_OK(result)) {
2389 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2391 MAXIMUM_ALLOWED_ACCESS,
2395 if (!NT_STATUS_IS_OK(status)) {
2398 if (!NT_STATUS_IS_OK(result)) {
2402 status = dcerpc_samr_AddAliasMember(b, mem_ctx,
2406 if (!NT_STATUS_IS_OK(status)) {
2413 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2417 static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
2418 const struct dom_sid *domain_sid,
2419 const char *domain_name,
2420 struct cli_state *cli,
2421 struct rpc_pipe_client *pipe_hnd,
2422 TALLOC_CTX *mem_ctx,
2426 struct dom_sid group_sid;
2427 enum lsa_SidType group_type;
2429 if (argc != 2 || c->display_usage) {
2432 _("net rpc group addmem <group> <member>\n"
2433 " Add a member to a group\n"
2434 " group\tGroup to add member to\n"
2435 " member\tMember to add to group\n"));
2436 return NT_STATUS_UNSUCCESSFUL;
2439 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2440 &group_sid, &group_type))) {
2441 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2443 return NT_STATUS_UNSUCCESSFUL;
2446 if (group_type == SID_NAME_DOM_GRP) {
2447 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2448 &group_sid, argv[1]);
2450 if (!NT_STATUS_IS_OK(result)) {
2451 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2452 argv[1], argv[0], nt_errstr(result));
2457 if (group_type == SID_NAME_ALIAS) {
2458 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, cli, mem_ctx,
2459 &group_sid, argv[1]);
2461 if (!NT_STATUS_IS_OK(result)) {
2462 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2463 argv[1], argv[0], nt_errstr(result));
2468 d_fprintf(stderr, _("Can only add members to global or local groups "
2469 "which %s is not\n"), argv[0]);
2471 return NT_STATUS_UNSUCCESSFUL;
2474 static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2476 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2477 rpc_group_addmem_internals,
2481 static NTSTATUS rpc_del_groupmem(struct net_context *c,
2482 struct rpc_pipe_client *pipe_hnd,
2483 TALLOC_CTX *mem_ctx,
2484 const struct dom_sid *group_sid,
2487 struct policy_handle connect_pol, domain_pol;
2488 NTSTATUS status, result;
2490 struct policy_handle group_pol;
2491 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2493 struct samr_Ids rids, rid_types;
2494 struct lsa_String lsa_acct_name;
2498 sid_copy(&sid, group_sid);
2500 if (!sid_split_rid(&sid, &group_rid))
2501 return NT_STATUS_UNSUCCESSFUL;
2503 /* Get sam policy handle */
2504 status = dcerpc_samr_Connect2(b, mem_ctx,
2506 MAXIMUM_ALLOWED_ACCESS,
2509 if (!NT_STATUS_IS_OK(status)) {
2512 if (!NT_STATUS_IS_OK(result)) {
2517 /* Get domain policy handle */
2518 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2520 MAXIMUM_ALLOWED_ACCESS,
2524 if (!NT_STATUS_IS_OK(status)) {
2527 if (!NT_STATUS_IS_OK(result)) {
2531 init_lsa_String(&lsa_acct_name, member);
2533 status = dcerpc_samr_LookupNames(b, mem_ctx,
2540 if (!NT_STATUS_IS_OK(status)) {
2541 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2546 if (!NT_STATUS_IS_OK(result)) {
2548 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2552 if (rids.count != 1) {
2553 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2556 if (rid_types.count != 1) {
2557 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2561 status = dcerpc_samr_OpenGroup(b, mem_ctx,
2563 MAXIMUM_ALLOWED_ACCESS,
2567 if (!NT_STATUS_IS_OK(status)) {
2570 if (!NT_STATUS_IS_OK(result)) {
2575 status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
2579 if (!NT_STATUS_IS_OK(status)) {
2585 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2589 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2590 struct cli_state *cli,
2591 TALLOC_CTX *mem_ctx,
2592 const struct dom_sid *alias_sid,
2595 struct policy_handle connect_pol, domain_pol;
2596 NTSTATUS status, result;
2598 struct policy_handle alias_pol;
2599 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2601 struct dom_sid member_sid;
2602 enum lsa_SidType member_type;
2606 sid_copy(&sid, alias_sid);
2608 if (!sid_split_rid(&sid, &alias_rid))
2609 return NT_STATUS_UNSUCCESSFUL;
2611 result = get_sid_from_name(cli, mem_ctx,
2612 member, &member_sid, &member_type);
2614 if (!NT_STATUS_IS_OK(result)) {
2615 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2620 /* Get sam policy handle */
2621 status = dcerpc_samr_Connect2(b, mem_ctx,
2623 MAXIMUM_ALLOWED_ACCESS,
2626 if (!NT_STATUS_IS_OK(status)) {
2629 if (!NT_STATUS_IS_OK(result)) {
2634 /* Get domain policy handle */
2635 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2637 MAXIMUM_ALLOWED_ACCESS,
2641 if (!NT_STATUS_IS_OK(status)) {
2644 if (!NT_STATUS_IS_OK(result)) {
2649 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2651 MAXIMUM_ALLOWED_ACCESS,
2655 if (!NT_STATUS_IS_OK(status)) {
2659 if (!NT_STATUS_IS_OK(result)) {
2663 status = dcerpc_samr_DeleteAliasMember(b, mem_ctx,
2668 if (!NT_STATUS_IS_OK(status)) {
2675 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2679 static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2680 const struct dom_sid *domain_sid,
2681 const char *domain_name,
2682 struct cli_state *cli,
2683 struct rpc_pipe_client *pipe_hnd,
2684 TALLOC_CTX *mem_ctx,
2688 struct dom_sid group_sid;
2689 enum lsa_SidType group_type;
2691 if (argc != 2 || c->display_usage) {
2694 _("net rpc group delmem <group> <member>\n"
2695 " Delete a member from a group\n"
2696 " group\tGroup to delete member from\n"
2697 " member\tMember to delete from group\n"));
2698 return NT_STATUS_UNSUCCESSFUL;
2701 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2702 &group_sid, &group_type))) {
2703 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2705 return NT_STATUS_UNSUCCESSFUL;
2708 if (group_type == SID_NAME_DOM_GRP) {
2709 NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2710 &group_sid, argv[1]);
2712 if (!NT_STATUS_IS_OK(result)) {
2713 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2714 argv[1], argv[0], nt_errstr(result));
2719 if (group_type == SID_NAME_ALIAS) {
2720 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, cli, mem_ctx,
2721 &group_sid, argv[1]);
2723 if (!NT_STATUS_IS_OK(result)) {
2724 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2725 argv[1], argv[0], nt_errstr(result));
2730 d_fprintf(stderr, _("Can only delete members from global or local "
2731 "groups which %s is not\n"), argv[0]);
2733 return NT_STATUS_UNSUCCESSFUL;
2736 static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2738 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2739 rpc_group_delmem_internals,
2744 * List groups on a remote RPC server.
2746 * All parameters are provided by the run_rpc_command function, except for
2747 * argc, argv which are passes through.
2749 * @param domain_sid The domain sid acquired from the remote server.
2750 * @param cli A cli_state connected to the server.
2751 * @param mem_ctx Talloc context, destroyed on completion of the function.
2752 * @param argc Standard main() style argc.
2753 * @param argv Standard main() style argv. Initial components are already
2756 * @return Normal NTSTATUS return.
2759 static NTSTATUS rpc_group_list_internals(struct net_context *c,
2760 const struct dom_sid *domain_sid,
2761 const char *domain_name,
2762 struct cli_state *cli,
2763 struct rpc_pipe_client *pipe_hnd,
2764 TALLOC_CTX *mem_ctx,
2768 struct policy_handle connect_pol, domain_pol;
2769 NTSTATUS status, result;
2770 uint32_t start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2771 struct samr_SamArray *groups = NULL;
2772 bool global = false;
2774 bool builtin = false;
2775 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2777 if (c->display_usage) {
2780 _("net rpc group list [global] [local] [builtin]\n"
2781 " List groups on RPC server\n"
2782 " global\tList global groups\n"
2783 " local\tList local groups\n"
2784 " builtin\tList builtin groups\n"
2785 " If none of global, local or builtin is "
2786 "specified, all three options are considered "
2788 return NT_STATUS_OK;
2797 for (i=0; i<argc; i++) {
2798 if (strequal(argv[i], "global"))
2801 if (strequal(argv[i], "local"))
2804 if (strequal(argv[i], "builtin"))
2808 /* Get sam policy handle */
2810 status = dcerpc_samr_Connect2(b, mem_ctx,
2812 MAXIMUM_ALLOWED_ACCESS,
2815 if (!NT_STATUS_IS_OK(status)) {
2818 if (!NT_STATUS_IS_OK(result)) {
2823 /* Get domain policy handle */
2825 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2827 MAXIMUM_ALLOWED_ACCESS,
2828 discard_const_p(struct dom_sid2, domain_sid),
2831 if (!NT_STATUS_IS_OK(status)) {
2834 if (!NT_STATUS_IS_OK(result)) {
2839 /* Query domain groups */
2840 if (c->opt_long_list_entries)
2841 d_printf(_("\nGroup name Comment"
2842 "\n-----------------------------\n"));
2844 uint32_t max_size, total_size, returned_size;
2845 union samr_DispInfo info;
2849 dcerpc_get_query_dispinfo_params(
2850 loop_count, &max_entries, &max_size);
2852 status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
2862 if (!NT_STATUS_IS_OK(status)) {
2865 num_entries = info.info3.count;
2866 start_idx += info.info3.count;
2868 if (!NT_STATUS_IS_OK(result) &&
2869 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2872 for (i = 0; i < num_entries; i++) {
2874 const char *group = NULL;
2875 const char *desc = NULL;
2877 group = info.info3.entries[i].account_name.string;
2878 desc = info.info3.entries[i].description.string;
2880 if (c->opt_long_list_entries)
2881 printf("%-21.21s %-50.50s\n",
2884 printf("%s\n", group);
2886 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2887 /* query domain aliases */
2892 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2899 if (!NT_STATUS_IS_OK(status)) {
2902 if (!NT_STATUS_IS_OK(result) &&
2903 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2906 for (i = 0; i < num_entries; i++) {
2908 const char *description = NULL;
2910 if (c->opt_long_list_entries) {
2912 struct policy_handle alias_pol;
2913 union samr_AliasInfo *info = NULL;
2916 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2919 groups->entries[i].idx,
2922 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2923 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
2928 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2929 status = dcerpc_samr_Close(b, mem_ctx,
2932 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2933 description = info->description.string;
2939 if (description != NULL) {
2940 printf("%-21.21s %-50.50s\n",
2941 groups->entries[i].name.string,
2944 printf("%s\n", groups->entries[i].name.string);
2947 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2948 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2949 /* Get builtin policy handle */
2951 status = dcerpc_samr_OpenDomain(b, mem_ctx,
2953 MAXIMUM_ALLOWED_ACCESS,
2954 discard_const_p(struct dom_sid2, &global_sid_Builtin),
2957 if (!NT_STATUS_IS_OK(status)) {
2960 if (!NT_STATUS_IS_OK(result)) {
2965 /* query builtin aliases */
2968 if (!builtin) break;
2970 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2977 if (!NT_STATUS_IS_OK(status)) {
2980 if (!NT_STATUS_IS_OK(result) &&
2981 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
2986 for (i = 0; i < num_entries; i++) {
2988 const char *description = NULL;
2990 if (c->opt_long_list_entries) {
2992 struct policy_handle alias_pol;
2993 union samr_AliasInfo *info = NULL;
2996 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2999 groups->entries[i].idx,
3002 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3003 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
3008 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3009 status = dcerpc_samr_Close(b, mem_ctx,
3012 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3013 description = info->description.string;
3019 if (description != NULL) {
3020 printf("%-21.21s %-50.50s\n",
3021 groups->entries[i].name.string,
3024 printf("%s\n", groups->entries[i].name.string);
3027 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
3035 static int rpc_group_list(struct net_context *c, int argc, const char **argv)
3037 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3038 rpc_group_list_internals,
3042 static NTSTATUS rpc_list_group_members(struct net_context *c,
3043 struct rpc_pipe_client *pipe_hnd,
3044 TALLOC_CTX *mem_ctx,
3045 const char *domain_name,
3046 const struct dom_sid *domain_sid,
3047 struct policy_handle *domain_pol,
3050 NTSTATUS result, status;
3051 struct policy_handle group_pol;
3052 uint32_t num_members, *group_rids;
3054 struct samr_RidAttrArray *rids = NULL;
3055 struct lsa_Strings names;
3056 struct samr_Ids types;
3057 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3059 status = dcerpc_samr_OpenGroup(b, mem_ctx,
3061 MAXIMUM_ALLOWED_ACCESS,
3065 if (!NT_STATUS_IS_OK(status)) {
3068 if (!NT_STATUS_IS_OK(result)) {
3072 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
3076 if (!NT_STATUS_IS_OK(status)) {
3079 if (!NT_STATUS_IS_OK(result)) {
3083 num_members = rids->count;
3084 group_rids = rids->rids;
3086 while (num_members > 0) {
3087 int this_time = 512;
3089 if (num_members < this_time)
3090 this_time = num_members;
3092 status = dcerpc_samr_LookupRids(b, mem_ctx,
3099 if (!NT_STATUS_IS_OK(status)) {
3102 if (!NT_STATUS_IS_OK(result)) {
3105 if (names.count != this_time) {
3106 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3108 if (types.count != this_time) {
3109 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3111 /* We only have users as members, but make the output
3112 the same as the output of alias members */
3114 for (i = 0; i < this_time; i++) {
3116 if (c->opt_long_list_entries) {
3118 struct dom_sid_buf sid_str;
3120 sid_compose(&sid, domain_sid, group_rids[i]);
3122 printf("%s %s\\%s %d\n",
3123 dom_sid_str_buf(&sid, &sid_str),
3125 names.names[i].string,
3128 printf("%s\\%s\n", domain_name,
3129 names.names[i].string);
3133 num_members -= this_time;
3137 return NT_STATUS_OK;
3140 static NTSTATUS rpc_list_alias_members(struct net_context *c,
3141 struct rpc_pipe_client *pipe_hnd,
3142 struct cli_state *cli,
3143 TALLOC_CTX *mem_ctx,
3144 struct policy_handle *domain_pol,
3147 NTSTATUS result, status;
3148 struct rpc_pipe_client *lsa_pipe;
3149 struct policy_handle alias_pol, lsa_pol;
3150 uint32_t num_members;
3151 struct dom_sid *alias_sids;
3154 enum lsa_SidType *types;
3156 struct lsa_SidArray sid_array;
3157 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3159 status = dcerpc_samr_OpenAlias(b, mem_ctx,
3161 MAXIMUM_ALLOWED_ACCESS,
3165 if (!NT_STATUS_IS_OK(status)) {
3168 if (!NT_STATUS_IS_OK(result)) {
3172 status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
3176 if (!NT_STATUS_IS_OK(status)) {
3177 d_fprintf(stderr, _("Couldn't list alias members\n"));
3180 if (!NT_STATUS_IS_OK(result)) {
3181 d_fprintf(stderr, _("Couldn't list alias members\n"));
3185 num_members = sid_array.num_sids;
3187 if (num_members == 0) {
3188 return NT_STATUS_OK;
3191 result = cli_rpc_pipe_open_noauth(cli,
3194 if (!NT_STATUS_IS_OK(result)) {
3195 d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
3196 nt_errstr(result) );
3200 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
3201 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
3203 if (!NT_STATUS_IS_OK(result)) {
3204 d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
3205 TALLOC_FREE(lsa_pipe);
3209 alias_sids = talloc_zero_array(mem_ctx, struct dom_sid, num_members);
3211 d_fprintf(stderr, _("Out of memory\n"));
3212 TALLOC_FREE(lsa_pipe);
3213 return NT_STATUS_NO_MEMORY;
3216 for (i=0; i<num_members; i++) {
3217 sid_copy(&alias_sids[i], sid_array.sids[i].sid);
3220 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
3221 num_members, alias_sids,
3222 &domains, &names, &types);
3224 if (!NT_STATUS_IS_OK(result) &&
3225 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3226 d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
3227 TALLOC_FREE(lsa_pipe);
3231 for (i = 0; i < num_members; i++) {
3232 struct dom_sid_buf sid_str;
3233 dom_sid_str_buf(&alias_sids[i], &sid_str);
3235 if (c->opt_long_list_entries) {
3236 printf("%s %s\\%s %d\n", sid_str.buf,
3237 domains[i] ? domains[i] : _("*unknown*"),
3238 names[i] ? names[i] : _("*unknown*"), types[i]);
3241 printf("%s\\%s\n", domains[i], names[i]);
3243 printf("%s\n", sid_str.buf);
3247 TALLOC_FREE(lsa_pipe);
3248 return NT_STATUS_OK;
3251 static NTSTATUS rpc_group_members_internals(struct net_context *c,
3252 const struct dom_sid *domain_sid,
3253 const char *domain_name,
3254 struct cli_state *cli,
3255 struct rpc_pipe_client *pipe_hnd,
3256 TALLOC_CTX *mem_ctx,
3260 NTSTATUS result, status;
3261 struct policy_handle connect_pol, domain_pol;
3262 struct samr_Ids rids, rid_types;
3263 struct lsa_String lsa_acct_name;
3264 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3266 /* Get sam policy handle */
3268 status = dcerpc_samr_Connect2(b, mem_ctx,
3270 MAXIMUM_ALLOWED_ACCESS,
3273 if (!NT_STATUS_IS_OK(status)) {
3276 if (!NT_STATUS_IS_OK(result)) {
3280 /* Get domain policy handle */
3282 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3284 MAXIMUM_ALLOWED_ACCESS,
3285 discard_const_p(struct dom_sid2, domain_sid),
3288 if (!NT_STATUS_IS_OK(status)) {
3291 if (!NT_STATUS_IS_OK(result)) {
3295 init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
3297 status = dcerpc_samr_LookupNames(b, mem_ctx,
3304 if (!NT_STATUS_IS_OK(status)) {
3308 if (!NT_STATUS_IS_OK(result)) {
3310 /* Ok, did not find it in the global sam, try with builtin */
3312 struct dom_sid sid_Builtin;
3314 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3316 sid_copy(&sid_Builtin, &global_sid_Builtin);
3318 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3320 MAXIMUM_ALLOWED_ACCESS,
3324 if (!NT_STATUS_IS_OK(status)) {
3327 if (!NT_STATUS_IS_OK(result)) {
3328 d_fprintf(stderr, _("Couldn't find group %s\n"),
3333 status = dcerpc_samr_LookupNames(b, mem_ctx,
3340 if (!NT_STATUS_IS_OK(status)) {
3343 if (!NT_STATUS_IS_OK(result)) {
3344 d_fprintf(stderr, _("Couldn't find group %s\n"),
3350 if (rids.count != 1) {
3351 d_fprintf(stderr, _("Couldn't find group %s\n"),
3353 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3355 if (rid_types.count != 1) {
3356 d_fprintf(stderr, _("Couldn't find group %s\n"),
3358 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3362 if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
3363 return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
3364 domain_sid, &domain_pol,
3368 if (rid_types.ids[0] == SID_NAME_ALIAS) {
3369 return rpc_list_alias_members(c, pipe_hnd, cli, mem_ctx, &domain_pol,
3373 return NT_STATUS_NO_SUCH_GROUP;
3376 static int rpc_group_members(struct net_context *c, int argc, const char **argv)
3378 if (argc != 1 || c->display_usage) {
3379 return rpc_group_usage(c, argc, argv);
3382 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3383 rpc_group_members_internals,
3387 static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
3389 NET_API_STATUS status;
3390 struct GROUP_INFO_0 g0;
3394 d_printf(_("Usage:\n"));
3395 d_printf("net rpc group rename group newname\n");
3399 g0.grpi0_name = argv[1];
3401 status = NetGroupSetInfo(c->opt_host,
3408 d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
3409 argv[0], libnetapi_get_error_string(c->netapi_ctx,
3417 static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
3419 if (argc != 2 || c->display_usage) {
3420 return rpc_group_usage(c, argc, argv);
3423 return rpc_group_rename_internals(c, argc, argv);
3427 * 'net rpc group' entrypoint.
3428 * @param argc Standard main() style argc.
3429 * @param argv Standard main() style argv. Initial components are already
3433 int net_rpc_group(struct net_context *c, int argc, const char **argv)
3435 NET_API_STATUS status;
3437 struct functable func[] = {
3442 N_("Create specified group"),
3443 N_("net rpc group add\n"
3444 " Create specified group")
3450 N_("Delete specified group"),
3451 N_("net rpc group delete\n"
3452 " Delete specified group")
3458 N_("Add member to group"),
3459 N_("net rpc group addmem\n"
3460 " Add member to group")
3466 N_("Remove member from group"),
3467 N_("net rpc group delmem\n"
3468 " Remove member from group")
3475 N_("net rpc group list\n"
3482 N_("List group members"),
3483 N_("net rpc group members\n"
3484 " List group members")
3491 N_("net rpc group rename\n"
3494 {NULL, NULL, 0, NULL, NULL}
3497 status = libnetapi_net_init(&c->netapi_ctx);
3501 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
3502 libnetapi_set_password(c->netapi_ctx, c->opt_password);
3503 if (c->opt_kerberos) {
3504 libnetapi_set_use_kerberos(c->netapi_ctx);
3508 if (c->display_usage) {
3509 d_printf(_("Usage:\n"));
3510 d_printf(_("net rpc group\n"
3511 " Alias for net rpc group list global "
3512 "local builtin\n"));
3513 net_display_usage_from_functable(func);
3517 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3518 rpc_group_list_internals,
3522 return net_run_function(c, argc, argv, "net rpc group", func);
3525 /****************************************************************************/
3527 static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
3529 return net_share_usage(c, argc, argv);
3533 * Add a share on a remote RPC server.
3535 * @param argc Standard main() style argc.
3536 * @param argv Standard main() style argv. Initial components are already
3539 * @return A shell status integer (0 for success).
3542 static int rpc_share_add(struct net_context *c, int argc, const char **argv)
3544 NET_API_STATUS status;
3547 uint32_t type = STYPE_DISKTREE; /* only allow disk shares to be added */
3548 uint32_t num_users=0, perms=0;
3549 char *password=NULL; /* don't allow a share password */
3550 struct SHARE_INFO_2 i2;
3551 uint32_t parm_error = 0;
3553 if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
3554 return rpc_share_usage(c, argc, argv);
3557 if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
3561 path = strchr(sharename, '=');
3568 i2.shi2_netname = sharename;
3569 i2.shi2_type = type;
3570 i2.shi2_remark = c->opt_comment;
3571 i2.shi2_permissions = perms;
3572 i2.shi2_max_uses = c->opt_maxusers;
3573 i2.shi2_current_uses = num_users;
3574 i2.shi2_path = path;
3575 i2.shi2_passwd = password;
3577 status = NetShareAdd(c->opt_host,
3582 printf(_("NetShareAdd failed with: %s\n"),
3583 libnetapi_get_error_string(c->netapi_ctx, status));
3590 * Delete a share on a remote RPC server.
3592 * @param domain_sid The domain sid acquired from the remote server.
3593 * @param argc Standard main() style argc.
3594 * @param argv Standard main() style argv. Initial components are already
3597 * @return A shell status integer (0 for success).
3599 static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
3601 if (argc < 1 || c->display_usage) {
3602 return rpc_share_usage(c, argc, argv);
3605 return NetShareDel(c->opt_host, argv[0], 0);
3609 * Formatted print of share info
3611 * @param r pointer to SHARE_INFO_1 to format
3614 static void display_share_info_1(struct net_context *c,
3615 struct SHARE_INFO_1 *r)
3617 if (c->opt_long_list_entries) {
3618 d_printf("%-12s %-8.8s %-50s\n",
3620 net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3623 d_printf("%s\n", r->shi1_netname);
3627 static WERROR get_share_info(struct net_context *c,
3628 struct rpc_pipe_client *pipe_hnd,
3629 TALLOC_CTX *mem_ctx,
3633 struct srvsvc_NetShareInfoCtr *info_ctr)
3637 union srvsvc_NetShareInfo info;
3638 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3640 /* no specific share requested, enumerate all */
3643 uint32_t preferred_len = 0xffffffff;
3644 uint32_t total_entries = 0;
3645 uint32_t resume_handle = 0;
3647 info_ctr->level = level;
3649 status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx,
3656 if (!NT_STATUS_IS_OK(status)) {
3657 return ntstatus_to_werror(status);
3662 /* request just one share */
3663 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
3670 if (!NT_STATUS_IS_OK(status)) {
3671 result = ntstatus_to_werror(status);
3675 if (!W_ERROR_IS_OK(result)) {
3680 ZERO_STRUCTP(info_ctr);
3682 info_ctr->level = level;
3687 struct srvsvc_NetShareCtr1 *ctr1;
3689 ctr1 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr1);
3690 W_ERROR_HAVE_NO_MEMORY(ctr1);
3693 ctr1->array = info.info1;
3695 info_ctr->ctr.ctr1 = ctr1;
3701 struct srvsvc_NetShareCtr2 *ctr2;
3703 ctr2 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr2);
3704 W_ERROR_HAVE_NO_MEMORY(ctr2);
3707 ctr2->array = info.info2;
3709 info_ctr->ctr.ctr2 = ctr2;
3715 struct srvsvc_NetShareCtr502 *ctr502;
3717 ctr502 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr502);
3718 W_ERROR_HAVE_NO_MEMORY(ctr502);
3721 ctr502->array = info.info502;
3723 info_ctr->ctr.ctr502 = ctr502;
3733 * 'net rpc share list' entrypoint.
3734 * @param argc Standard main() style argc.
3735 * @param argv Standard main() style argv. Initial components are already
3738 static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3740 NET_API_STATUS status;
3741 struct SHARE_INFO_1 *i1 = NULL;
3742 uint32_t entries_read = 0;
3743 uint32_t total_entries = 0;
3744 uint32_t resume_handle = 0;
3745 uint32_t i, level = 1;
3747 if (c->display_usage) {
3749 "net rpc share list\n"
3752 _("List shares on remote server"));
3756 status = NetShareEnum(c->opt_host,
3758 (uint8_t **)(void *)&i1,
3767 /* Display results */
3769 if (c->opt_long_list_entries) {
3771 "\nEnumerating shared resources (exports) on remote server:\n\n"
3772 "\nShare name Type Description\n"
3773 "---------- ---- -----------\n"));
3775 for (i = 0; i < entries_read; i++)
3776 display_share_info_1(c, &i1[i]);
3781 static bool check_share_availability(struct cli_state *cli, const char *netname)
3785 status = cli_tree_connect(cli, netname, "A:", NULL);
3786 if (!NT_STATUS_IS_OK(status)) {
3787 d_printf(_("skipping [%s]: not a file share.\n"), netname);
3791 status = cli_tdis(cli);
3792 if (!NT_STATUS_IS_OK(status)) {
3793 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3800 static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3801 const char *netname, uint32_t type)
3803 /* only support disk shares */
3804 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3805 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3810 /* skip builtin shares */
3811 /* FIXME: should print$ be added too ? */
3812 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3813 strequal(netname,"global"))
3816 if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3817 printf(_("excluding [%s]\n"), netname);
3821 return check_share_availability(cli, netname);
3825 * Migrate shares from a remote RPC server to the local RPC server.
3827 * All parameters are provided by the run_rpc_command function, except for
3828 * argc, argv which are passed through.
3830 * @param domain_sid The domain sid acquired from the remote server.
3831 * @param cli A cli_state connected to the server.
3832 * @param mem_ctx Talloc context, destroyed on completion of the function.
3833 * @param argc Standard main() style argc.
3834 * @param argv Standard main() style argv. Initial components are already
3837 * @return Normal NTSTATUS return.
3840 static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3841 const struct dom_sid *domain_sid,
3842 const char *domain_name,
3843 struct cli_state *cli,
3844 struct rpc_pipe_client *pipe_hnd,
3845 TALLOC_CTX *mem_ctx,
3850 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3851 struct srvsvc_NetShareInfoCtr ctr_src;
3853 struct rpc_pipe_client *srvsvc_pipe = NULL;
3854 struct cli_state *cli_dst = NULL;
3855 uint32_t level = 502; /* includes secdesc */
3856 uint32_t parm_error = 0;
3857 struct dcerpc_binding_handle *b;
3859 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3861 if (!W_ERROR_IS_OK(result))
3864 /* connect destination PI_SRVSVC */
3865 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3867 if (!NT_STATUS_IS_OK(nt_status))
3870 b = srvsvc_pipe->binding_handle;
3872 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3874 union srvsvc_NetShareInfo info;
3875 struct srvsvc_NetShareInfo502 info502 =
3876 ctr_src.ctr.ctr502->array[i];
3878 /* reset error-code */
3879 nt_status = NT_STATUS_UNSUCCESSFUL;
3881 if (!check_share_sanity(c, cli, info502.name, info502.type))
3884 /* finally add the share on the dst server */
3886 printf(_("migrating: [%s], path: %s, comment: %s, without "
3888 info502.name, info502.path, info502.comment);
3890 info.info502 = &info502;
3892 nt_status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
3893 srvsvc_pipe->desthost,
3898 if (!NT_STATUS_IS_OK(nt_status)) {
3899 printf(_("cannot add share: %s\n"),
3900 nt_errstr(nt_status));
3903 if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3904 printf(_(" [%s] does already exist\n"),
3909 if (!W_ERROR_IS_OK(result)) {
3910 nt_status = werror_to_ntstatus(result);
3911 printf(_("cannot add share: %s\n"),
3912 win_errstr(result));
3918 nt_status = NT_STATUS_OK;
3922 cli_shutdown(cli_dst);
3930 * Migrate shares from a RPC server to another.
3932 * @param argc Standard main() style argc.
3933 * @param argv Standard main() style argv. Initial components are already
3936 * @return A shell status integer (0 for success).
3938 static int rpc_share_migrate_shares(struct net_context *c, int argc,
3941 if (c->display_usage) {
3943 "net rpc share migrate shares\n"
3946 _("Migrate shares to local server"));
3951 printf(_("no server to migrate\n"));
3955 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
3956 rpc_share_migrate_shares_internals,
3963 * @param f file_info
3964 * @param mask current search mask
3965 * @param state arg-pointer
3968 static NTSTATUS copy_fn(const char *mnt, struct file_info *f,
3969 const char *mask, void *state)
3971 static NTSTATUS nt_status;
3972 static struct copy_clistate *local_state;
3973 static fstring filename, new_mask;
3976 struct net_context *c;
3978 local_state = (struct copy_clistate *)state;
3979 nt_status = NT_STATUS_UNSUCCESSFUL;
3983 if (strequal(f->name, ".") || strequal(f->name, ".."))
3984 return NT_STATUS_OK;
3986 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3989 if (f->mode & FILE_ATTRIBUTE_DIRECTORY) {
3991 DEBUG(3,("got dir: %s\n", f->name));
3993 fstrcpy(dir, local_state->cwd);
3995 fstrcat(dir, f->name);
3997 switch (net_mode_share)
3999 case NET_MODE_SHARE_MIGRATE:
4000 /* create that directory */
4001 nt_status = net_copy_file(c, local_state->mem_ctx,
4002 local_state->cli_share_src,
4003 local_state->cli_share_dst,
4005 c->opt_acls? true : false,
4006 c->opt_attrs? true : false,
4007 c->opt_timestamps? true:false,
4011 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
4012 return NT_STATUS_INTERNAL_ERROR;
4015 if (!NT_STATUS_IS_OK(nt_status)) {
4016 printf(_("could not handle dir %s: %s\n"),
4017 dir, nt_errstr(nt_status));
4021 /* search below that directory */
4022 if (strlcpy(new_mask, dir, sizeof(new_mask)) >= sizeof(new_mask)) {
4023 return NT_STATUS_NO_MEMORY;
4025 if (strlcat(new_mask, "\\*", sizeof(new_mask)) >= sizeof(new_mask)) {
4026 return NT_STATUS_NO_MEMORY;
4029 old_dir = local_state->cwd;
4030 local_state->cwd = dir;
4031 nt_status = sync_files(local_state, new_mask);
4032 if (!NT_STATUS_IS_OK(nt_status)) {
4033 printf(_("could not handle files\n"));
4035 local_state->cwd = old_dir;
4042 fstrcpy(filename, local_state->cwd);
4043 fstrcat(filename, "\\");
4044 fstrcat(filename, f->name);
4046 DEBUG(3,("got file: %s\n", filename));
4048 switch (net_mode_share)
4050 case NET_MODE_SHARE_MIGRATE:
4051 nt_status = net_copy_file(c, local_state->mem_ctx,
4052 local_state->cli_share_src,
4053 local_state->cli_share_dst,
4055 c->opt_acls? true : false,
4056 c->opt_attrs? true : false,
4057 c->opt_timestamps? true: false,
4061 d_fprintf(stderr, _("Unsupported file mode %d\n"),
4063 return NT_STATUS_INTERNAL_ERROR;
4066 if (!NT_STATUS_IS_OK(nt_status))
4067 printf(_("could not handle file %s: %s\n"),
4068 filename, nt_errstr(nt_status));
4073 * sync files, can be called recursivly to list files
4074 * and then call copy_fn for each file
4076 * @param cp_clistate pointer to the copy_clistate we work with
4077 * @param mask the current search mask
4079 * @return Boolean result
4081 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask)
4083 struct cli_state *targetcli;
4084 char *targetpath = NULL;
4087 DEBUG(3,("calling cli_list with mask: %s\n", mask));
4089 status = cli_resolve_path(talloc_tos(), "", NULL,
4090 cp_clistate->cli_share_src,
4091 mask, &targetcli, &targetpath);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
4095 mask, nt_errstr(status));
4099 status = cli_list(targetcli, targetpath, cp_clistate->attribute,
4100 copy_fn, cp_clistate);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
4103 mask, nt_errstr(status));
4111 * Set the top level directory permissions before we do any further copies.
4112 * Should set up ACL inheritance.
4115 bool copy_top_level_perms(struct net_context *c,
4116 struct copy_clistate *cp_clistate,
4117 const char *sharename)
4119 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4121 switch (net_mode_share) {
4122 case NET_MODE_SHARE_MIGRATE:
4123 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
4124 nt_status = net_copy_fileattr(c,
4125 cp_clistate->mem_ctx,
4126 cp_clistate->cli_share_src,
4127 cp_clistate->cli_share_dst,
4129 c->opt_acls? true : false,
4130 c->opt_attrs? true : false,
4131 c->opt_timestamps? true: false,
4135 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
4139 if (!NT_STATUS_IS_OK(nt_status)) {
4140 printf(_("Could handle directory attributes for top level "
4141 "directory of share %s. Error %s\n"),
4142 sharename, nt_errstr(nt_status));
4150 * Sync all files inside a remote share to another share (over smb).
4152 * All parameters are provided by the run_rpc_command function, except for
4153 * argc, argv which are passed through.
4155 * @param domain_sid The domain sid acquired from the remote server.
4156 * @param cli A cli_state connected to the server.
4157 * @param mem_ctx Talloc context, destroyed on completion of the function.
4158 * @param argc Standard main() style argc.
4159 * @param argv Standard main() style argv. Initial components are already
4162 * @return Normal NTSTATUS return.
4165 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
4166 const struct dom_sid *domain_sid,
4167 const char *domain_name,
4168 struct cli_state *cli,
4169 struct rpc_pipe_client *pipe_hnd,
4170 TALLOC_CTX *mem_ctx,
4175 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4176 struct srvsvc_NetShareInfoCtr ctr_src;
4178 uint32_t level = 502;
4179 struct copy_clistate cp_clistate;
4180 bool got_src_share = false;
4181 bool got_dst_share = false;
4182 const char *mask = "\\*";
4185 dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
4187 nt_status = NT_STATUS_NO_MEMORY;
4191 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4194 if (!W_ERROR_IS_OK(result))
4197 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4199 struct srvsvc_NetShareInfo502 info502 =
4200 ctr_src.ctr.ctr502->array[i];
4202 if (!check_share_sanity(c, cli, info502.name, info502.type))
4205 /* one might not want to mirror whole discs :) */
4206 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
4207 d_printf(_("skipping [%s]: builtin/hidden share\n"),
4212 switch (net_mode_share)
4214 case NET_MODE_SHARE_MIGRATE:
4218 d_fprintf(stderr, _("Unsupported mode %d\n"),
4222 printf(_(" [%s] files and directories %s ACLs, %s DOS "
4225 c->opt_acls ? _("including") : _("without"),
4226 c->opt_attrs ? _("including") : _("without"),
4227 c->opt_timestamps ? _("(preserving timestamps)") : "");
4229 cp_clistate.mem_ctx = mem_ctx;
4230 cp_clistate.cli_share_src = NULL;
4231 cp_clistate.cli_share_dst = NULL;
4232 cp_clistate.cwd = NULL;
4233 cp_clistate.attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
4236 /* open share source */
4237 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
4238 smbXcli_conn_remote_sockaddr(cli->conn),
4239 smbXcli_conn_remote_name(cli->conn),
4240 info502.name, "A:");
4241 if (!NT_STATUS_IS_OK(nt_status))
4244 got_src_share = true;
4246 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
4247 /* open share destination */
4248 nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
4249 NULL, dst, info502.name, "A:");
4250 if (!NT_STATUS_IS_OK(nt_status))
4253 got_dst_share = true;
4256 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
4257 d_fprintf(stderr, _("Could not handle the top level "
4258 "directory permissions for the "
4259 "share: %s\n"), info502.name);
4260 nt_status = NT_STATUS_UNSUCCESSFUL;
4264 nt_status = sync_files(&cp_clistate, mask);
4265 if (!NT_STATUS_IS_OK(nt_status)) {
4266 d_fprintf(stderr, _("could not handle files for share: "
4267 "%s\n"), info502.name);
4272 nt_status = NT_STATUS_OK;
4277 cli_shutdown(cp_clistate.cli_share_src);
4280 cli_shutdown(cp_clistate.cli_share_dst);
4287 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
4289 if (c->display_usage) {
4291 "net share migrate files\n"
4294 _("Migrate files to local server"));
4299 d_printf(_("no server to migrate\n"));
4303 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4304 rpc_share_migrate_files_internals,
4309 * Migrate share-ACLs from a remote RPC server to the local RPC server.
4311 * All parameters are provided by the run_rpc_command function, except for
4312 * argc, argv which are passed through.
4314 * @param domain_sid The domain sid acquired from the remote server.
4315 * @param cli A cli_state connected to the server.
4316 * @param mem_ctx Talloc context, destroyed on completion of the function.
4317 * @param argc Standard main() style argc.
4318 * @param argv Standard main() style argv. Initial components are already
4321 * @return Normal NTSTATUS return.
4324 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
4325 const struct dom_sid *domain_sid,
4326 const char *domain_name,
4327 struct cli_state *cli,
4328 struct rpc_pipe_client *pipe_hnd,
4329 TALLOC_CTX *mem_ctx,
4334 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4335 struct srvsvc_NetShareInfoCtr ctr_src;
4336 union srvsvc_NetShareInfo info;
4338 struct rpc_pipe_client *srvsvc_pipe = NULL;
4339 struct cli_state *cli_dst = NULL;
4340 uint32_t level = 502; /* includes secdesc */
4341 uint32_t parm_error = 0;
4342 struct dcerpc_binding_handle *b;
4344 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4347 if (!W_ERROR_IS_OK(result))
4350 /* connect destination PI_SRVSVC */
4351 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
4353 if (!NT_STATUS_IS_OK(nt_status))
4356 b = srvsvc_pipe->binding_handle;
4358 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4360 struct srvsvc_NetShareInfo502 info502 =
4361 ctr_src.ctr.ctr502->array[i];
4363 /* reset error-code */
4364 nt_status = NT_STATUS_UNSUCCESSFUL;
4366 if (!check_share_sanity(c, cli, info502.name, info502.type))
4369 printf(_("migrating: [%s], path: %s, comment: %s, including "
4371 info502.name, info502.path, info502.comment);
4374 display_sec_desc(info502.sd_buf.sd);
4376 /* FIXME: shouldn't we be able to just set the security descriptor ? */
4377 info.info502 = &info502;
4379 /* finally modify the share on the dst server */
4380 nt_status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx,
4381 srvsvc_pipe->desthost,
4387 if (!NT_STATUS_IS_OK(nt_status)) {
4388 printf(_("cannot set share-acl: %s\n"),
4389 nt_errstr(nt_status));
4392 if (!W_ERROR_IS_OK(result)) {
4393 nt_status = werror_to_ntstatus(result);
4394 printf(_("cannot set share-acl: %s\n"),
4395 win_errstr(result));
4401 nt_status = NT_STATUS_OK;
4405 cli_shutdown(cli_dst);
4413 * Migrate share-acls from a RPC server to another.
4415 * @param argc Standard main() style argc.
4416 * @param argv Standard main() style argv. Initial components are already
4419 * @return A shell status integer (0 for success).
4421 static int rpc_share_migrate_security(struct net_context *c, int argc,
4424 if (c->display_usage) {
4426 "net rpc share migrate security\n"
4429 _("Migrate share-acls to local server"));
4434 d_printf(_("no server to migrate\n"));
4438 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4439 rpc_share_migrate_security_internals,
4444 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4445 * from one server to another.
4447 * @param argc Standard main() style argc.
4448 * @param argv Standard main() style argv. Initial components are already
4451 * @return A shell status integer (0 for success).
4454 static int rpc_share_migrate_all(struct net_context *c, int argc,
4459 if (c->display_usage) {
4461 "net rpc share migrate all\n"
4464 _("Migrates shares including all share settings"));
4469 d_printf(_("no server to migrate\n"));
4473 /* order is important. we don't want to be locked out by the share-acl
4474 * before copying files - gd */
4476 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4477 rpc_share_migrate_shares_internals, argc, argv);
4481 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4482 rpc_share_migrate_files_internals, argc, argv);
4486 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4487 rpc_share_migrate_security_internals, argc,
4493 * 'net rpc share migrate' entrypoint.
4494 * @param argc Standard main() style argc.
4495 * @param argv Standard main() style argv. Initial components are already
4498 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
4501 struct functable func[] = {
4504 rpc_share_migrate_all,
4506 N_("Migrate shares from remote to local server"),
4507 N_("net rpc share migrate all\n"
4508 " Migrate shares from remote to local server")
4512 rpc_share_migrate_files,
4514 N_("Migrate files from remote to local server"),
4515 N_("net rpc share migrate files\n"
4516 " Migrate files from remote to local server")
4520 rpc_share_migrate_security,
4522 N_("Migrate share-ACLs from remote to local server"),
4523 N_("net rpc share migrate security\n"
4524 " Migrate share-ACLs from remote to local server")
4528 rpc_share_migrate_shares,
4530 N_("Migrate shares from remote to local server"),
4531 N_("net rpc share migrate shares\n"
4532 " Migrate shares from remote to local server")
4534 {NULL, NULL, 0, NULL, NULL}
4537 net_mode_share = NET_MODE_SHARE_MIGRATE;
4539 return net_run_function(c, argc, argv, "net rpc share migrate", func);
4544 uint32_t num_members;
4545 struct dom_sid *members;
4548 static int num_server_aliases;
4549 static struct full_alias *server_aliases;
4552 * Add an alias to the static list.
4554 static void push_alias(struct full_alias *alias)
4558 if (server_aliases == NULL) {
4559 server_aliases = talloc_array(NULL, struct full_alias, 100);
4560 if (server_aliases == NULL) {
4561 smb_panic("talloc_array failed");
4565 array_size = talloc_array_length(server_aliases);
4566 if (array_size == num_server_aliases) {
4567 server_aliases = talloc_realloc(NULL, server_aliases,
4568 struct full_alias, array_size + 100);
4569 if (server_aliases == NULL) {
4570 smb_panic("talloc_realloc failed");
4574 server_aliases[num_server_aliases] = *alias;
4575 num_server_aliases += 1;
4579 * For a specific domain on the server, fetch all the aliases
4580 * and their members. Add all of them to the server_aliases.
4583 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4584 TALLOC_CTX *mem_ctx,
4585 struct policy_handle *connect_pol,
4586 const struct dom_sid *domain_sid)
4588 uint32_t start_idx, max_entries, num_entries, i;
4589 struct samr_SamArray *groups = NULL;
4590 NTSTATUS result, status;
4591 struct policy_handle domain_pol;
4592 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4594 /* Get domain policy handle */
4596 status = dcerpc_samr_OpenDomain(b, mem_ctx,
4598 MAXIMUM_ALLOWED_ACCESS,
4599 discard_const_p(struct dom_sid2, domain_sid),
4602 if (!NT_STATUS_IS_OK(status)) {
4605 if (!NT_STATUS_IS_OK(result)) {
4613 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
4620 if (!NT_STATUS_IS_OK(status)) {
4623 for (i = 0; i < num_entries; i++) {
4625 struct policy_handle alias_pol;
4626 struct full_alias alias;
4627 struct lsa_SidArray sid_array;
4631 status = dcerpc_samr_OpenAlias(b, mem_ctx,
4633 MAXIMUM_ALLOWED_ACCESS,
4634 groups->entries[i].idx,
4637 if (!NT_STATUS_IS_OK(status)) {
4640 if (!NT_STATUS_IS_OK(_result)) {
4645 status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
4649 if (!NT_STATUS_IS_OK(status)) {
4652 if (!NT_STATUS_IS_OK(_result)) {
4657 alias.num_members = sid_array.num_sids;
4659 status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &_result);
4660 if (!NT_STATUS_IS_OK(status)) {
4663 if (!NT_STATUS_IS_OK(_result)) {
4668 alias.members = NULL;
4670 if (alias.num_members > 0) {
4671 alias.members = SMB_MALLOC_ARRAY(struct dom_sid, alias.num_members);
4673 for (j = 0; j < alias.num_members; j++)
4674 sid_copy(&alias.members[j],
4675 sid_array.sids[j].sid);
4678 sid_compose(&alias.sid, domain_sid,
4679 groups->entries[i].idx);
4683 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4685 status = NT_STATUS_OK;
4688 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
4694 * Dump server_aliases as names for debugging purposes.
4697 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4698 const struct dom_sid *domain_sid,
4699 const char *domain_name,
4700 struct cli_state *cli,
4701 struct rpc_pipe_client *pipe_hnd,
4702 TALLOC_CTX *mem_ctx,
4708 struct policy_handle lsa_pol;
4709 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4711 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4712 SEC_FLAG_MAXIMUM_ALLOWED,
4714 if (!NT_STATUS_IS_OK(result))
4717 for (i=0; i<num_server_aliases; i++) {
4720 enum lsa_SidType *types;
4723 struct full_alias *alias = &server_aliases[i];
4725 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4727 &domains, &names, &types);
4728 if (!NT_STATUS_IS_OK(result))
4731 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4733 if (alias->num_members == 0) {
4738 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4741 &domains, &names, &types);
4743 if (!NT_STATUS_IS_OK(result) &&
4744 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4747 for (j=0; j<alias->num_members; j++)
4748 DEBUG(1, ("%s\\%s (%d); ",
4749 domains[j] ? domains[j] : "*unknown*",
4750 names[j] ? names[j] : "*unknown*",types[j]));
4754 dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
4756 return NT_STATUS_OK;
4760 * Fetch a list of all server aliases and their members into
4764 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4765 const struct dom_sid *domain_sid,
4766 const char *domain_name,
4767 struct cli_state *cli,
4768 struct rpc_pipe_client *pipe_hnd,
4769 TALLOC_CTX *mem_ctx,
4773 NTSTATUS result, status;
4774 struct policy_handle connect_pol;
4775 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4777 status = dcerpc_samr_Connect2(b, mem_ctx,
4779 MAXIMUM_ALLOWED_ACCESS,
4782 if (!NT_STATUS_IS_OK(status)) {
4785 if (!NT_STATUS_IS_OK(result)) {
4790 status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4791 &global_sid_Builtin);
4792 if (!NT_STATUS_IS_OK(status)) {
4796 status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4799 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
4804 static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4806 token->num_sids = 4;
4808 if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4809 d_fprintf(stderr, "malloc %s\n",_("failed"));
4810 token->num_sids = 0;
4814 token->sids[0] = *user_sid;
4815 sid_copy(&token->sids[1], &global_sid_World);
4816 sid_copy(&token->sids[2], &global_sid_Network);
4817 sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4820 static void free_user_token(struct security_token *token)
4822 SAFE_FREE(token->sids);
4825 static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4827 if (security_token_has_sid(token, sid))
4830 token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4835 sid_copy(&token->sids[token->num_sids], sid);
4837 token->num_sids += 1;
4842 struct security_token token;
4845 static void dump_user_token(struct user_token *token)
4849 d_printf("%s\n", token->name);
4851 for (i=0; i<token->token.num_sids; i++) {
4852 struct dom_sid_buf buf;
4854 dom_sid_str_buf(&token->token.sids[i], &buf));
4858 static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4862 for (i=0; i<alias->num_members; i++) {
4863 if (dom_sid_equal(sid, &alias->members[i])) {
4871 static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4875 for (i=0; i<num_server_aliases; i++) {
4876 if (is_alias_member(&sid, &server_aliases[i]))
4877 add_sid_to_token(token, &server_aliases[i].sid);
4882 * We got a user token with all the SIDs we can know about without asking the
4883 * server directly. These are the user and domain group sids. All of these can
4884 * be members of aliases. So scan the list of aliases for each of the SIDs and
4885 * add them to the token.
4888 static void collect_alias_memberships(struct security_token *token)
4890 int num_global_sids = token->num_sids;
4893 for (i=0; i<num_global_sids; i++) {
4894 collect_sid_memberships(token, token->sids[i]);
4898 static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4900 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4901 enum wbcSidType type;
4903 struct wbcDomainSid wsid;
4904 char sid_str[WBC_SID_STRING_BUFLEN];
4905 struct dom_sid user_sid;
4906 uint32_t num_groups;
4907 gid_t *groups = NULL;
4910 fstr_sprintf(full_name, "%s%c%s",
4911 domain, *lp_winbind_separator(), user);
4913 /* First let's find out the user sid */
4915 wbc_status = wbcLookupName(domain, user, &wsid, &type);
4917 if (!WBC_ERROR_IS_OK(wbc_status)) {
4918 DEBUG(1, ("winbind could not find %s: %s\n",
4919 full_name, wbcErrorString(wbc_status)));
4923 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4925 if (type != WBC_SID_NAME_USER) {
4926 DEBUG(1, ("%s is not a user\n", full_name));
4930 if (!string_to_sid(&user_sid, sid_str)) {
4931 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4935 init_user_token(token, &user_sid);
4937 /* And now the groups winbind knows about */
4939 wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4940 if (!WBC_ERROR_IS_OK(wbc_status)) {
4941 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4942 full_name, wbcErrorString(wbc_status)));
4946 for (i = 0; i < num_groups; i++) {
4947 gid_t gid = groups[i];
4951 wbc_status = wbcGidToSid(gid, &wsid);
4952 if (!WBC_ERROR_IS_OK(wbc_status)) {
4953 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4954 (unsigned int)gid, wbcErrorString(wbc_status)));
4955 wbcFreeMemory(groups);
4959 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4961 DEBUG(3, (" %s\n", sid_str));
4963 ok = string_to_sid(&sid, sid_str);
4965 DEBUG(1, ("Failed to convert string to SID\n"));
4966 wbcFreeMemory(groups);
4969 add_sid_to_token(token, &sid);
4971 wbcFreeMemory(groups);
4977 * Get a list of all user tokens we want to look at
4980 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4981 struct user_token **user_tokens)
4983 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4984 uint32_t i, num_users;
4986 struct user_token *result;
4987 TALLOC_CTX *frame = NULL;
4989 if (lp_winbind_use_default_domain() &&
4990 (c->opt_target_workgroup == NULL)) {
4991 d_fprintf(stderr, _("winbind use default domain = yes set, "
4992 "please specify a workgroup\n"));
4996 /* Send request to winbind daemon */
4998 wbc_status = wbcListUsers(NULL, &num_users, &users);
4999 if (!WBC_ERROR_IS_OK(wbc_status)) {
5000 DEBUG(1, (_("winbind could not list users: %s\n"),
5001 wbcErrorString(wbc_status)));
5005 result = SMB_MALLOC_ARRAY(struct user_token, num_users);
5007 if (result == NULL) {
5008 DEBUG(1, ("Could not malloc sid array\n"));
5009 wbcFreeMemory(users);
5013 frame = talloc_stackframe();
5014 for (i=0; i < num_users; i++) {
5015 fstring domain, user;
5018 fstrcpy(result[i].name, users[i]);
5020 p = strchr(users[i], *lp_winbind_separator());
5022 DEBUG(3, ("%s\n", users[i]));
5025 fstrcpy(domain, c->opt_target_workgroup);
5026 fstrcpy(user, users[i]);
5029 fstrcpy(domain, users[i]);
5030 if (!strupper_m(domain)) {
5031 DEBUG(1, ("strupper_m %s failed\n", domain));
5032 wbcFreeMemory(users);
5038 get_user_sids(domain, user, &(result[i].token));
5041 wbcFreeMemory(users);
5043 *num_tokens = num_users;
5044 *user_tokens = result;
5049 static bool get_user_tokens_from_file(FILE *f,
5051 struct user_token **tokens)
5053 struct user_token *token = NULL;
5058 if (fgets(line, sizeof(line)-1, f) == NULL) {
5062 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
5063 line[strlen(line)-1] = '\0';
5066 if (line[0] == ' ') {
5070 if(!string_to_sid(&sid, &line[1])) {
5071 DEBUG(1,("get_user_tokens_from_file: Could "
5072 "not convert sid %s \n",&line[1]));
5076 if (token == NULL) {
5077 DEBUG(0, ("File does not begin with username"));
5081 add_sid_to_token(&token->token, &sid);
5085 /* And a new user... */
5088 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
5089 if (*tokens == NULL) {
5090 DEBUG(0, ("Could not realloc tokens\n"));
5094 token = &((*tokens)[*num_tokens-1]);
5096 if (strlcpy(token->name, line, sizeof(token->name)) >= sizeof(token->name)) {
5099 token->token.num_sids = 0;
5100 token->token.sids = NULL;
5109 * Show the list of all users that have access to a share
5112 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
5113 struct cli_state *cli,
5114 TALLOC_CTX *mem_ctx,
5115 const char *netname,
5117 struct user_token *tokens)
5120 struct security_descriptor *share_sd = NULL;
5121 struct security_descriptor *root_sd = NULL;
5123 union srvsvc_NetShareInfo info;
5126 struct smbXcli_tcon *orig_tcon = NULL;
5127 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5129 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5136 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
5137 DEBUG(1, ("Could not query secdesc for share %s\n",
5142 share_sd = info.info502->sd_buf.sd;
5143 if (share_sd == NULL) {
5144 DEBUG(1, ("Got no secdesc for share %s\n",
5148 if (cli_state_has_tcon(cli)) {
5149 orig_tcon = cli_state_save_tcon(cli);
5150 if (orig_tcon == NULL) {
5155 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", NULL))) {
5156 cli_state_restore_tcon(cli, orig_tcon);
5160 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
5161 FILE_SHARE_READ|FILE_SHARE_WRITE,
5162 FILE_OPEN, 0x0, 0x0, &fnum, NULL))) {
5163 cli_query_secdesc(cli, fnum, mem_ctx, &root_sd);
5166 for (i=0; i<num_tokens; i++) {
5167 uint32_t acc_granted;
5169 if (share_sd != NULL) {
5170 status = se_access_check(share_sd, &tokens[i].token,
5173 if (!NT_STATUS_IS_OK(status)) {
5174 DEBUG(1, ("Could not check share_sd for "
5181 if (root_sd == NULL) {
5182 d_printf(" %s\n", tokens[i].name);
5186 status = se_access_check(root_sd, &tokens[i].token,
5188 if (!NT_STATUS_IS_OK(status)) {
5189 DEBUG(1, ("Could not check root_sd for user %s\n",
5193 d_printf(" %s\n", tokens[i].name);
5196 if (fnum != (uint16_t)-1)
5197 cli_close(cli, fnum);
5199 cli_state_restore_tcon(cli, orig_tcon);
5205 * List shares on a remote RPC server, including the security descriptors.
5207 * All parameters are provided by the run_rpc_command function, except for
5208 * argc, argv which are passed through.
5210 * @param domain_sid The domain sid acquired from the remote server.
5211 * @param cli A cli_state connected to the server.
5212 * @param mem_ctx Talloc context, destroyed on completion of the function.
5213 * @param argc Standard main() style argc.
5214 * @param argv Standard main() style argv. Initial components are already
5217 * @return Normal NTSTATUS return.
5220 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
5221 const struct dom_sid *domain_sid,
5222 const char *domain_name,
5223 struct cli_state *cli,
5224 struct rpc_pipe_client *pipe_hnd,
5225 TALLOC_CTX *mem_ctx,
5231 NTSTATUS nt_status = NT_STATUS_OK;
5232 uint32_t total_entries = 0;
5233 uint32_t resume_handle = 0;
5234 uint32_t preferred_len = 0xffffffff;
5236 struct dcerpc_binding_handle *b = NULL;
5237 struct srvsvc_NetShareInfoCtr info_ctr;
5238 struct srvsvc_NetShareCtr1 ctr1;
5241 struct user_token *tokens = NULL;
5247 if (strequal(argv[0], "-")) {
5250 f = fopen(argv[0], "r");
5257 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
5258 return NT_STATUS_UNSUCCESSFUL;
5261 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
5267 DEBUG(0, ("Could not read users from file\n"));
5268 return NT_STATUS_UNSUCCESSFUL;
5271 for (i=0; i<num_tokens; i++)
5272 collect_alias_memberships(&tokens[i].token);
5274 ZERO_STRUCT(info_ctr);
5278 info_ctr.ctr.ctr1 = &ctr1;
5280 b = pipe_hnd->binding_handle;
5283 /* Show results only for shares listed on the command line. */
5285 const char *netname = *argv++;
5286 d_printf("%s\n", netname);
5287 show_userlist(pipe_hnd, cli, mem_ctx, netname,
5288 num_tokens, tokens);
5293 /* Issue the NetShareEnum RPC call and retrieve the response */
5294 nt_status = dcerpc_srvsvc_NetShareEnumAll(b,
5303 /* Was it successful? */
5304 if (!NT_STATUS_IS_OK(nt_status)) {
5305 /* Nope. Go clean up. */
5309 if (!W_ERROR_IS_OK(result)) {
5310 /* Nope. Go clean up. */
5311 nt_status = werror_to_ntstatus(result);
5315 if (total_entries == 0) {
5319 /* For each returned entry... */
5320 for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
5321 const char *netname = info_ctr.ctr.ctr1->array[i].name;
5323 if (info_ctr.ctr.ctr1->array[i].type != STYPE_DISKTREE) {
5327 d_printf("%s\n", netname);
5329 show_userlist(pipe_hnd, cli, mem_ctx, netname,
5330 num_tokens, tokens);
5333 for (i=0; i<num_tokens; i++) {
5334 free_user_token(&tokens[i].token);
5337 TALLOC_FREE(server_aliases);
5342 static int rpc_share_allowedusers(struct net_context *c, int argc,
5347 if (c->display_usage) {
5349 "net rpc share allowedusers\n"
5352 _("List allowed users"));
5356 result = run_rpc_command(c, NULL, &ndr_table_samr, 0,
5357 rpc_aliaslist_internals,
5362 result = run_rpc_command(c, NULL, &ndr_table_lsarpc, 0,
5368 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
5369 rpc_share_allowedusers_internals,
5373 int net_usersidlist(struct net_context *c, int argc, const char **argv)
5376 struct user_token *tokens = NULL;
5380 net_usersidlist_usage(c, argc, argv);
5384 if (!get_user_tokens(c, &num_tokens, &tokens)) {
5385 DEBUG(0, ("Could not get the user/sid list\n"));
5389 for (i=0; i<num_tokens; i++) {
5390 dump_user_token(&tokens[i]);
5391 free_user_token(&tokens[i].token);
5398 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
5400 d_printf(_("net usersidlist\n"
5401 "\tprints out a list of all users the running winbind knows\n"
5402 "\tabout, together with all their SIDs. This is used as\n"
5403 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5405 net_common_flags_usage(c, argc, argv);
5410 * 'net rpc share' entrypoint.
5411 * @param argc Standard main() style argc.
5412 * @param argv Standard main() style argv. Initial components are already
5416 int net_rpc_share(struct net_context *c, int argc, const char **argv)
5418 NET_API_STATUS status;
5420 struct functable func[] = {
5426 N_("net rpc share add\n"
5434 N_("net rpc share delete\n"
5439 rpc_share_allowedusers,
5441 N_("List allowed users"),
5442 N_("net rpc share allowedusers\n"
5443 " List allowed users")
5449 N_("Migrate share to local server"),
5450 N_("net rpc share migrate\n"
5451 " Migrate share to local server")
5458 N_("net rpc share list\n"
5461 {NULL, NULL, 0, NULL, NULL}
5464 status = libnetapi_net_init(&c->netapi_ctx);
5468 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5469 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5470 if (c->opt_kerberos) {
5471 libnetapi_set_use_kerberos(c->netapi_ctx);
5475 if (c->display_usage) {
5480 " Alias for net rpc share list\n"));
5481 net_display_usage_from_functable(func);
5485 return rpc_share_list(c, argc, argv);
5488 return net_run_function(c, argc, argv, "net rpc share", func);
5491 static NTSTATUS rpc_sh_share_list(struct net_context *c,
5492 TALLOC_CTX *mem_ctx,
5493 struct rpc_sh_ctx *ctx,
5494 struct rpc_pipe_client *pipe_hnd,
5495 int argc, const char **argv)
5498 return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
5501 static NTSTATUS rpc_sh_share_add(struct net_context *c,
5502 TALLOC_CTX *mem_ctx,
5503 struct rpc_sh_ctx *ctx,
5504 struct rpc_pipe_client *pipe_hnd,
5505 int argc, const char **argv)
5507 NET_API_STATUS status;
5508 uint32_t parm_err = 0;
5509 struct SHARE_INFO_2 i2;
5511 if ((argc < 2) || (argc > 3)) {
5512 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
5514 return NT_STATUS_INVALID_PARAMETER;
5517 i2.shi2_netname = argv[0];
5518 i2.shi2_type = STYPE_DISKTREE;
5519 i2.shi2_remark = (argc == 3) ? argv[2] : "";
5520 i2.shi2_permissions = 0;
5521 i2.shi2_max_uses = 0;
5522 i2.shi2_current_uses = 0;
5523 i2.shi2_path = argv[1];
5524 i2.shi2_passwd = NULL;
5526 status = NetShareAdd(pipe_hnd->desthost,
5531 return werror_to_ntstatus(W_ERROR(status));
5534 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
5535 TALLOC_CTX *mem_ctx,
5536 struct rpc_sh_ctx *ctx,
5537 struct rpc_pipe_client *pipe_hnd,
5538 int argc, const char **argv)
5541 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5542 return NT_STATUS_INVALID_PARAMETER;
5545 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
5548 static NTSTATUS rpc_sh_share_info(struct net_context *c,
5549 TALLOC_CTX *mem_ctx,
5550 struct rpc_sh_ctx *ctx,
5551 struct rpc_pipe_client *pipe_hnd,
5552 int argc, const char **argv)
5554 union srvsvc_NetShareInfo info;
5557 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5560 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5561 return NT_STATUS_INVALID_PARAMETER;
5564 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5570 if (!NT_STATUS_IS_OK(status)) {
5571 result = ntstatus_to_werror(status);
5574 if (!W_ERROR_IS_OK(result)) {
5578 d_printf(_("Name: %s\n"), info.info2->name);
5579 d_printf(_("Comment: %s\n"), info.info2->comment);
5580 d_printf(_("Path: %s\n"), info.info2->path);
5581 d_printf(_("Password: %s\n"), info.info2->password);
5584 return werror_to_ntstatus(result);
5587 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
5588 struct rpc_sh_ctx *ctx)
5590 static struct rpc_sh_cmd cmds[] = {
5592 { "list", NULL, &ndr_table_srvsvc, rpc_sh_share_list,
5593 N_("List available shares") },
5595 { "add", NULL, &ndr_table_srvsvc, rpc_sh_share_add,
5596 N_("Add a share") },
5598 { "delete", NULL, &ndr_table_srvsvc, rpc_sh_share_delete,
5599 N_("Delete a share") },
5601 { "info", NULL, &ndr_table_srvsvc, rpc_sh_share_info,
5602 N_("Get information about a share") },
5604 { NULL, NULL, 0, NULL, NULL }
5610 /****************************************************************************/
5612 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
5614 return net_file_usage(c, argc, argv);
5618 * Close a file on a remote RPC server.
5620 * @param argc Standard main() style argc.
5621 * @param argv Standard main() style argv. Initial components are already
5624 * @return A shell status integer (0 for success).
5626 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5628 if (argc < 1 || c->display_usage) {
5629 return rpc_file_usage(c, argc, argv);
5632 return NetFileClose(c->opt_host, atoi(argv[0]));
5636 * Formatted print of open file info
5638 * @param r struct FILE_INFO_3 contents
5641 static void display_file_info_3(struct FILE_INFO_3 *r)
5643 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5644 r->fi3_id, r->fi3_username, r->fi3_permissions,
5645 r->fi3_num_locks, r->fi3_pathname);
5649 * List files for a user on a remote RPC server.
5651 * @param argc Standard main() style argc.
5652 * @param argv Standard main() style argv. Initial components are already
5655 * @return A shell status integer (0 for success)..
5658 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5660 NET_API_STATUS status;
5661 uint32_t preferred_len = 0xffffffff, i;
5662 char *username=NULL;
5663 uint32_t total_entries = 0;
5664 uint32_t entries_read = 0;
5665 uint32_t resume_handle = 0;
5666 struct FILE_INFO_3 *i3 = NULL;
5668 if (c->display_usage) {
5669 return rpc_file_usage(c, argc, argv);
5672 /* if argc > 0, must be user command */
5674 username = smb_xstrdup(argv[0]);
5677 status = NetFileEnum(c->opt_host,
5681 (uint8_t **)(void *)&i3,
5691 /* Display results */
5694 "\nEnumerating open files on remote server:\n\n"
5695 "\nFileId Opened by Perms Locks Path"
5696 "\n------ --------- ----- ----- ---- \n"));
5697 for (i = 0; i < entries_read; i++) {
5698 display_file_info_3(&i3[i]);
5701 SAFE_FREE(username);
5706 * 'net rpc file' entrypoint.
5707 * @param argc Standard main() style argc.
5708 * @param argv Standard main() style argv. Initial components are already
5712 int net_rpc_file(struct net_context *c, int argc, const char **argv)
5714 NET_API_STATUS status;
5716 struct functable func[] = {
5721 N_("Close opened file"),
5722 N_("net rpc file close\n"
5723 " Close opened file")
5729 N_("List files opened by user"),
5730 N_("net rpc file user\n"
5731 " List files opened by user")
5738 N_("Display information about opened file"),
5739 N_("net rpc file info\n"
5740 " Display information about opened file")
5743 {NULL, NULL, 0, NULL, NULL}
5746 status = libnetapi_net_init(&c->netapi_ctx);
5750 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5751 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5752 if (c->opt_kerberos) {
5753 libnetapi_set_use_kerberos(c->netapi_ctx);
5757 if (c->display_usage) {
5758 d_printf(_("Usage:\n"));
5759 d_printf(_("net rpc file\n"
5760 " List opened files\n"));
5761 net_display_usage_from_functable(func);
5765 return rpc_file_user(c, argc, argv);
5768 return net_run_function(c, argc, argv, "net rpc file", func);
5772 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5774 * All parameters are provided by the run_rpc_command function, except for
5775 * argc, argv which are passed through.
5777 * @param c A net_context structure.
5778 * @param domain_sid The domain sid acquired from the remote server.
5779 * @param cli A cli_state connected to the server.
5780 * @param mem_ctx Talloc context, destroyed on completion of the function.
5781 * @param argc Standard main() style argc.
5782 * @param argv Standard main() style argv. Initial components are already
5785 * @return Normal NTSTATUS return.
5788 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5789 const struct dom_sid *domain_sid,
5790 const char *domain_name,
5791 struct cli_state *cli,
5792 struct rpc_pipe_client *pipe_hnd,
5793 TALLOC_CTX *mem_ctx,
5797 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5799 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5801 status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5802 if (!NT_STATUS_IS_OK(status)) {
5805 if (W_ERROR_IS_OK(result)) {
5806 d_printf(_("\nShutdown successfully aborted\n"));
5807 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5809 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5811 return werror_to_ntstatus(result);
5815 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5817 * All parameters are provided by the run_rpc_command function, except for
5818 * argc, argv which are passed through.
5820 * @param c A net_context structure.
5821 * @param domain_sid The domain sid acquired from the remote server.
5822 * @param cli A cli_state connected to the server.
5823 * @param mem_ctx Talloc context, destroyed on completion of the function.
5824 * @param argc Standard main() style argc.
5825 * @param argv Standard main() style argv. Initial components are already
5828 * @return Normal NTSTATUS return.
5831 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5832 const struct dom_sid *domain_sid,
5833 const char *domain_name,
5834 struct cli_state *cli,
5835 struct rpc_pipe_client *pipe_hnd,
5836 TALLOC_CTX *mem_ctx,
5840 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5842 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5844 result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5846 if (!NT_STATUS_IS_OK(result)) {
5847 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5850 if (W_ERROR_IS_OK(werr)) {
5851 d_printf(_("\nShutdown successfully aborted\n"));
5852 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5854 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5856 return werror_to_ntstatus(werr);
5860 * ABORT the shutdown of a remote RPC server.
5862 * @param argc Standard main() style argc.
5863 * @param argv Standard main() style argv. Initial components are already
5866 * @return A shell status integer (0 for success).
5869 static int rpc_shutdown_abort(struct net_context *c, int argc,
5874 if (c->display_usage) {
5876 "net rpc abortshutdown\n"
5879 _("Abort a scheduled shutdown"));
5883 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
5884 rpc_shutdown_abort_internals, argc, argv);
5889 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5891 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
5892 rpc_reg_shutdown_abort_internals,
5897 * Shut down a remote RPC Server via initshutdown pipe.
5899 * All parameters are provided by the run_rpc_command function, except for
5900 * argc, argv which are passed through.
5902 * @param c A net_context structure.
5903 * @param domain_sid The domain sid acquired from the remote server.
5904 * @param cli A cli_state connected to the server.
5905 * @param mem_ctx Talloc context, destroyed on completion of the function.
5906 * @param argc Standard main() style argc.
5907 * @param argv Standard main() style argv. Initial components are already
5910 * @return Normal NTSTATUS return.
5913 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5914 const struct dom_sid *domain_sid,
5915 const char *domain_name,
5916 struct cli_state *cli,
5917 struct rpc_pipe_client *pipe_hnd,
5918 TALLOC_CTX *mem_ctx,
5922 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5924 const char *msg = N_("This machine will be shutdown shortly");
5925 uint32_t timeout = 20;
5926 struct lsa_StringLarge msg_string;
5927 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5929 if (c->opt_comment) {
5930 msg = c->opt_comment;
5932 if (c->opt_timeout) {
5933 timeout = c->opt_timeout;
5936 msg_string.string = msg;
5938 /* create an entry */
5939 status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5940 &msg_string, timeout, c->opt_force, c->opt_reboot,
5942 if (!NT_STATUS_IS_OK(status)) {
5945 if (W_ERROR_IS_OK(result)) {
5946 d_printf(_("\nShutdown of remote machine succeeded\n"));
5947 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5949 DEBUG(1,("Shutdown of remote machine failed!\n"));
5951 return werror_to_ntstatus(result);
5955 * Shut down a remote RPC Server via winreg pipe.
5957 * All parameters are provided by the run_rpc_command function, except for
5958 * argc, argv which are passed through.
5960 * @param c A net_context structure.
5961 * @param domain_sid The domain sid acquired from the remote server.
5962 * @param cli A cli_state connected to the server.
5963 * @param mem_ctx Talloc context, destroyed on completion of the function.
5964 * @param argc Standard main() style argc.
5965 * @param argv Standard main() style argv. Initial components are already
5968 * @return Normal NTSTATUS return.
5971 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5972 const struct dom_sid *domain_sid,
5973 const char *domain_name,
5974 struct cli_state *cli,
5975 struct rpc_pipe_client *pipe_hnd,
5976 TALLOC_CTX *mem_ctx,
5980 const char *msg = N_("This machine will be shutdown shortly");
5981 uint32_t timeout = 20;
5982 struct lsa_StringLarge msg_string;
5985 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5987 if (c->opt_comment) {
5988 msg = c->opt_comment;
5990 msg_string.string = msg;
5992 if (c->opt_timeout) {
5993 timeout = c->opt_timeout;
5996 /* create an entry */
5997 result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
5998 &msg_string, timeout, c->opt_force, c->opt_reboot,
6000 if (!NT_STATUS_IS_OK(result)) {
6001 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6005 if (W_ERROR_IS_OK(werr)) {
6006 d_printf(_("\nShutdown of remote machine succeeded\n"));
6008 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6009 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
6010 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
6012 d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
6015 return werror_to_ntstatus(werr);
6019 * Shut down a remote RPC server.
6021 * @param argc Standard main() style argc.
6022 * @param argv Standard main() style argv. Initial components are already
6025 * @return A shell status integer (0 for success).
6028 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
6032 if (c->display_usage) {
6034 "net rpc shutdown\n"
6037 _("Shut down a remote RPC server"));
6041 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
6042 rpc_init_shutdown_internals, argc, argv);
6045 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
6046 rc = run_rpc_command(c, NULL, &ndr_table_winreg, 0,
6047 rpc_reg_shutdown_internals, argc, argv);
6053 /***************************************************************************
6054 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
6055 ***************************************************************************/
6058 * Add interdomain trust account to the RPC server.
6059 * All parameters (except for argc and argv) are passed by run_rpc_command
6062 * @param c A net_context structure.
6063 * @param domain_sid The domain sid acquired from the server.
6064 * @param cli A cli_state connected to the server.
6065 * @param mem_ctx Talloc context, destroyed on completion of the function.
6066 * @param argc Standard main() style argc.
6067 * @param argv Standard main() style argv. Initial components are already
6070 * @return normal NTSTATUS return code.
6073 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
6074 const struct dom_sid *domain_sid,
6075 const char *domain_name,
6076 struct cli_state *cli,
6077 struct rpc_pipe_client *pipe_hnd,
6078 TALLOC_CTX *mem_ctx,
6082 struct policy_handle connect_pol, domain_pol, user_pol;
6083 NTSTATUS status, result;
6085 struct lsa_String lsa_acct_name;
6087 uint32_t acct_flags=0;
6089 uint32_t access_granted = 0;
6090 union samr_UserInfo info;
6091 unsigned int orig_timeout;
6092 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6093 DATA_BLOB session_key = data_blob_null;
6098 _(" net rpc trustdom add <domain_name> "
6099 "<trust password>\n"));
6100 return NT_STATUS_INVALID_PARAMETER;
6104 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6107 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
6108 return NT_STATUS_NO_MEMORY;
6111 if (!strupper_m(acct_name)) {
6112 SAFE_FREE(acct_name);
6113 return NT_STATUS_INVALID_PARAMETER;
6116 init_lsa_String(&lsa_acct_name, acct_name);
6118 status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6119 if (!NT_STATUS_IS_OK(status)) {
6120 DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
6121 nt_errstr(status)));
6125 /* Get samr policy handle */
6126 status = dcerpc_samr_Connect2(b, mem_ctx,
6128 MAXIMUM_ALLOWED_ACCESS,
6131 if (!NT_STATUS_IS_OK(status)) {
6134 if (!NT_STATUS_IS_OK(result)) {
6139 /* Get domain policy handle */
6140 status = dcerpc_samr_OpenDomain(b, mem_ctx,
6142 MAXIMUM_ALLOWED_ACCESS,
6143 discard_const_p(struct dom_sid2, domain_sid),
6146 if (!NT_STATUS_IS_OK(status)) {
6149 if (!NT_STATUS_IS_OK(result)) {
6154 /* This call can take a long time - allow the server to time out.
6155 * 35 seconds should do it. */
6157 orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
6159 /* Create trusting domain's account */
6160 acb_info = ACB_NORMAL;
6161 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
6162 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
6163 SAMR_USER_ACCESS_SET_PASSWORD |
6164 SAMR_USER_ACCESS_GET_ATTRIBUTES |
6165 SAMR_USER_ACCESS_SET_ATTRIBUTES;
6167 status = dcerpc_samr_CreateUser2(b, mem_ctx,
6176 if (!NT_STATUS_IS_OK(status)) {
6179 /* And restore our original timeout. */
6180 rpccli_set_timeout(pipe_hnd, orig_timeout);
6182 if (!NT_STATUS_IS_OK(result)) {
6184 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
6185 acct_name, nt_errstr(result));
6190 struct samr_CryptPassword crypt_pwd;
6192 ZERO_STRUCT(info.info23);
6194 init_samr_CryptPassword(argv[1],
6198 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
6199 SAMR_FIELD_NT_PASSWORD_PRESENT;
6200 info.info23.info.acct_flags = ACB_DOMTRUST;
6201 info.info23.password = crypt_pwd;
6203 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
6208 if (!NT_STATUS_IS_OK(status)) {
6212 if (!NT_STATUS_IS_OK(result)) {
6214 DEBUG(0,("Could not set trust account password: %s\n",
6215 nt_errstr(result)));
6221 SAFE_FREE(acct_name);
6222 data_blob_clear_free(&session_key);
6227 * Create interdomain trust account for a remote domain.
6229 * @param argc Standard argc.
6230 * @param argv Standard argv without initial components.
6232 * @return Integer status (0 means success).
6235 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
6237 if (argc > 0 && !c->display_usage) {
6238 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6239 rpc_trustdom_add_internals, argc, argv);
6243 _("net rpc trustdom add <domain_name> <trust "
6251 * Remove interdomain trust account from the RPC server.
6252 * All parameters (except for argc and argv) are passed by run_rpc_command
6255 * @param c A net_context structure.
6256 * @param domain_sid The domain sid acquired from the server.
6257 * @param cli A cli_state connected to the server.
6258 * @param mem_ctx Talloc context, destroyed on completion of the function.
6259 * @param argc Standard main() style argc.
6260 * @param argv Standard main() style argv. Initial components are already
6263 * @return normal NTSTATUS return code.
6266 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
6267 const struct dom_sid *domain_sid,
6268 const char *domain_name,
6269 struct cli_state *cli,
6270 struct rpc_pipe_client *pipe_hnd,
6271 TALLOC_CTX *mem_ctx,
6275 struct policy_handle connect_pol, domain_pol, user_pol;
6276 NTSTATUS status, result;
6278 struct dom_sid trust_acct_sid;
6279 struct samr_Ids user_rids, name_types;
6280 struct lsa_String lsa_acct_name;
6281 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6286 _(" net rpc trustdom del <domain_name>\n"));
6287 return NT_STATUS_INVALID_PARAMETER;
6291 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6293 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
6295 if (acct_name == NULL)
6296 return NT_STATUS_NO_MEMORY;
6298 if (!strupper_m(acct_name)) {
6299 TALLOC_FREE(acct_name);
6300 return NT_STATUS_INVALID_PARAMETER;
6303 /* Get samr policy handle */
6304 status = dcerpc_samr_Connect2(b, mem_ctx,
6306 MAXIMUM_ALLOWED_ACCESS,
6309 if (!NT_STATUS_IS_OK(status)) {
6312 if (!NT_STATUS_IS_OK(result)) {
6317 /* Get domain policy handle */
6318 status = dcerpc_samr_OpenDomain(b, mem_ctx,
6320 MAXIMUM_ALLOWED_ACCESS,
6321 discard_const_p(struct dom_sid2, domain_sid),
6324 if (!NT_STATUS_IS_OK(status)) {
6327 if (!NT_STATUS_IS_OK(result)) {
6332 init_lsa_String(&lsa_acct_name, acct_name);
6334 status = dcerpc_samr_LookupNames(b, mem_ctx,
6341 if (!NT_STATUS_IS_OK(status)) {
6342 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6344 acct_name, nt_errstr(status));
6347 if (!NT_STATUS_IS_OK(result)) {
6349 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6351 acct_name, nt_errstr(result) );
6354 if (user_rids.count != 1) {
6355 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6358 if (name_types.count != 1) {
6359 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6363 status = dcerpc_samr_OpenUser(b, mem_ctx,
6365 MAXIMUM_ALLOWED_ACCESS,
6369 if (!NT_STATUS_IS_OK(status)) {
6370 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6372 acct_name, nt_errstr(status) );
6376 if (!NT_STATUS_IS_OK(result)) {
6378 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6380 acct_name, nt_errstr(result) );
6384 /* append the rid to the domain sid */
6385 if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
6389 /* remove the sid */
6391 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, mem_ctx,
6395 if (!NT_STATUS_IS_OK(status)) {
6396 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6397 " on user %s failed %s\n"),
6398 acct_name, nt_errstr(status));
6401 if (!NT_STATUS_IS_OK(result)) {
6403 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6404 " on user %s failed %s\n"),
6405 acct_name, nt_errstr(result) );
6412 status = dcerpc_samr_DeleteUser(b, mem_ctx,
6415 if (!NT_STATUS_IS_OK(status)) {
6416 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6418 acct_name, nt_errstr(status));
6422 if (!NT_STATUS_IS_OK(result)) {
6424 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6426 acct_name, nt_errstr(result) );
6430 if (!NT_STATUS_IS_OK(result)) {
6431 d_printf(_("Could not set trust account password: %s\n"),
6441 * Delete interdomain trust account for a remote domain.
6443 * @param argc Standard argc.
6444 * @param argv Standard argv without initial components.
6446 * @return Integer status (0 means success).
6449 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
6451 if (argc > 0 && !c->display_usage) {
6452 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6453 rpc_trustdom_del_internals, argc, argv);
6457 _("net rpc trustdom del <domain>\n"));
6462 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
6463 struct cli_state *cli,
6464 TALLOC_CTX *mem_ctx,
6465 const char *domain_name)
6467 char *dc_name = NULL;
6468 const char *buffer = NULL;
6469 struct rpc_pipe_client *netr;
6472 struct dcerpc_binding_handle *b;
6474 /* Use NetServerEnum2 */
6476 if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
6478 return NT_STATUS_OK;
6481 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6482 for domain %s\n", domain_name));
6484 /* Try netr_GetDcName */
6486 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon,
6488 if (!NT_STATUS_IS_OK(status)) {
6492 b = netr->binding_handle;
6494 status = dcerpc_netr_GetDcName(b, mem_ctx,
6501 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
6505 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6506 for domain %s\n", domain_name));
6508 if (!NT_STATUS_IS_OK(status)) {
6512 return werror_to_ntstatus(result);
6516 * Establish trust relationship to a trusting domain.
6517 * Interdomain account must already be created on remote PDC.
6519 * @param c A net_context structure.
6520 * @param argc Standard argc.
6521 * @param argv Standard argv without initial components.
6523 * @return Integer status (0 means success).
6526 static int rpc_trustdom_establish(struct net_context *c, int argc,
6529 struct cli_state *cli = NULL;
6530 struct sockaddr_storage server_ss;
6531 struct rpc_pipe_client *pipe_hnd = NULL;
6532 struct policy_handle connect_hnd;
6533 TALLOC_CTX *mem_ctx;
6534 NTSTATUS nt_status, result;
6535 struct dom_sid *domain_sid;
6540 union lsa_PolicyInformation *info = NULL;
6541 struct dcerpc_binding_handle *b;
6544 * Connect to \\server\ipc$ as 'our domain' account with password
6547 if (argc != 1 || c->display_usage) {
6550 _("net rpc trustdom establish <domain_name>\n"));
6554 domain_name = smb_xstrdup(argv[0]);
6555 if (!strupper_m(domain_name)) {
6556 SAFE_FREE(domain_name);
6560 /* account name used at first is our domain's name with '$' */
6561 if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
6564 if (!strupper_m(acct_name)) {
6565 SAFE_FREE(domain_name);
6566 SAFE_FREE(acct_name);
6571 * opt_workgroup will be used by connection functions further,
6572 * hence it should be set to remote domain name instead of ours
6574 if (c->opt_workgroup) {
6575 c->opt_workgroup = smb_xstrdup(domain_name);
6578 c->opt_user_name = acct_name;
6580 /* find the domain controller */
6581 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
6582 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
6586 /* connect to ipc$ as username/password */
6587 nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
6588 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
6590 /* Is it trusting domain account for sure ? */
6591 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6592 nt_errstr(nt_status)));
6596 /* store who we connected to */
6598 saf_store( domain_name, pdc_name );
6601 * Connect to \\server\ipc$ again (this time anonymously)
6604 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
6607 if (NT_STATUS_IS_ERR(nt_status)) {
6608 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6609 domain_name, nt_errstr(nt_status)));
6613 if (!(mem_ctx = talloc_init("establishing trust relationship to "
6614 "domain %s", domain_name))) {
6615 DEBUG(0, ("talloc_init() failed\n"));
6620 /* Make sure we're talking to a proper server */
6622 nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
6623 if (!NT_STATUS_IS_OK(nt_status)) {
6625 talloc_destroy(mem_ctx);
6630 * Call LsaOpenPolicy and LsaQueryInfo
6633 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6635 if (!NT_STATUS_IS_OK(nt_status)) {
6636 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
6638 talloc_destroy(mem_ctx);
6642 b = pipe_hnd->binding_handle;
6644 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
6646 if (NT_STATUS_IS_ERR(nt_status)) {
6647 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6648 nt_errstr(nt_status)));
6650 talloc_destroy(mem_ctx);
6654 /* Querying info level 5 */
6656 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6658 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6661 if (NT_STATUS_IS_ERR(nt_status)) {
6662 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6663 nt_errstr(nt_status)));
6665 talloc_destroy(mem_ctx);
6668 if (NT_STATUS_IS_ERR(result)) {
6669 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6670 nt_errstr(result)));
6672 talloc_destroy(mem_ctx);
6676 domain_sid = info->account_domain.sid;
6678 /* There should be actually query info level 3 (following nt serv behaviour),
6679 but I still don't know if it's _really_ necessary */
6682 * Store the password in secrets db
6685 if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
6686 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6688 talloc_destroy(mem_ctx);
6693 * Close the pipes and clean up
6696 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6697 if (NT_STATUS_IS_ERR(nt_status)) {
6698 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6699 nt_errstr(nt_status)));
6701 talloc_destroy(mem_ctx);
6707 talloc_destroy(mem_ctx);
6709 d_printf(_("Trust to domain %s established\n"), domain_name);
6714 * Revoke trust relationship to the remote domain.
6716 * @param c A net_context structure.
6717 * @param argc Standard argc.
6718 * @param argv Standard argv without initial components.
6720 * @return Integer status (0 means success).
6723 static int rpc_trustdom_revoke(struct net_context *c, int argc,
6729 if (argc < 1 || c->display_usage) {
6732 _("net rpc trustdom revoke <domain_name>\n"
6733 " Revoke trust relationship\n"
6734 " domain_name\tName of domain to revoke trust\n"));
6738 /* generate upper cased domain name */
6739 domain_name = smb_xstrdup(argv[0]);
6740 if (!strupper_m(domain_name)) {
6741 SAFE_FREE(domain_name);
6745 /* delete password of the trust */
6746 if (!pdb_del_trusteddom_pw(domain_name)) {
6747 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6754 SAFE_FREE(domain_name);
6758 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6759 const struct dom_sid *domain_sid,
6760 const char *domain_name,
6761 struct cli_state *cli,
6762 struct rpc_pipe_client *pipe_hnd,
6763 TALLOC_CTX *mem_ctx,
6767 struct dom_sid_buf sid_str;
6768 d_printf("%s\n", dom_sid_str_buf(domain_sid, &sid_str));
6769 return NT_STATUS_OK;
6772 static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6774 struct dom_sid_buf sid_str;
6776 d_printf("%-20s%s\n",
6778 dom_sid_str_buf(dom_sid, &sid_str));
6781 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6782 TALLOC_CTX *mem_ctx,
6783 struct policy_handle *pol,
6784 struct dom_sid dom_sid,
6785 const char *trusted_dom_name)
6787 NTSTATUS nt_status, result;
6788 union lsa_TrustedDomainInfo *info = NULL;
6789 char *cleartextpwd = NULL;
6790 DATA_BLOB session_key;
6791 DATA_BLOB data = data_blob_null;
6792 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6794 nt_status = dcerpc_lsa_QueryTrustedDomainInfoBySid(b, mem_ctx,
6797 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6800 if (NT_STATUS_IS_ERR(nt_status)) {
6801 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6802 nt_errstr(nt_status)));
6805 if (NT_STATUS_IS_ERR(result)) {
6807 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6808 nt_errstr(result)));
6812 data = data_blob(info->password.password->data,
6813 info->password.password->length);
6815 nt_status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6816 if (!NT_STATUS_IS_OK(nt_status)) {
6817 DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status)));
6821 cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key);
6822 data_blob_free(&session_key);
6824 if (cleartextpwd == NULL) {
6825 DEBUG(0,("retrieved NULL password\n"));
6826 nt_status = NT_STATUS_UNSUCCESSFUL;
6830 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6831 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6832 nt_status = NT_STATUS_UNSUCCESSFUL;
6836 #ifdef DEBUG_PASSWORD
6838 struct dom_sid_buf buf;
6839 DEBUG(100,("successfully vampired trusted domain [%s], "
6840 "sid: [%s], password: [%s]\n",
6842 dom_sid_str_buf(&dom_sid, &buf),
6848 SAFE_FREE(cleartextpwd);
6849 data_blob_free(&data);
6854 static int rpc_trustdom_vampire(struct net_context *c, int argc,
6857 /* common variables */
6858 TALLOC_CTX* mem_ctx;
6859 struct cli_state *cli = NULL;
6860 struct rpc_pipe_client *pipe_hnd = NULL;
6861 NTSTATUS nt_status, result;
6862 const char *domain_name = NULL;
6863 struct policy_handle connect_hnd;
6864 union lsa_PolicyInformation *info = NULL;
6866 /* trusted domains listing variables */
6867 unsigned int enum_ctx = 0;
6869 struct lsa_DomainList dom_list;
6871 struct dcerpc_binding_handle *b;
6873 if (c->display_usage) {
6875 "net rpc trustdom vampire\n"
6878 _("Vampire trust relationship from remote server"));
6883 * Listing trusted domains (stored in secrets.tdb, if local)
6886 mem_ctx = talloc_init("trust relationships vampire");
6889 * set domain and pdc name to local samba server (default)
6890 * or to remote one given in command line
6893 if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
6894 domain_name = c->opt_workgroup;
6895 c->opt_target_workgroup = c->opt_workgroup;
6897 fstrcpy(pdc_name, lp_netbios_name());
6898 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6899 c->opt_target_workgroup = domain_name;
6902 /* open \PIPE\lsarpc and open policy handle */
6903 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6904 if (!NT_STATUS_IS_OK(nt_status)) {
6905 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6906 nt_errstr(nt_status)));
6907 talloc_destroy(mem_ctx);
6911 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6913 if (!NT_STATUS_IS_OK(nt_status)) {
6914 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6915 nt_errstr(nt_status) ));
6917 talloc_destroy(mem_ctx);
6921 b = pipe_hnd->binding_handle;
6923 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6925 if (NT_STATUS_IS_ERR(nt_status)) {
6926 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6927 nt_errstr(nt_status)));
6929 talloc_destroy(mem_ctx);
6933 /* query info level 5 to obtain sid of a domain being queried */
6934 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6936 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6940 if (NT_STATUS_IS_ERR(nt_status)) {
6941 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6942 nt_errstr(nt_status)));
6944 talloc_destroy(mem_ctx);
6947 if (NT_STATUS_IS_ERR(result)) {
6948 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6949 nt_errstr(result)));
6951 talloc_destroy(mem_ctx);
6956 * Keep calling LsaEnumTrustdom over opened pipe until
6957 * the end of enumeration is reached
6960 d_printf(_("Vampire trusted domains:\n\n"));
6963 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6969 if (NT_STATUS_IS_ERR(nt_status)) {
6970 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6971 nt_errstr(nt_status)));
6973 talloc_destroy(mem_ctx);
6976 if (NT_STATUS_IS_ERR(result)) {
6978 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6979 nt_errstr(result)));
6981 talloc_destroy(mem_ctx);
6986 for (i = 0; i < dom_list.count; i++) {
6988 print_trusted_domain(dom_list.domains[i].sid,
6989 dom_list.domains[i].name.string);
6991 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6992 *dom_list.domains[i].sid,
6993 dom_list.domains[i].name.string);
6994 if (!NT_STATUS_IS_OK(nt_status)) {
6996 talloc_destroy(mem_ctx);
7002 * in case of no trusted domains say something rather
7003 * than just display blank line
7005 if (!dom_list.count) d_printf(_("none\n"));
7007 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7009 /* close this connection before doing next one */
7010 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7011 if (NT_STATUS_IS_ERR(nt_status)) {
7012 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7013 nt_errstr(nt_status)));
7015 talloc_destroy(mem_ctx);
7019 /* close lsarpc pipe and connection to IPC$ */
7022 talloc_destroy(mem_ctx);
7026 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
7028 /* common variables */
7029 TALLOC_CTX* mem_ctx;
7030 struct cli_state *cli = NULL, *remote_cli = NULL;
7031 struct rpc_pipe_client *pipe_hnd = NULL;
7032 NTSTATUS nt_status, result;
7033 const char *domain_name = NULL;
7034 struct dom_sid *queried_dom_sid;
7035 int ascii_dom_name_len;
7036 struct policy_handle connect_hnd;
7037 union lsa_PolicyInformation *info = NULL;
7038 struct dcerpc_binding_handle *b = NULL;
7040 /* trusted domains listing variables */
7041 unsigned int num_domains, enum_ctx = 0;
7043 struct lsa_DomainList dom_list;
7047 /* trusting domains listing variables */
7048 struct policy_handle domain_hnd;
7049 struct samr_SamArray *trusts = NULL;
7051 if (c->display_usage) {
7053 "net rpc trustdom list\n"
7056 _("List incoming and outgoing trust relationships"));
7061 * Listing trusted domains (stored in secrets.tdb, if local)
7064 mem_ctx = talloc_init("trust relationships listing");
7067 * set domain and pdc name to local samba server (default)
7068 * or to remote one given in command line
7071 if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
7072 domain_name = c->opt_workgroup;
7073 c->opt_target_workgroup = c->opt_workgroup;
7075 fstrcpy(pdc_name, lp_netbios_name());
7076 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
7077 c->opt_target_workgroup = domain_name;
7080 /* open \PIPE\lsarpc and open policy handle */
7081 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
7082 if (!NT_STATUS_IS_OK(nt_status)) {
7083 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
7084 nt_errstr(nt_status)));
7085 talloc_destroy(mem_ctx);
7089 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
7091 if (!NT_STATUS_IS_OK(nt_status)) {
7092 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
7093 nt_errstr(nt_status) ));
7095 talloc_destroy(mem_ctx);
7099 b = pipe_hnd->binding_handle;
7101 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
7103 if (NT_STATUS_IS_ERR(nt_status)) {
7104 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
7105 nt_errstr(nt_status)));
7107 talloc_destroy(mem_ctx);
7111 /* query info level 5 to obtain sid of a domain being queried */
7112 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
7114 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
7118 if (NT_STATUS_IS_ERR(nt_status)) {
7119 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7120 nt_errstr(nt_status)));
7122 talloc_destroy(mem_ctx);
7125 if (NT_STATUS_IS_ERR(result)) {
7126 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7127 nt_errstr(result)));
7129 talloc_destroy(mem_ctx);
7133 queried_dom_sid = info->account_domain.sid;
7136 * Keep calling LsaEnumTrustdom over opened pipe until
7137 * the end of enumeration is reached
7140 d_printf(_("Trusted domains list:\n\n"));
7142 found_domain = false;
7145 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
7151 if (NT_STATUS_IS_ERR(nt_status)) {
7152 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7153 nt_errstr(nt_status)));
7155 talloc_destroy(mem_ctx);
7158 if (NT_STATUS_IS_ERR(result)) {
7159 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7160 nt_errstr(result)));
7162 talloc_destroy(mem_ctx);
7167 for (i = 0; i < dom_list.count; i++) {
7168 print_trusted_domain(dom_list.domains[i].sid,
7169 dom_list.domains[i].name.string);
7170 found_domain = true;
7174 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7177 * in case of no trusted domains say something rather
7178 * than just display blank line
7180 if (!found_domain) {
7181 d_printf(_("none\n"));
7184 /* close this connection before doing next one */
7185 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7186 if (NT_STATUS_IS_ERR(nt_status)) {
7187 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7188 nt_errstr(nt_status)));
7190 talloc_destroy(mem_ctx);
7194 TALLOC_FREE(pipe_hnd);
7197 * Listing trusting domains (stored in passdb backend, if local)
7200 d_printf(_("\nTrusting domains list:\n\n"));
7203 * Open \PIPE\samr and get needed policy handles
7205 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr,
7207 if (!NT_STATUS_IS_OK(nt_status)) {
7208 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
7210 talloc_destroy(mem_ctx);
7214 b = pipe_hnd->binding_handle;
7217 nt_status = dcerpc_samr_Connect2(b, mem_ctx,
7219 SAMR_ACCESS_LOOKUP_DOMAIN,
7222 if (!NT_STATUS_IS_OK(nt_status)) {
7223 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7224 nt_errstr(nt_status)));
7226 talloc_destroy(mem_ctx);
7229 if (!NT_STATUS_IS_OK(result)) {
7231 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7232 nt_errstr(result)));
7234 talloc_destroy(mem_ctx);
7238 /* SamrOpenDomain - we have to open domain policy handle in order to be
7239 able to enumerate accounts*/
7240 nt_status = dcerpc_samr_OpenDomain(b, mem_ctx,
7242 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
7246 if (!NT_STATUS_IS_OK(nt_status)) {
7247 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7248 nt_errstr(nt_status)));
7250 talloc_destroy(mem_ctx);
7253 if (!NT_STATUS_IS_OK(result)) {
7255 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7256 nt_errstr(result)));
7258 talloc_destroy(mem_ctx);
7263 * perform actual enumeration
7266 found_domain = false;
7268 enum_ctx = 0; /* reset enumeration context from last enumeration */
7271 nt_status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
7279 if (NT_STATUS_IS_ERR(nt_status)) {
7280 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7281 nt_errstr(nt_status)));
7283 talloc_destroy(mem_ctx);
7286 if (NT_STATUS_IS_ERR(result)) {
7288 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7289 nt_errstr(result)));
7291 talloc_destroy(mem_ctx);
7295 for (i = 0; i < num_domains; i++) {
7297 char *str = discard_const_p(char, trusts->entries[i].name.string);
7299 found_domain = true;
7302 * get each single domain's sid (do we _really_ need this ?):
7303 * 1) connect to domain's pdc
7304 * 2) query the pdc for domain's sid
7307 /* get rid of '$' tail */
7308 ascii_dom_name_len = strlen(str);
7309 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
7310 str[ascii_dom_name_len - 1] = '\0';
7312 /* set opt_* variables to remote domain */
7313 if (!strupper_m(str)) {
7315 talloc_destroy(mem_ctx);
7318 c->opt_workgroup = talloc_strdup(mem_ctx, str);
7319 c->opt_target_workgroup = c->opt_workgroup;
7321 d_printf("%-20s", str);
7323 /* connect to remote domain controller */
7324 nt_status = net_make_ipc_connection(c,
7325 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
7327 if (NT_STATUS_IS_OK(nt_status)) {
7328 /* query for domain's sid */
7329 if (run_rpc_command(
7331 &ndr_table_lsarpc, 0,
7332 rpc_query_domain_sid, argc,
7334 d_printf(_("strange - couldn't get domain's sid\n"));
7336 cli_shutdown(remote_cli);
7339 d_fprintf(stderr, _("domain controller is not "
7340 "responding: %s\n"),
7341 nt_errstr(nt_status));
7342 d_printf(_("couldn't get domain's sid\n"));
7346 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
7348 if (!found_domain) {
7352 /* close opened samr and domain policy handles */
7353 nt_status = dcerpc_samr_Close(b, mem_ctx, &domain_hnd, &result);
7354 if (!NT_STATUS_IS_OK(nt_status)) {
7355 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
7358 nt_status = dcerpc_samr_Close(b, mem_ctx, &connect_hnd, &result);
7359 if (!NT_STATUS_IS_OK(nt_status)) {
7360 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
7363 /* close samr pipe and connection to IPC$ */
7366 talloc_destroy(mem_ctx);
7371 * Entrypoint for 'net rpc trustdom' code.
7373 * @param argc Standard argc.
7374 * @param argv Standard argv without initial components.
7376 * @return Integer status (0 means success).
7379 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
7381 struct functable func[] = {
7386 N_("Add trusting domain's account"),
7387 N_("net rpc trustdom add\n"
7388 " Add trusting domain's account")
7394 N_("Remove trusting domain's account"),
7395 N_("net rpc trustdom del\n"
7396 " Remove trusting domain's account")
7400 rpc_trustdom_establish,
7402 N_("Establish outgoing trust relationship"),
7403 N_("net rpc trustdom establish\n"
7404 " Establish outgoing trust relationship")
7408 rpc_trustdom_revoke,
7410 N_("Revoke outgoing trust relationship"),
7411 N_("net rpc trustdom revoke\n"
7412 " Revoke outgoing trust relationship")
7418 N_("List in- and outgoing domain trusts"),
7419 N_("net rpc trustdom list\n"
7420 " List in- and outgoing domain trusts")
7424 rpc_trustdom_vampire,
7426 N_("Vampire trusts from remote server"),
7427 N_("net rpc trustdom vampire\n"
7428 " Vampire trusts from remote server")
7430 {NULL, NULL, 0, NULL, NULL}
7433 return net_run_function(c, argc, argv, "net rpc trustdom", func);
7437 * Check if a server will take rpc commands
7438 * @param flags Type of server to connect to (PDC, DMB, localhost)
7439 * if the host is not explicitly specified
7440 * @return bool (true means rpc supported)
7442 bool net_rpc_check(struct net_context *c, unsigned flags)
7444 struct cli_state *cli;
7446 struct sockaddr_storage server_ss;
7447 char *server_name = NULL;
7450 /* flags (i.e. server type) may depend on command */
7451 if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
7454 status = cli_connect_nb(server_name, &server_ss, 0, 0x20,
7455 lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT,
7457 if (!NT_STATUS_IS_OK(status)) {
7460 status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
7462 if (!NT_STATUS_IS_OK(status))
7464 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1)
7473 /* syncronise sam database via samsync rpc calls */
7474 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
7476 struct functable func[] = {
7481 N_("Dump remote SAM database to Kerberos Keytab"),
7482 N_("net rpc vampire keytab\n"
7483 " Dump remote SAM database to Kerberos keytab "
7490 N_("Dump remote SAM database to passdb"),
7491 N_("net rpc vampire passdb\n"
7492 " Dump remote SAM database to passdb")
7495 {NULL, NULL, 0, NULL, NULL}
7499 if (c->display_usage) {
7504 _("Vampire remote SAM database"));
7508 return rpc_vampire_passdb(c, argc, argv);
7511 return net_run_function(c, argc, argv, "net rpc vampire", func);
7515 * Migrate everything from a print server.
7517 * @param c A net_context structure.
7518 * @param argc Standard main() style argc.
7519 * @param argv Standard main() style argv. Initial components are already
7522 * @return A shell status integer (0 for success).
7524 * The order is important !
7525 * To successfully add drivers the print queues have to exist !
7526 * Applying ACLs should be the last step, because you're easily locked out.
7529 static int rpc_printer_migrate_all(struct net_context *c, int argc,
7534 if (c->display_usage) {
7536 "net rpc printer migrate all\n"
7539 _("Migrate everything from a print server"));
7544 d_printf(_("no server to migrate\n"));
7548 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7549 rpc_printer_migrate_printers_internals, argc,
7554 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7555 rpc_printer_migrate_drivers_internals, argc,
7560 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7561 rpc_printer_migrate_forms_internals, argc, argv);
7565 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7566 rpc_printer_migrate_settings_internals, argc,
7571 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7572 rpc_printer_migrate_security_internals, argc,
7578 * Migrate print drivers from a print server.
7580 * @param c A net_context structure.
7581 * @param argc Standard main() style argc.
7582 * @param argv Standard main() style argv. Initial components are already
7585 * @return A shell status integer (0 for success).
7587 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
7590 if (c->display_usage) {
7592 "net rpc printer migrate drivers\n"
7595 _("Migrate print-drivers from a print-server"));
7600 d_printf(_("no server to migrate\n"));
7604 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7605 rpc_printer_migrate_drivers_internals,
7610 * Migrate print-forms from a print-server.
7612 * @param c A net_context structure.
7613 * @param argc Standard main() style argc.
7614 * @param argv Standard main() style argv. Initial components are already
7617 * @return A shell status integer (0 for success).
7619 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
7622 if (c->display_usage) {
7624 "net rpc printer migrate forms\n"
7627 _("Migrate print-forms from a print-server"));
7632 d_printf(_("no server to migrate\n"));
7636 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7637 rpc_printer_migrate_forms_internals,
7642 * Migrate printers from a print-server.
7644 * @param c A net_context structure.
7645 * @param argc Standard main() style argc.
7646 * @param argv Standard main() style argv. Initial components are already
7649 * @return A shell status integer (0 for success).
7651 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
7654 if (c->display_usage) {
7656 "net rpc printer migrate printers\n"
7659 _("Migrate printers from a print-server"));
7664 d_printf(_("no server to migrate\n"));
7668 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7669 rpc_printer_migrate_printers_internals,
7674 * Migrate printer-ACLs from a print-server
7676 * @param c A net_context structure.
7677 * @param argc Standard main() style argc.
7678 * @param argv Standard main() style argv. Initial components are already
7681 * @return A shell status integer (0 for success).
7683 static int rpc_printer_migrate_security(struct net_context *c, int argc,
7686 if (c->display_usage) {
7688 "net rpc printer migrate security\n"
7691 _("Migrate printer-ACLs from a print-server"));
7696 d_printf(_("no server to migrate\n"));
7700 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7701 rpc_printer_migrate_security_internals,
7706 * Migrate printer-settings from a print-server.
7708 * @param c A net_context structure.
7709 * @param argc Standard main() style argc.
7710 * @param argv Standard main() style argv. Initial components are already
7713 * @return A shell status integer (0 for success).
7715 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
7718 if (c->display_usage) {
7720 "net rpc printer migrate settings\n"
7723 _("Migrate printer-settings from a "
7729 d_printf(_("no server to migrate\n"));
7733 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7734 rpc_printer_migrate_settings_internals,
7739 * 'net rpc printer' entrypoint.
7741 * @param c A net_context structure.
7742 * @param argc Standard main() style argc.
7743 * @param argv Standard main() style argv. Initial components are already
7747 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
7750 /* ouch: when addriver and setdriver are called from within
7751 rpc_printer_migrate_drivers_internals, the printer-queue already
7754 struct functable func[] = {
7757 rpc_printer_migrate_all,
7759 N_("Migrate all from remote to local print server"),
7760 N_("net rpc printer migrate all\n"
7761 " Migrate all from remote to local print server")
7765 rpc_printer_migrate_drivers,
7767 N_("Migrate drivers to local server"),
7768 N_("net rpc printer migrate drivers\n"
7769 " Migrate drivers to local server")
7773 rpc_printer_migrate_forms,
7775 N_("Migrate froms to local server"),
7776 N_("net rpc printer migrate forms\n"
7777 " Migrate froms to local server")
7781 rpc_printer_migrate_printers,
7783 N_("Migrate printers to local server"),
7784 N_("net rpc printer migrate printers\n"
7785 " Migrate printers to local server")
7789 rpc_printer_migrate_security,
7791 N_("Mirgate printer ACLs to local server"),
7792 N_("net rpc printer migrate security\n"
7793 " Mirgate printer ACLs to local server")
7797 rpc_printer_migrate_settings,
7799 N_("Migrate printer settings to local server"),
7800 N_("net rpc printer migrate settings\n"
7801 " Migrate printer settings to local server")
7803 {NULL, NULL, 0, NULL, NULL}
7806 return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7811 * List printers on a remote RPC server.
7813 * @param c A net_context structure.
7814 * @param argc Standard main() style argc.
7815 * @param argv Standard main() style argv. Initial components are already
7818 * @return A shell status integer (0 for success).
7820 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7822 if (c->display_usage) {
7824 "net rpc printer list\n"
7827 _("List printers on a remote RPC server"));
7831 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7832 rpc_printer_list_internals,
7837 * List printer-drivers on a remote RPC server.
7839 * @param c A net_context structure.
7840 * @param argc Standard main() style argc.
7841 * @param argv Standard main() style argv. Initial components are already
7844 * @return A shell status integer (0 for success).
7846 static int rpc_printer_driver_list(struct net_context *c, int argc,
7849 if (c->display_usage) {
7851 "net rpc printer driver\n"
7854 _("List printer-drivers on a remote RPC server"));
7858 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7859 rpc_printer_driver_list_internals,
7864 * Publish printer in ADS via MSRPC.
7866 * @param c A net_context structure.
7867 * @param argc Standard main() style argc.
7868 * @param argv Standard main() style argv. Initial components are already
7871 * @return A shell status integer (0 for success).
7873 static int rpc_printer_publish_publish(struct net_context *c, int argc,
7876 if (c->display_usage) {
7878 "net rpc printer publish publish\n"
7881 _("Publish printer in ADS via MSRPC"));
7885 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7886 rpc_printer_publish_publish_internals,
7891 * Update printer in ADS via MSRPC.
7893 * @param c A net_context structure.
7894 * @param argc Standard main() style argc.
7895 * @param argv Standard main() style argv. Initial components are already
7898 * @return A shell status integer (0 for success).
7900 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7902 if (c->display_usage) {
7904 "net rpc printer publish update\n"
7907 _("Update printer in ADS via MSRPC"));
7911 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7912 rpc_printer_publish_update_internals,
7917 * UnPublish printer in ADS via MSRPC.
7919 * @param c A net_context structure.
7920 * @param argc Standard main() style argc.
7921 * @param argv Standard main() style argv. Initial components are already
7924 * @return A shell status integer (0 for success).
7926 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7929 if (c->display_usage) {
7931 "net rpc printer publish unpublish\n"
7934 _("UnPublish printer in ADS via MSRPC"));
7938 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7939 rpc_printer_publish_unpublish_internals,
7944 * List published printers via MSRPC.
7946 * @param c A net_context structure.
7947 * @param argc Standard main() style argc.
7948 * @param argv Standard main() style argv. Initial components are already
7951 * @return A shell status integer (0 for success).
7953 static int rpc_printer_publish_list(struct net_context *c, int argc,
7956 if (c->display_usage) {
7958 "net rpc printer publish list\n"
7961 _("List published printers via MSRPC"));
7965 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7966 rpc_printer_publish_list_internals,
7972 * Publish printer in ADS.
7974 * @param c A net_context structure.
7975 * @param argc Standard main() style argc.
7976 * @param argv Standard main() style argv. Initial components are already
7979 * @return A shell status integer (0 for success).
7981 static int rpc_printer_publish(struct net_context *c, int argc,
7985 struct functable func[] = {
7988 rpc_printer_publish_publish,
7990 N_("Publish printer in AD"),
7991 N_("net rpc printer publish publish\n"
7992 " Publish printer in AD")
7996 rpc_printer_publish_update,
7998 N_("Update printer in AD"),
7999 N_("net rpc printer publish update\n"
8000 " Update printer in AD")
8004 rpc_printer_publish_unpublish,
8006 N_("Unpublish printer"),
8007 N_("net rpc printer publish unpublish\n"
8008 " Unpublish printer")
8012 rpc_printer_publish_list,
8014 N_("List published printers"),
8015 N_("net rpc printer publish list\n"
8016 " List published printers")
8018 {NULL, NULL, 0, NULL, NULL}
8022 if (c->display_usage) {
8023 d_printf(_("Usage:\n"));
8024 d_printf(_("net rpc printer publish\n"
8025 " List published printers\n"
8026 " Alias of net rpc printer publish "
8028 net_display_usage_from_functable(func);
8031 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8032 rpc_printer_publish_list_internals,
8036 return net_run_function(c, argc, argv, "net rpc printer publish",func);
8042 * Display rpc printer help page.
8044 * @param c A net_context structure.
8045 * @param argc Standard main() style argc.
8046 * @param argv Standard main() style argv. Initial components are already
8049 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
8051 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
8052 "\tlists all printers on print-server\n\n"));
8053 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
8054 "\tlists all printer-drivers on print-server\n\n"));
8055 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
8056 "\tpublishes printer settings in Active Directory\n"
8057 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
8058 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
8059 "\n\tmigrates printers from remote to local server\n\n"));
8060 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
8061 "\n\tmigrates printer-settings from remote to local server\n\n"));
8062 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
8063 "\n\tmigrates printer-drivers from remote to local server\n\n"));
8064 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
8065 "\n\tmigrates printer-forms from remote to local server\n\n"));
8066 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
8067 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
8068 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
8069 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
8070 "\tremote to local print-server\n\n"));
8071 net_common_methods_usage(c, argc, argv);
8072 net_common_flags_usage(c, argc, argv);
8074 "\t-v or --verbose\t\t\tgive verbose output\n"
8075 "\t --destination\t\tmigration target server (default: localhost)\n"));
8081 * 'net rpc printer' entrypoint.
8083 * @param c A net_context structure.
8084 * @param argc Standard main() style argc.
8085 * @param argv Standard main() style argv. Initial components are already
8088 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
8090 struct functable func[] = {
8095 N_("List all printers on print server"),
8096 N_("net rpc printer list\n"
8097 " List all printers on print server")
8101 rpc_printer_migrate,
8103 N_("Migrate printer to local server"),
8104 N_("net rpc printer migrate\n"
8105 " Migrate printer to local server")
8109 rpc_printer_driver_list,
8111 N_("List printer drivers"),
8112 N_("net rpc printer driver\n"
8113 " List printer drivers")
8117 rpc_printer_publish,
8119 N_("Publish printer in AD"),
8120 N_("net rpc printer publish\n"
8121 " Publish printer in AD")
8123 {NULL, NULL, 0, NULL, NULL}
8127 if (c->display_usage) {
8128 d_printf(_("Usage:\n"));
8129 d_printf(_("net rpc printer\n"
8130 " List printers\n"));
8131 net_display_usage_from_functable(func);
8134 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8135 rpc_printer_list_internals,
8139 return net_run_function(c, argc, argv, "net rpc printer", func);
8143 * 'net rpc' entrypoint.
8145 * @param c A net_context structure.
8146 * @param argc Standard main() style argc.
8147 * @param argv Standard main() style argv. Initial components are already
8151 int net_rpc(struct net_context *c, int argc, const char **argv)
8153 NET_API_STATUS status;
8155 struct functable func[] = {
8160 N_("Modify global audit settings"),
8161 N_("net rpc audit\n"
8162 " Modify global audit settings")
8168 N_("Show basic info about a domain"),
8170 " Show basic info about a domain")
8176 N_("Join a domain"),
8184 N_("Join a domain created in server manager"),
8185 N_("net rpc oldjoin\n"
8186 " Join a domain created in server manager")
8192 N_("Test that a join is valid"),
8193 N_("net rpc testjoin\n"
8194 " Test that a join is valid")
8200 N_("List/modify users"),
8202 " List/modify users")
8208 N_("Change a user password"),
8209 N_("net rpc password\n"
8210 " Change a user password\n"
8211 " Alias for net rpc user password")
8217 N_("List/modify groups"),
8218 N_("net rpc group\n"
8219 " List/modify groups")
8225 N_("List/modify shares"),
8226 N_("net rpc share\n"
8227 " List/modify shares")
8233 N_("List open files"),
8241 N_("List/modify printers"),
8242 N_("net rpc printer\n"
8243 " List/modify printers")
8247 net_rpc_changetrustpw,
8249 N_("Change trust account password"),
8250 N_("net rpc changetrustpw\n"
8251 " Change trust account password")
8257 N_("Modify domain trusts"),
8258 N_("net rpc trustdom\n"
8259 " Modify domain trusts")
8265 N_("Abort a remote shutdown"),
8266 N_("net rpc abortshutdown\n"
8267 " Abort a remote shutdown")
8273 N_("Shutdown a remote server"),
8274 N_("net rpc shutdown\n"
8275 " Shutdown a remote server")
8281 N_("Sync a remote NT PDC's data into local passdb"),
8282 N_("net rpc vampire\n"
8283 " Sync a remote NT PDC's data into local passdb")
8289 N_("Fetch the domain sid into local secrets.tdb"),
8290 N_("net rpc getsid\n"
8291 " Fetch the domain sid into local secrets.tdb")
8297 N_("Manage privileges assigned to SID"),
8298 N_("net rpc rights\n"
8299 " Manage privileges assigned to SID")
8305 N_("Start/stop/query remote services"),
8306 N_("net rpc service\n"
8307 " Start/stop/query remote services")
8313 N_("Manage registry hives"),
8314 N_("net rpc registry\n"
8315 " Manage registry hives")
8321 N_("Open interactive shell on remote server"),
8322 N_("net rpc shell\n"
8323 " Open interactive shell on remote server")
8329 N_("Manage trusts"),
8330 N_("net rpc trust\n"
8337 N_("Configure a remote samba server"),
8339 " Configure a remote samba server")
8341 {NULL, NULL, 0, NULL, NULL}
8344 status = libnetapi_net_init(&c->netapi_ctx);
8348 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
8349 libnetapi_set_password(c->netapi_ctx, c->opt_password);
8350 if (c->opt_kerberos) {
8351 libnetapi_set_use_kerberos(c->netapi_ctx);
8353 if (c->opt_ccache) {
8354 libnetapi_set_use_ccache(c->netapi_ctx);
8357 return net_run_function(c, argc, argv, "net rpc", func);