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);
4672 if (alias.members == NULL) {
4673 status = NT_STATUS_NO_MEMORY;
4677 for (j = 0; j < alias.num_members; j++)
4678 sid_copy(&alias.members[j],
4679 sid_array.sids[j].sid);
4682 sid_compose(&alias.sid, domain_sid,
4683 groups->entries[i].idx);
4687 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4689 status = NT_STATUS_OK;
4692 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
4698 * Dump server_aliases as names for debugging purposes.
4701 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4702 const struct dom_sid *domain_sid,
4703 const char *domain_name,
4704 struct cli_state *cli,
4705 struct rpc_pipe_client *pipe_hnd,
4706 TALLOC_CTX *mem_ctx,
4712 struct policy_handle lsa_pol;
4713 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4715 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4716 SEC_FLAG_MAXIMUM_ALLOWED,
4718 if (!NT_STATUS_IS_OK(result))
4721 for (i=0; i<num_server_aliases; i++) {
4724 enum lsa_SidType *types;
4727 struct full_alias *alias = &server_aliases[i];
4729 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4731 &domains, &names, &types);
4732 if (!NT_STATUS_IS_OK(result))
4735 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4737 if (alias->num_members == 0) {
4742 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4745 &domains, &names, &types);
4747 if (!NT_STATUS_IS_OK(result) &&
4748 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4751 for (j=0; j<alias->num_members; j++)
4752 DEBUG(1, ("%s\\%s (%d); ",
4753 domains[j] ? domains[j] : "*unknown*",
4754 names[j] ? names[j] : "*unknown*",types[j]));
4758 dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
4760 return NT_STATUS_OK;
4764 * Fetch a list of all server aliases and their members into
4768 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4769 const struct dom_sid *domain_sid,
4770 const char *domain_name,
4771 struct cli_state *cli,
4772 struct rpc_pipe_client *pipe_hnd,
4773 TALLOC_CTX *mem_ctx,
4777 NTSTATUS result, status;
4778 struct policy_handle connect_pol;
4779 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4781 status = dcerpc_samr_Connect2(b, mem_ctx,
4783 MAXIMUM_ALLOWED_ACCESS,
4786 if (!NT_STATUS_IS_OK(status)) {
4789 if (!NT_STATUS_IS_OK(result)) {
4794 status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4795 &global_sid_Builtin);
4796 if (!NT_STATUS_IS_OK(status)) {
4800 status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4803 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
4808 static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4810 token->num_sids = 4;
4812 if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4813 d_fprintf(stderr, "malloc %s\n",_("failed"));
4814 token->num_sids = 0;
4818 token->sids[0] = *user_sid;
4819 sid_copy(&token->sids[1], &global_sid_World);
4820 sid_copy(&token->sids[2], &global_sid_Network);
4821 sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4824 static void free_user_token(struct security_token *token)
4826 SAFE_FREE(token->sids);
4829 static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4831 if (security_token_has_sid(token, sid))
4834 token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4839 sid_copy(&token->sids[token->num_sids], sid);
4841 token->num_sids += 1;
4846 struct security_token token;
4849 static void dump_user_token(struct user_token *token)
4853 d_printf("%s\n", token->name);
4855 for (i=0; i<token->token.num_sids; i++) {
4856 struct dom_sid_buf buf;
4858 dom_sid_str_buf(&token->token.sids[i], &buf));
4862 static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4866 for (i=0; i<alias->num_members; i++) {
4867 if (dom_sid_equal(sid, &alias->members[i])) {
4875 static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4879 for (i=0; i<num_server_aliases; i++) {
4880 if (is_alias_member(&sid, &server_aliases[i]))
4881 add_sid_to_token(token, &server_aliases[i].sid);
4886 * We got a user token with all the SIDs we can know about without asking the
4887 * server directly. These are the user and domain group sids. All of these can
4888 * be members of aliases. So scan the list of aliases for each of the SIDs and
4889 * add them to the token.
4892 static void collect_alias_memberships(struct security_token *token)
4894 int num_global_sids = token->num_sids;
4897 for (i=0; i<num_global_sids; i++) {
4898 collect_sid_memberships(token, token->sids[i]);
4902 static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4904 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4905 enum wbcSidType type;
4907 struct wbcDomainSid wsid;
4908 char sid_str[WBC_SID_STRING_BUFLEN];
4909 struct dom_sid user_sid;
4910 uint32_t num_groups;
4911 gid_t *groups = NULL;
4914 fstr_sprintf(full_name, "%s%c%s",
4915 domain, *lp_winbind_separator(), user);
4917 /* First let's find out the user sid */
4919 wbc_status = wbcLookupName(domain, user, &wsid, &type);
4921 if (!WBC_ERROR_IS_OK(wbc_status)) {
4922 DEBUG(1, ("winbind could not find %s: %s\n",
4923 full_name, wbcErrorString(wbc_status)));
4927 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4929 if (type != WBC_SID_NAME_USER) {
4930 DEBUG(1, ("%s is not a user\n", full_name));
4934 if (!string_to_sid(&user_sid, sid_str)) {
4935 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4939 init_user_token(token, &user_sid);
4941 /* And now the groups winbind knows about */
4943 wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4944 if (!WBC_ERROR_IS_OK(wbc_status)) {
4945 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4946 full_name, wbcErrorString(wbc_status)));
4950 for (i = 0; i < num_groups; i++) {
4951 gid_t gid = groups[i];
4955 wbc_status = wbcGidToSid(gid, &wsid);
4956 if (!WBC_ERROR_IS_OK(wbc_status)) {
4957 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4958 (unsigned int)gid, wbcErrorString(wbc_status)));
4959 wbcFreeMemory(groups);
4963 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4965 DEBUG(3, (" %s\n", sid_str));
4967 ok = string_to_sid(&sid, sid_str);
4969 DEBUG(1, ("Failed to convert string to SID\n"));
4970 wbcFreeMemory(groups);
4973 add_sid_to_token(token, &sid);
4975 wbcFreeMemory(groups);
4981 * Get a list of all user tokens we want to look at
4984 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4985 struct user_token **user_tokens)
4987 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4988 uint32_t i, num_users;
4990 struct user_token *result;
4991 TALLOC_CTX *frame = NULL;
4993 if (lp_winbind_use_default_domain() &&
4994 (c->opt_target_workgroup == NULL)) {
4995 d_fprintf(stderr, _("winbind use default domain = yes set, "
4996 "please specify a workgroup\n"));
5000 /* Send request to winbind daemon */
5002 wbc_status = wbcListUsers(NULL, &num_users, &users);
5003 if (!WBC_ERROR_IS_OK(wbc_status)) {
5004 DEBUG(1, (_("winbind could not list users: %s\n"),
5005 wbcErrorString(wbc_status)));
5009 result = SMB_MALLOC_ARRAY(struct user_token, num_users);
5011 if (result == NULL) {
5012 DEBUG(1, ("Could not malloc sid array\n"));
5013 wbcFreeMemory(users);
5017 frame = talloc_stackframe();
5018 for (i=0; i < num_users; i++) {
5019 fstring domain, user;
5022 fstrcpy(result[i].name, users[i]);
5024 p = strchr(users[i], *lp_winbind_separator());
5026 DEBUG(3, ("%s\n", users[i]));
5029 fstrcpy(domain, c->opt_target_workgroup);
5030 fstrcpy(user, users[i]);
5033 fstrcpy(domain, users[i]);
5034 if (!strupper_m(domain)) {
5035 DEBUG(1, ("strupper_m %s failed\n", domain));
5036 wbcFreeMemory(users);
5042 get_user_sids(domain, user, &(result[i].token));
5045 wbcFreeMemory(users);
5047 *num_tokens = num_users;
5048 *user_tokens = result;
5053 static bool get_user_tokens_from_file(FILE *f,
5055 struct user_token **tokens)
5057 struct user_token *token = NULL;
5062 if (fgets(line, sizeof(line)-1, f) == NULL) {
5066 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
5067 line[strlen(line)-1] = '\0';
5070 if (line[0] == ' ') {
5074 if(!string_to_sid(&sid, &line[1])) {
5075 DEBUG(1,("get_user_tokens_from_file: Could "
5076 "not convert sid %s \n",&line[1]));
5080 if (token == NULL) {
5081 DEBUG(0, ("File does not begin with username"));
5085 add_sid_to_token(&token->token, &sid);
5089 /* And a new user... */
5092 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
5093 if (*tokens == NULL) {
5094 DEBUG(0, ("Could not realloc tokens\n"));
5098 token = &((*tokens)[*num_tokens-1]);
5100 if (strlcpy(token->name, line, sizeof(token->name)) >= sizeof(token->name)) {
5103 token->token.num_sids = 0;
5104 token->token.sids = NULL;
5113 * Show the list of all users that have access to a share
5116 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
5117 struct cli_state *cli,
5118 TALLOC_CTX *mem_ctx,
5119 const char *netname,
5121 struct user_token *tokens)
5124 struct security_descriptor *share_sd = NULL;
5125 struct security_descriptor *root_sd = NULL;
5127 union srvsvc_NetShareInfo info;
5130 struct smbXcli_tcon *orig_tcon = NULL;
5131 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5133 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5140 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
5141 DEBUG(1, ("Could not query secdesc for share %s\n",
5146 share_sd = info.info502->sd_buf.sd;
5147 if (share_sd == NULL) {
5148 DEBUG(1, ("Got no secdesc for share %s\n",
5152 if (cli_state_has_tcon(cli)) {
5153 orig_tcon = cli_state_save_tcon(cli);
5154 if (orig_tcon == NULL) {
5159 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", NULL))) {
5160 cli_state_restore_tcon(cli, orig_tcon);
5164 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
5165 FILE_SHARE_READ|FILE_SHARE_WRITE,
5166 FILE_OPEN, 0x0, 0x0, &fnum, NULL))) {
5167 cli_query_secdesc(cli, fnum, mem_ctx, &root_sd);
5170 for (i=0; i<num_tokens; i++) {
5171 uint32_t acc_granted;
5173 if (share_sd != NULL) {
5174 status = se_access_check(share_sd, &tokens[i].token,
5177 if (!NT_STATUS_IS_OK(status)) {
5178 DEBUG(1, ("Could not check share_sd for "
5185 if (root_sd == NULL) {
5186 d_printf(" %s\n", tokens[i].name);
5190 status = se_access_check(root_sd, &tokens[i].token,
5192 if (!NT_STATUS_IS_OK(status)) {
5193 DEBUG(1, ("Could not check root_sd for user %s\n",
5197 d_printf(" %s\n", tokens[i].name);
5200 if (fnum != (uint16_t)-1)
5201 cli_close(cli, fnum);
5203 cli_state_restore_tcon(cli, orig_tcon);
5209 * List shares on a remote RPC server, including the security descriptors.
5211 * All parameters are provided by the run_rpc_command function, except for
5212 * argc, argv which are passed through.
5214 * @param domain_sid The domain sid acquired from the remote server.
5215 * @param cli A cli_state connected to the server.
5216 * @param mem_ctx Talloc context, destroyed on completion of the function.
5217 * @param argc Standard main() style argc.
5218 * @param argv Standard main() style argv. Initial components are already
5221 * @return Normal NTSTATUS return.
5224 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
5225 const struct dom_sid *domain_sid,
5226 const char *domain_name,
5227 struct cli_state *cli,
5228 struct rpc_pipe_client *pipe_hnd,
5229 TALLOC_CTX *mem_ctx,
5235 NTSTATUS nt_status = NT_STATUS_OK;
5236 uint32_t total_entries = 0;
5237 uint32_t resume_handle = 0;
5238 uint32_t preferred_len = 0xffffffff;
5240 struct dcerpc_binding_handle *b = NULL;
5241 struct srvsvc_NetShareInfoCtr info_ctr;
5242 struct srvsvc_NetShareCtr1 ctr1;
5245 struct user_token *tokens = NULL;
5251 if (strequal(argv[0], "-")) {
5254 f = fopen(argv[0], "r");
5261 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
5262 return NT_STATUS_UNSUCCESSFUL;
5265 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
5271 DEBUG(0, ("Could not read users from file\n"));
5272 return NT_STATUS_UNSUCCESSFUL;
5275 for (i=0; i<num_tokens; i++)
5276 collect_alias_memberships(&tokens[i].token);
5278 ZERO_STRUCT(info_ctr);
5282 info_ctr.ctr.ctr1 = &ctr1;
5284 b = pipe_hnd->binding_handle;
5287 /* Show results only for shares listed on the command line. */
5289 const char *netname = *argv++;
5290 d_printf("%s\n", netname);
5291 show_userlist(pipe_hnd, cli, mem_ctx, netname,
5292 num_tokens, tokens);
5297 /* Issue the NetShareEnum RPC call and retrieve the response */
5298 nt_status = dcerpc_srvsvc_NetShareEnumAll(b,
5307 /* Was it successful? */
5308 if (!NT_STATUS_IS_OK(nt_status)) {
5309 /* Nope. Go clean up. */
5313 if (!W_ERROR_IS_OK(result)) {
5314 /* Nope. Go clean up. */
5315 nt_status = werror_to_ntstatus(result);
5319 if (total_entries == 0) {
5323 /* For each returned entry... */
5324 for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
5325 const char *netname = info_ctr.ctr.ctr1->array[i].name;
5327 if (info_ctr.ctr.ctr1->array[i].type != STYPE_DISKTREE) {
5331 d_printf("%s\n", netname);
5333 show_userlist(pipe_hnd, cli, mem_ctx, netname,
5334 num_tokens, tokens);
5337 for (i=0; i<num_tokens; i++) {
5338 free_user_token(&tokens[i].token);
5341 TALLOC_FREE(server_aliases);
5346 static int rpc_share_allowedusers(struct net_context *c, int argc,
5351 if (c->display_usage) {
5353 "net rpc share allowedusers\n"
5356 _("List allowed users"));
5360 result = run_rpc_command(c, NULL, &ndr_table_samr, 0,
5361 rpc_aliaslist_internals,
5366 result = run_rpc_command(c, NULL, &ndr_table_lsarpc, 0,
5372 return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
5373 rpc_share_allowedusers_internals,
5377 int net_usersidlist(struct net_context *c, int argc, const char **argv)
5380 struct user_token *tokens = NULL;
5384 net_usersidlist_usage(c, argc, argv);
5388 if (!get_user_tokens(c, &num_tokens, &tokens)) {
5389 DEBUG(0, ("Could not get the user/sid list\n"));
5393 for (i=0; i<num_tokens; i++) {
5394 dump_user_token(&tokens[i]);
5395 free_user_token(&tokens[i].token);
5402 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
5404 d_printf(_("net usersidlist\n"
5405 "\tprints out a list of all users the running winbind knows\n"
5406 "\tabout, together with all their SIDs. This is used as\n"
5407 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5409 net_common_flags_usage(c, argc, argv);
5414 * 'net rpc share' entrypoint.
5415 * @param argc Standard main() style argc.
5416 * @param argv Standard main() style argv. Initial components are already
5420 int net_rpc_share(struct net_context *c, int argc, const char **argv)
5422 NET_API_STATUS status;
5424 struct functable func[] = {
5430 N_("net rpc share add\n"
5438 N_("net rpc share delete\n"
5443 rpc_share_allowedusers,
5445 N_("List allowed users"),
5446 N_("net rpc share allowedusers\n"
5447 " List allowed users")
5453 N_("Migrate share to local server"),
5454 N_("net rpc share migrate\n"
5455 " Migrate share to local server")
5462 N_("net rpc share list\n"
5465 {NULL, NULL, 0, NULL, NULL}
5468 status = libnetapi_net_init(&c->netapi_ctx);
5472 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5473 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5474 if (c->opt_kerberos) {
5475 libnetapi_set_use_kerberos(c->netapi_ctx);
5479 if (c->display_usage) {
5484 " Alias for net rpc share list\n"));
5485 net_display_usage_from_functable(func);
5489 return rpc_share_list(c, argc, argv);
5492 return net_run_function(c, argc, argv, "net rpc share", func);
5495 static NTSTATUS rpc_sh_share_list(struct net_context *c,
5496 TALLOC_CTX *mem_ctx,
5497 struct rpc_sh_ctx *ctx,
5498 struct rpc_pipe_client *pipe_hnd,
5499 int argc, const char **argv)
5502 return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
5505 static NTSTATUS rpc_sh_share_add(struct net_context *c,
5506 TALLOC_CTX *mem_ctx,
5507 struct rpc_sh_ctx *ctx,
5508 struct rpc_pipe_client *pipe_hnd,
5509 int argc, const char **argv)
5511 NET_API_STATUS status;
5512 uint32_t parm_err = 0;
5513 struct SHARE_INFO_2 i2;
5515 if ((argc < 2) || (argc > 3)) {
5516 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
5518 return NT_STATUS_INVALID_PARAMETER;
5521 i2.shi2_netname = argv[0];
5522 i2.shi2_type = STYPE_DISKTREE;
5523 i2.shi2_remark = (argc == 3) ? argv[2] : "";
5524 i2.shi2_permissions = 0;
5525 i2.shi2_max_uses = 0;
5526 i2.shi2_current_uses = 0;
5527 i2.shi2_path = argv[1];
5528 i2.shi2_passwd = NULL;
5530 status = NetShareAdd(pipe_hnd->desthost,
5535 return werror_to_ntstatus(W_ERROR(status));
5538 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
5539 TALLOC_CTX *mem_ctx,
5540 struct rpc_sh_ctx *ctx,
5541 struct rpc_pipe_client *pipe_hnd,
5542 int argc, const char **argv)
5545 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5546 return NT_STATUS_INVALID_PARAMETER;
5549 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
5552 static NTSTATUS rpc_sh_share_info(struct net_context *c,
5553 TALLOC_CTX *mem_ctx,
5554 struct rpc_sh_ctx *ctx,
5555 struct rpc_pipe_client *pipe_hnd,
5556 int argc, const char **argv)
5558 union srvsvc_NetShareInfo info;
5561 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5564 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5565 return NT_STATUS_INVALID_PARAMETER;
5568 status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5574 if (!NT_STATUS_IS_OK(status)) {
5575 result = ntstatus_to_werror(status);
5578 if (!W_ERROR_IS_OK(result)) {
5582 d_printf(_("Name: %s\n"), info.info2->name);
5583 d_printf(_("Comment: %s\n"), info.info2->comment);
5584 d_printf(_("Path: %s\n"), info.info2->path);
5585 d_printf(_("Password: %s\n"), info.info2->password);
5588 return werror_to_ntstatus(result);
5591 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
5592 struct rpc_sh_ctx *ctx)
5594 static struct rpc_sh_cmd cmds[] = {
5596 { "list", NULL, &ndr_table_srvsvc, rpc_sh_share_list,
5597 N_("List available shares") },
5599 { "add", NULL, &ndr_table_srvsvc, rpc_sh_share_add,
5600 N_("Add a share") },
5602 { "delete", NULL, &ndr_table_srvsvc, rpc_sh_share_delete,
5603 N_("Delete a share") },
5605 { "info", NULL, &ndr_table_srvsvc, rpc_sh_share_info,
5606 N_("Get information about a share") },
5608 { NULL, NULL, 0, NULL, NULL }
5614 /****************************************************************************/
5616 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
5618 return net_file_usage(c, argc, argv);
5622 * Close a file on a remote RPC server.
5624 * @param argc Standard main() style argc.
5625 * @param argv Standard main() style argv. Initial components are already
5628 * @return A shell status integer (0 for success).
5630 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5632 if (argc < 1 || c->display_usage) {
5633 return rpc_file_usage(c, argc, argv);
5636 return NetFileClose(c->opt_host, atoi(argv[0]));
5640 * Formatted print of open file info
5642 * @param r struct FILE_INFO_3 contents
5645 static void display_file_info_3(struct FILE_INFO_3 *r)
5647 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5648 r->fi3_id, r->fi3_username, r->fi3_permissions,
5649 r->fi3_num_locks, r->fi3_pathname);
5653 * List files for a user on a remote RPC server.
5655 * @param argc Standard main() style argc.
5656 * @param argv Standard main() style argv. Initial components are already
5659 * @return A shell status integer (0 for success)..
5662 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5664 NET_API_STATUS status;
5665 uint32_t preferred_len = 0xffffffff, i;
5666 char *username=NULL;
5667 uint32_t total_entries = 0;
5668 uint32_t entries_read = 0;
5669 uint32_t resume_handle = 0;
5670 struct FILE_INFO_3 *i3 = NULL;
5672 if (c->display_usage) {
5673 return rpc_file_usage(c, argc, argv);
5676 /* if argc > 0, must be user command */
5678 username = smb_xstrdup(argv[0]);
5681 status = NetFileEnum(c->opt_host,
5685 (uint8_t **)(void *)&i3,
5695 /* Display results */
5698 "\nEnumerating open files on remote server:\n\n"
5699 "\nFileId Opened by Perms Locks Path"
5700 "\n------ --------- ----- ----- ---- \n"));
5701 for (i = 0; i < entries_read; i++) {
5702 display_file_info_3(&i3[i]);
5705 SAFE_FREE(username);
5710 * 'net rpc file' entrypoint.
5711 * @param argc Standard main() style argc.
5712 * @param argv Standard main() style argv. Initial components are already
5716 int net_rpc_file(struct net_context *c, int argc, const char **argv)
5718 NET_API_STATUS status;
5720 struct functable func[] = {
5725 N_("Close opened file"),
5726 N_("net rpc file close\n"
5727 " Close opened file")
5733 N_("List files opened by user"),
5734 N_("net rpc file user\n"
5735 " List files opened by user")
5742 N_("Display information about opened file"),
5743 N_("net rpc file info\n"
5744 " Display information about opened file")
5747 {NULL, NULL, 0, NULL, NULL}
5750 status = libnetapi_net_init(&c->netapi_ctx);
5754 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5755 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5756 if (c->opt_kerberos) {
5757 libnetapi_set_use_kerberos(c->netapi_ctx);
5761 if (c->display_usage) {
5762 d_printf(_("Usage:\n"));
5763 d_printf(_("net rpc file\n"
5764 " List opened files\n"));
5765 net_display_usage_from_functable(func);
5769 return rpc_file_user(c, argc, argv);
5772 return net_run_function(c, argc, argv, "net rpc file", func);
5776 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5778 * All parameters are provided by the run_rpc_command function, except for
5779 * argc, argv which are passed through.
5781 * @param c A net_context structure.
5782 * @param domain_sid The domain sid acquired from the remote server.
5783 * @param cli A cli_state connected to the server.
5784 * @param mem_ctx Talloc context, destroyed on completion of the function.
5785 * @param argc Standard main() style argc.
5786 * @param argv Standard main() style argv. Initial components are already
5789 * @return Normal NTSTATUS return.
5792 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5793 const struct dom_sid *domain_sid,
5794 const char *domain_name,
5795 struct cli_state *cli,
5796 struct rpc_pipe_client *pipe_hnd,
5797 TALLOC_CTX *mem_ctx,
5801 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5803 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5805 status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5806 if (!NT_STATUS_IS_OK(status)) {
5809 if (W_ERROR_IS_OK(result)) {
5810 d_printf(_("\nShutdown successfully aborted\n"));
5811 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5813 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5815 return werror_to_ntstatus(result);
5819 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5821 * All parameters are provided by the run_rpc_command function, except for
5822 * argc, argv which are passed through.
5824 * @param c A net_context structure.
5825 * @param domain_sid The domain sid acquired from the remote server.
5826 * @param cli A cli_state connected to the server.
5827 * @param mem_ctx Talloc context, destroyed on completion of the function.
5828 * @param argc Standard main() style argc.
5829 * @param argv Standard main() style argv. Initial components are already
5832 * @return Normal NTSTATUS return.
5835 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5836 const struct dom_sid *domain_sid,
5837 const char *domain_name,
5838 struct cli_state *cli,
5839 struct rpc_pipe_client *pipe_hnd,
5840 TALLOC_CTX *mem_ctx,
5844 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5846 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5848 result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5850 if (!NT_STATUS_IS_OK(result)) {
5851 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5854 if (W_ERROR_IS_OK(werr)) {
5855 d_printf(_("\nShutdown successfully aborted\n"));
5856 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5858 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5860 return werror_to_ntstatus(werr);
5864 * ABORT the shutdown of a remote RPC server.
5866 * @param argc Standard main() style argc.
5867 * @param argv Standard main() style argv. Initial components are already
5870 * @return A shell status integer (0 for success).
5873 static int rpc_shutdown_abort(struct net_context *c, int argc,
5878 if (c->display_usage) {
5880 "net rpc abortshutdown\n"
5883 _("Abort a scheduled shutdown"));
5887 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
5888 rpc_shutdown_abort_internals, argc, argv);
5893 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5895 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
5896 rpc_reg_shutdown_abort_internals,
5901 * Shut down a remote RPC Server via initshutdown pipe.
5903 * All parameters are provided by the run_rpc_command function, except for
5904 * argc, argv which are passed through.
5906 * @param c A net_context structure.
5907 * @param domain_sid The domain sid acquired from the remote server.
5908 * @param cli A cli_state connected to the server.
5909 * @param mem_ctx Talloc context, destroyed on completion of the function.
5910 * @param argc Standard main() style argc.
5911 * @param argv Standard main() style argv. Initial components are already
5914 * @return Normal NTSTATUS return.
5917 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5918 const struct dom_sid *domain_sid,
5919 const char *domain_name,
5920 struct cli_state *cli,
5921 struct rpc_pipe_client *pipe_hnd,
5922 TALLOC_CTX *mem_ctx,
5926 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5928 const char *msg = N_("This machine will be shutdown shortly");
5929 uint32_t timeout = 20;
5930 struct lsa_StringLarge msg_string;
5931 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5933 if (c->opt_comment) {
5934 msg = c->opt_comment;
5936 if (c->opt_timeout) {
5937 timeout = c->opt_timeout;
5940 msg_string.string = msg;
5942 /* create an entry */
5943 status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5944 &msg_string, timeout, c->opt_force, c->opt_reboot,
5946 if (!NT_STATUS_IS_OK(status)) {
5949 if (W_ERROR_IS_OK(result)) {
5950 d_printf(_("\nShutdown of remote machine succeeded\n"));
5951 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5953 DEBUG(1,("Shutdown of remote machine failed!\n"));
5955 return werror_to_ntstatus(result);
5959 * Shut down a remote RPC Server via winreg pipe.
5961 * All parameters are provided by the run_rpc_command function, except for
5962 * argc, argv which are passed through.
5964 * @param c A net_context structure.
5965 * @param domain_sid The domain sid acquired from the remote server.
5966 * @param cli A cli_state connected to the server.
5967 * @param mem_ctx Talloc context, destroyed on completion of the function.
5968 * @param argc Standard main() style argc.
5969 * @param argv Standard main() style argv. Initial components are already
5972 * @return Normal NTSTATUS return.
5975 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5976 const struct dom_sid *domain_sid,
5977 const char *domain_name,
5978 struct cli_state *cli,
5979 struct rpc_pipe_client *pipe_hnd,
5980 TALLOC_CTX *mem_ctx,
5984 const char *msg = N_("This machine will be shutdown shortly");
5985 uint32_t timeout = 20;
5986 struct lsa_StringLarge msg_string;
5989 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5991 if (c->opt_comment) {
5992 msg = c->opt_comment;
5994 msg_string.string = msg;
5996 if (c->opt_timeout) {
5997 timeout = c->opt_timeout;
6000 /* create an entry */
6001 result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
6002 &msg_string, timeout, c->opt_force, c->opt_reboot,
6004 if (!NT_STATUS_IS_OK(result)) {
6005 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6009 if (W_ERROR_IS_OK(werr)) {
6010 d_printf(_("\nShutdown of remote machine succeeded\n"));
6012 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6013 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
6014 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
6016 d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
6019 return werror_to_ntstatus(werr);
6023 * Shut down a remote RPC server.
6025 * @param argc Standard main() style argc.
6026 * @param argv Standard main() style argv. Initial components are already
6029 * @return A shell status integer (0 for success).
6032 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
6036 if (c->display_usage) {
6038 "net rpc shutdown\n"
6041 _("Shut down a remote RPC server"));
6045 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
6046 rpc_init_shutdown_internals, argc, argv);
6049 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
6050 rc = run_rpc_command(c, NULL, &ndr_table_winreg, 0,
6051 rpc_reg_shutdown_internals, argc, argv);
6057 /***************************************************************************
6058 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
6059 ***************************************************************************/
6062 * Add interdomain trust account to the RPC server.
6063 * All parameters (except for argc and argv) are passed by run_rpc_command
6066 * @param c A net_context structure.
6067 * @param domain_sid The domain sid acquired from the server.
6068 * @param cli A cli_state connected to the server.
6069 * @param mem_ctx Talloc context, destroyed on completion of the function.
6070 * @param argc Standard main() style argc.
6071 * @param argv Standard main() style argv. Initial components are already
6074 * @return normal NTSTATUS return code.
6077 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
6078 const struct dom_sid *domain_sid,
6079 const char *domain_name,
6080 struct cli_state *cli,
6081 struct rpc_pipe_client *pipe_hnd,
6082 TALLOC_CTX *mem_ctx,
6086 struct policy_handle connect_pol, domain_pol, user_pol;
6087 NTSTATUS status, result;
6089 struct lsa_String lsa_acct_name;
6091 uint32_t acct_flags=0;
6093 uint32_t access_granted = 0;
6094 union samr_UserInfo info;
6095 unsigned int orig_timeout;
6096 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6097 DATA_BLOB session_key = data_blob_null;
6102 _(" net rpc trustdom add <domain_name> "
6103 "<trust password>\n"));
6104 return NT_STATUS_INVALID_PARAMETER;
6108 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6111 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
6112 return NT_STATUS_NO_MEMORY;
6115 if (!strupper_m(acct_name)) {
6116 SAFE_FREE(acct_name);
6117 return NT_STATUS_INVALID_PARAMETER;
6120 init_lsa_String(&lsa_acct_name, acct_name);
6122 status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6123 if (!NT_STATUS_IS_OK(status)) {
6124 DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
6125 nt_errstr(status)));
6129 /* Get samr policy handle */
6130 status = dcerpc_samr_Connect2(b, mem_ctx,
6132 MAXIMUM_ALLOWED_ACCESS,
6135 if (!NT_STATUS_IS_OK(status)) {
6138 if (!NT_STATUS_IS_OK(result)) {
6143 /* Get domain policy handle */
6144 status = dcerpc_samr_OpenDomain(b, mem_ctx,
6146 MAXIMUM_ALLOWED_ACCESS,
6147 discard_const_p(struct dom_sid2, domain_sid),
6150 if (!NT_STATUS_IS_OK(status)) {
6153 if (!NT_STATUS_IS_OK(result)) {
6158 /* This call can take a long time - allow the server to time out.
6159 * 35 seconds should do it. */
6161 orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
6163 /* Create trusting domain's account */
6164 acb_info = ACB_NORMAL;
6165 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
6166 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
6167 SAMR_USER_ACCESS_SET_PASSWORD |
6168 SAMR_USER_ACCESS_GET_ATTRIBUTES |
6169 SAMR_USER_ACCESS_SET_ATTRIBUTES;
6171 status = dcerpc_samr_CreateUser2(b, mem_ctx,
6180 if (!NT_STATUS_IS_OK(status)) {
6183 /* And restore our original timeout. */
6184 rpccli_set_timeout(pipe_hnd, orig_timeout);
6186 if (!NT_STATUS_IS_OK(result)) {
6188 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
6189 acct_name, nt_errstr(result));
6194 struct samr_CryptPassword crypt_pwd;
6196 ZERO_STRUCT(info.info23);
6198 init_samr_CryptPassword(argv[1],
6202 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
6203 SAMR_FIELD_NT_PASSWORD_PRESENT;
6204 info.info23.info.acct_flags = ACB_DOMTRUST;
6205 info.info23.password = crypt_pwd;
6207 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
6212 if (!NT_STATUS_IS_OK(status)) {
6216 if (!NT_STATUS_IS_OK(result)) {
6218 DEBUG(0,("Could not set trust account password: %s\n",
6219 nt_errstr(result)));
6225 SAFE_FREE(acct_name);
6226 data_blob_clear_free(&session_key);
6231 * Create interdomain trust account for a remote domain.
6233 * @param argc Standard argc.
6234 * @param argv Standard argv without initial components.
6236 * @return Integer status (0 means success).
6239 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
6241 if (argc > 0 && !c->display_usage) {
6242 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6243 rpc_trustdom_add_internals, argc, argv);
6247 _("net rpc trustdom add <domain_name> <trust "
6255 * Remove interdomain trust account from the RPC server.
6256 * All parameters (except for argc and argv) are passed by run_rpc_command
6259 * @param c A net_context structure.
6260 * @param domain_sid The domain sid acquired from the server.
6261 * @param cli A cli_state connected to the server.
6262 * @param mem_ctx Talloc context, destroyed on completion of the function.
6263 * @param argc Standard main() style argc.
6264 * @param argv Standard main() style argv. Initial components are already
6267 * @return normal NTSTATUS return code.
6270 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
6271 const struct dom_sid *domain_sid,
6272 const char *domain_name,
6273 struct cli_state *cli,
6274 struct rpc_pipe_client *pipe_hnd,
6275 TALLOC_CTX *mem_ctx,
6279 struct policy_handle connect_pol, domain_pol, user_pol;
6280 NTSTATUS status, result;
6282 struct dom_sid trust_acct_sid;
6283 struct samr_Ids user_rids, name_types;
6284 struct lsa_String lsa_acct_name;
6285 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6290 _(" net rpc trustdom del <domain_name>\n"));
6291 return NT_STATUS_INVALID_PARAMETER;
6295 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6297 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
6299 if (acct_name == NULL)
6300 return NT_STATUS_NO_MEMORY;
6302 if (!strupper_m(acct_name)) {
6303 TALLOC_FREE(acct_name);
6304 return NT_STATUS_INVALID_PARAMETER;
6307 /* Get samr policy handle */
6308 status = dcerpc_samr_Connect2(b, mem_ctx,
6310 MAXIMUM_ALLOWED_ACCESS,
6313 if (!NT_STATUS_IS_OK(status)) {
6316 if (!NT_STATUS_IS_OK(result)) {
6321 /* Get domain policy handle */
6322 status = dcerpc_samr_OpenDomain(b, mem_ctx,
6324 MAXIMUM_ALLOWED_ACCESS,
6325 discard_const_p(struct dom_sid2, domain_sid),
6328 if (!NT_STATUS_IS_OK(status)) {
6331 if (!NT_STATUS_IS_OK(result)) {
6336 init_lsa_String(&lsa_acct_name, acct_name);
6338 status = dcerpc_samr_LookupNames(b, mem_ctx,
6345 if (!NT_STATUS_IS_OK(status)) {
6346 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6348 acct_name, nt_errstr(status));
6351 if (!NT_STATUS_IS_OK(result)) {
6353 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6355 acct_name, nt_errstr(result) );
6358 if (user_rids.count != 1) {
6359 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6362 if (name_types.count != 1) {
6363 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6367 status = dcerpc_samr_OpenUser(b, mem_ctx,
6369 MAXIMUM_ALLOWED_ACCESS,
6373 if (!NT_STATUS_IS_OK(status)) {
6374 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6376 acct_name, nt_errstr(status) );
6380 if (!NT_STATUS_IS_OK(result)) {
6382 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6384 acct_name, nt_errstr(result) );
6388 /* append the rid to the domain sid */
6389 if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
6393 /* remove the sid */
6395 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, mem_ctx,
6399 if (!NT_STATUS_IS_OK(status)) {
6400 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6401 " on user %s failed %s\n"),
6402 acct_name, nt_errstr(status));
6405 if (!NT_STATUS_IS_OK(result)) {
6407 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6408 " on user %s failed %s\n"),
6409 acct_name, nt_errstr(result) );
6416 status = dcerpc_samr_DeleteUser(b, mem_ctx,
6419 if (!NT_STATUS_IS_OK(status)) {
6420 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6422 acct_name, nt_errstr(status));
6426 if (!NT_STATUS_IS_OK(result)) {
6428 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6430 acct_name, nt_errstr(result) );
6434 if (!NT_STATUS_IS_OK(result)) {
6435 d_printf(_("Could not set trust account password: %s\n"),
6445 * Delete interdomain trust account for a remote domain.
6447 * @param argc Standard argc.
6448 * @param argv Standard argv without initial components.
6450 * @return Integer status (0 means success).
6453 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
6455 if (argc > 0 && !c->display_usage) {
6456 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6457 rpc_trustdom_del_internals, argc, argv);
6461 _("net rpc trustdom del <domain>\n"));
6466 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
6467 struct cli_state *cli,
6468 TALLOC_CTX *mem_ctx,
6469 const char *domain_name)
6471 char *dc_name = NULL;
6472 const char *buffer = NULL;
6473 struct rpc_pipe_client *netr;
6476 struct dcerpc_binding_handle *b;
6478 /* Use NetServerEnum2 */
6480 if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
6482 return NT_STATUS_OK;
6485 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6486 for domain %s\n", domain_name));
6488 /* Try netr_GetDcName */
6490 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon,
6492 if (!NT_STATUS_IS_OK(status)) {
6496 b = netr->binding_handle;
6498 status = dcerpc_netr_GetDcName(b, mem_ctx,
6505 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
6509 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6510 for domain %s\n", domain_name));
6512 if (!NT_STATUS_IS_OK(status)) {
6516 return werror_to_ntstatus(result);
6520 * Establish trust relationship to a trusting domain.
6521 * Interdomain account must already be created on remote PDC.
6523 * @param c A net_context structure.
6524 * @param argc Standard argc.
6525 * @param argv Standard argv without initial components.
6527 * @return Integer status (0 means success).
6530 static int rpc_trustdom_establish(struct net_context *c, int argc,
6533 struct cli_state *cli = NULL;
6534 struct sockaddr_storage server_ss;
6535 struct rpc_pipe_client *pipe_hnd = NULL;
6536 struct policy_handle connect_hnd;
6537 TALLOC_CTX *mem_ctx;
6538 NTSTATUS nt_status, result;
6539 struct dom_sid *domain_sid;
6544 union lsa_PolicyInformation *info = NULL;
6545 struct dcerpc_binding_handle *b;
6548 * Connect to \\server\ipc$ as 'our domain' account with password
6551 if (argc != 1 || c->display_usage) {
6554 _("net rpc trustdom establish <domain_name>\n"));
6558 domain_name = smb_xstrdup(argv[0]);
6559 if (!strupper_m(domain_name)) {
6560 SAFE_FREE(domain_name);
6564 /* account name used at first is our domain's name with '$' */
6565 if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
6568 if (!strupper_m(acct_name)) {
6569 SAFE_FREE(domain_name);
6570 SAFE_FREE(acct_name);
6575 * opt_workgroup will be used by connection functions further,
6576 * hence it should be set to remote domain name instead of ours
6578 if (c->opt_workgroup) {
6579 c->opt_workgroup = smb_xstrdup(domain_name);
6582 c->opt_user_name = acct_name;
6584 /* find the domain controller */
6585 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
6586 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
6590 /* connect to ipc$ as username/password */
6591 nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
6592 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
6594 /* Is it trusting domain account for sure ? */
6595 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6596 nt_errstr(nt_status)));
6600 /* store who we connected to */
6602 saf_store( domain_name, pdc_name );
6605 * Connect to \\server\ipc$ again (this time anonymously)
6608 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
6611 if (NT_STATUS_IS_ERR(nt_status)) {
6612 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6613 domain_name, nt_errstr(nt_status)));
6617 if (!(mem_ctx = talloc_init("establishing trust relationship to "
6618 "domain %s", domain_name))) {
6619 DEBUG(0, ("talloc_init() failed\n"));
6624 /* Make sure we're talking to a proper server */
6626 nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
6627 if (!NT_STATUS_IS_OK(nt_status)) {
6629 talloc_destroy(mem_ctx);
6634 * Call LsaOpenPolicy and LsaQueryInfo
6637 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6639 if (!NT_STATUS_IS_OK(nt_status)) {
6640 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
6642 talloc_destroy(mem_ctx);
6646 b = pipe_hnd->binding_handle;
6648 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
6650 if (NT_STATUS_IS_ERR(nt_status)) {
6651 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6652 nt_errstr(nt_status)));
6654 talloc_destroy(mem_ctx);
6658 /* Querying info level 5 */
6660 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6662 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6665 if (NT_STATUS_IS_ERR(nt_status)) {
6666 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6667 nt_errstr(nt_status)));
6669 talloc_destroy(mem_ctx);
6672 if (NT_STATUS_IS_ERR(result)) {
6673 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6674 nt_errstr(result)));
6676 talloc_destroy(mem_ctx);
6680 domain_sid = info->account_domain.sid;
6682 /* There should be actually query info level 3 (following nt serv behaviour),
6683 but I still don't know if it's _really_ necessary */
6686 * Store the password in secrets db
6689 if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
6690 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6692 talloc_destroy(mem_ctx);
6697 * Close the pipes and clean up
6700 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6701 if (NT_STATUS_IS_ERR(nt_status)) {
6702 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6703 nt_errstr(nt_status)));
6705 talloc_destroy(mem_ctx);
6711 talloc_destroy(mem_ctx);
6713 d_printf(_("Trust to domain %s established\n"), domain_name);
6718 * Revoke trust relationship to the remote domain.
6720 * @param c A net_context structure.
6721 * @param argc Standard argc.
6722 * @param argv Standard argv without initial components.
6724 * @return Integer status (0 means success).
6727 static int rpc_trustdom_revoke(struct net_context *c, int argc,
6733 if (argc < 1 || c->display_usage) {
6736 _("net rpc trustdom revoke <domain_name>\n"
6737 " Revoke trust relationship\n"
6738 " domain_name\tName of domain to revoke trust\n"));
6742 /* generate upper cased domain name */
6743 domain_name = smb_xstrdup(argv[0]);
6744 if (!strupper_m(domain_name)) {
6745 SAFE_FREE(domain_name);
6749 /* delete password of the trust */
6750 if (!pdb_del_trusteddom_pw(domain_name)) {
6751 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6758 SAFE_FREE(domain_name);
6762 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6763 const struct dom_sid *domain_sid,
6764 const char *domain_name,
6765 struct cli_state *cli,
6766 struct rpc_pipe_client *pipe_hnd,
6767 TALLOC_CTX *mem_ctx,
6771 struct dom_sid_buf sid_str;
6772 d_printf("%s\n", dom_sid_str_buf(domain_sid, &sid_str));
6773 return NT_STATUS_OK;
6776 static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6778 struct dom_sid_buf sid_str;
6780 d_printf("%-20s%s\n",
6782 dom_sid_str_buf(dom_sid, &sid_str));
6785 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6786 TALLOC_CTX *mem_ctx,
6787 struct policy_handle *pol,
6788 struct dom_sid dom_sid,
6789 const char *trusted_dom_name)
6791 NTSTATUS nt_status, result;
6792 union lsa_TrustedDomainInfo *info = NULL;
6793 char *cleartextpwd = NULL;
6794 DATA_BLOB session_key;
6795 DATA_BLOB data = data_blob_null;
6796 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6798 nt_status = dcerpc_lsa_QueryTrustedDomainInfoBySid(b, mem_ctx,
6801 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6804 if (NT_STATUS_IS_ERR(nt_status)) {
6805 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6806 nt_errstr(nt_status)));
6809 if (NT_STATUS_IS_ERR(result)) {
6811 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6812 nt_errstr(result)));
6816 data = data_blob(info->password.password->data,
6817 info->password.password->length);
6819 nt_status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6820 if (!NT_STATUS_IS_OK(nt_status)) {
6821 DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status)));
6825 cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key);
6826 data_blob_free(&session_key);
6828 if (cleartextpwd == NULL) {
6829 DEBUG(0,("retrieved NULL password\n"));
6830 nt_status = NT_STATUS_UNSUCCESSFUL;
6834 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6835 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6836 nt_status = NT_STATUS_UNSUCCESSFUL;
6840 #ifdef DEBUG_PASSWORD
6842 struct dom_sid_buf buf;
6843 DEBUG(100,("successfully vampired trusted domain [%s], "
6844 "sid: [%s], password: [%s]\n",
6846 dom_sid_str_buf(&dom_sid, &buf),
6852 SAFE_FREE(cleartextpwd);
6853 data_blob_free(&data);
6858 static int rpc_trustdom_vampire(struct net_context *c, int argc,
6861 /* common variables */
6862 TALLOC_CTX* mem_ctx;
6863 struct cli_state *cli = NULL;
6864 struct rpc_pipe_client *pipe_hnd = NULL;
6865 NTSTATUS nt_status, result;
6866 const char *domain_name = NULL;
6867 struct policy_handle connect_hnd;
6868 union lsa_PolicyInformation *info = NULL;
6870 /* trusted domains listing variables */
6871 unsigned int enum_ctx = 0;
6873 struct lsa_DomainList dom_list;
6875 struct dcerpc_binding_handle *b;
6877 if (c->display_usage) {
6879 "net rpc trustdom vampire\n"
6882 _("Vampire trust relationship from remote server"));
6887 * Listing trusted domains (stored in secrets.tdb, if local)
6890 mem_ctx = talloc_init("trust relationships vampire");
6893 * set domain and pdc name to local samba server (default)
6894 * or to remote one given in command line
6897 if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
6898 domain_name = c->opt_workgroup;
6899 c->opt_target_workgroup = c->opt_workgroup;
6901 fstrcpy(pdc_name, lp_netbios_name());
6902 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6903 c->opt_target_workgroup = domain_name;
6906 /* open \PIPE\lsarpc and open policy handle */
6907 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6908 if (!NT_STATUS_IS_OK(nt_status)) {
6909 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6910 nt_errstr(nt_status)));
6911 talloc_destroy(mem_ctx);
6915 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6917 if (!NT_STATUS_IS_OK(nt_status)) {
6918 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6919 nt_errstr(nt_status) ));
6921 talloc_destroy(mem_ctx);
6925 b = pipe_hnd->binding_handle;
6927 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6929 if (NT_STATUS_IS_ERR(nt_status)) {
6930 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6931 nt_errstr(nt_status)));
6933 talloc_destroy(mem_ctx);
6937 /* query info level 5 to obtain sid of a domain being queried */
6938 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6940 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6944 if (NT_STATUS_IS_ERR(nt_status)) {
6945 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6946 nt_errstr(nt_status)));
6948 talloc_destroy(mem_ctx);
6951 if (NT_STATUS_IS_ERR(result)) {
6952 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6953 nt_errstr(result)));
6955 talloc_destroy(mem_ctx);
6960 * Keep calling LsaEnumTrustdom over opened pipe until
6961 * the end of enumeration is reached
6964 d_printf(_("Vampire trusted domains:\n\n"));
6967 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6973 if (NT_STATUS_IS_ERR(nt_status)) {
6974 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6975 nt_errstr(nt_status)));
6977 talloc_destroy(mem_ctx);
6980 if (NT_STATUS_IS_ERR(result)) {
6982 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6983 nt_errstr(result)));
6985 talloc_destroy(mem_ctx);
6990 for (i = 0; i < dom_list.count; i++) {
6992 print_trusted_domain(dom_list.domains[i].sid,
6993 dom_list.domains[i].name.string);
6995 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6996 *dom_list.domains[i].sid,
6997 dom_list.domains[i].name.string);
6998 if (!NT_STATUS_IS_OK(nt_status)) {
7000 talloc_destroy(mem_ctx);
7006 * in case of no trusted domains say something rather
7007 * than just display blank line
7009 if (!dom_list.count) d_printf(_("none\n"));
7011 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7013 /* close this connection before doing next one */
7014 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7015 if (NT_STATUS_IS_ERR(nt_status)) {
7016 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7017 nt_errstr(nt_status)));
7019 talloc_destroy(mem_ctx);
7023 /* close lsarpc pipe and connection to IPC$ */
7026 talloc_destroy(mem_ctx);
7030 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
7032 /* common variables */
7033 TALLOC_CTX* mem_ctx;
7034 struct cli_state *cli = NULL, *remote_cli = NULL;
7035 struct rpc_pipe_client *pipe_hnd = NULL;
7036 NTSTATUS nt_status, result;
7037 const char *domain_name = NULL;
7038 struct dom_sid *queried_dom_sid;
7039 int ascii_dom_name_len;
7040 struct policy_handle connect_hnd;
7041 union lsa_PolicyInformation *info = NULL;
7042 struct dcerpc_binding_handle *b = NULL;
7044 /* trusted domains listing variables */
7045 unsigned int num_domains, enum_ctx = 0;
7047 struct lsa_DomainList dom_list;
7051 /* trusting domains listing variables */
7052 struct policy_handle domain_hnd;
7053 struct samr_SamArray *trusts = NULL;
7055 if (c->display_usage) {
7057 "net rpc trustdom list\n"
7060 _("List incoming and outgoing trust relationships"));
7065 * Listing trusted domains (stored in secrets.tdb, if local)
7068 mem_ctx = talloc_init("trust relationships listing");
7071 * set domain and pdc name to local samba server (default)
7072 * or to remote one given in command line
7075 if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
7076 domain_name = c->opt_workgroup;
7077 c->opt_target_workgroup = c->opt_workgroup;
7079 fstrcpy(pdc_name, lp_netbios_name());
7080 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
7081 c->opt_target_workgroup = domain_name;
7084 /* open \PIPE\lsarpc and open policy handle */
7085 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
7086 if (!NT_STATUS_IS_OK(nt_status)) {
7087 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
7088 nt_errstr(nt_status)));
7089 talloc_destroy(mem_ctx);
7093 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
7095 if (!NT_STATUS_IS_OK(nt_status)) {
7096 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
7097 nt_errstr(nt_status) ));
7099 talloc_destroy(mem_ctx);
7103 b = pipe_hnd->binding_handle;
7105 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
7107 if (NT_STATUS_IS_ERR(nt_status)) {
7108 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
7109 nt_errstr(nt_status)));
7111 talloc_destroy(mem_ctx);
7115 /* query info level 5 to obtain sid of a domain being queried */
7116 nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
7118 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
7122 if (NT_STATUS_IS_ERR(nt_status)) {
7123 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7124 nt_errstr(nt_status)));
7126 talloc_destroy(mem_ctx);
7129 if (NT_STATUS_IS_ERR(result)) {
7130 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7131 nt_errstr(result)));
7133 talloc_destroy(mem_ctx);
7137 queried_dom_sid = info->account_domain.sid;
7140 * Keep calling LsaEnumTrustdom over opened pipe until
7141 * the end of enumeration is reached
7144 d_printf(_("Trusted domains list:\n\n"));
7146 found_domain = false;
7149 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
7155 if (NT_STATUS_IS_ERR(nt_status)) {
7156 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7157 nt_errstr(nt_status)));
7159 talloc_destroy(mem_ctx);
7162 if (NT_STATUS_IS_ERR(result)) {
7163 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7164 nt_errstr(result)));
7166 talloc_destroy(mem_ctx);
7171 for (i = 0; i < dom_list.count; i++) {
7172 print_trusted_domain(dom_list.domains[i].sid,
7173 dom_list.domains[i].name.string);
7174 found_domain = true;
7178 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7181 * in case of no trusted domains say something rather
7182 * than just display blank line
7184 if (!found_domain) {
7185 d_printf(_("none\n"));
7188 /* close this connection before doing next one */
7189 nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7190 if (NT_STATUS_IS_ERR(nt_status)) {
7191 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7192 nt_errstr(nt_status)));
7194 talloc_destroy(mem_ctx);
7198 TALLOC_FREE(pipe_hnd);
7201 * Listing trusting domains (stored in passdb backend, if local)
7204 d_printf(_("\nTrusting domains list:\n\n"));
7207 * Open \PIPE\samr and get needed policy handles
7209 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr,
7211 if (!NT_STATUS_IS_OK(nt_status)) {
7212 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
7214 talloc_destroy(mem_ctx);
7218 b = pipe_hnd->binding_handle;
7221 nt_status = dcerpc_samr_Connect2(b, mem_ctx,
7223 SAMR_ACCESS_LOOKUP_DOMAIN,
7226 if (!NT_STATUS_IS_OK(nt_status)) {
7227 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7228 nt_errstr(nt_status)));
7230 talloc_destroy(mem_ctx);
7233 if (!NT_STATUS_IS_OK(result)) {
7235 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7236 nt_errstr(result)));
7238 talloc_destroy(mem_ctx);
7242 /* SamrOpenDomain - we have to open domain policy handle in order to be
7243 able to enumerate accounts*/
7244 nt_status = dcerpc_samr_OpenDomain(b, mem_ctx,
7246 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
7250 if (!NT_STATUS_IS_OK(nt_status)) {
7251 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7252 nt_errstr(nt_status)));
7254 talloc_destroy(mem_ctx);
7257 if (!NT_STATUS_IS_OK(result)) {
7259 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7260 nt_errstr(result)));
7262 talloc_destroy(mem_ctx);
7267 * perform actual enumeration
7270 found_domain = false;
7272 enum_ctx = 0; /* reset enumeration context from last enumeration */
7275 nt_status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
7283 if (NT_STATUS_IS_ERR(nt_status)) {
7284 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7285 nt_errstr(nt_status)));
7287 talloc_destroy(mem_ctx);
7290 if (NT_STATUS_IS_ERR(result)) {
7292 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7293 nt_errstr(result)));
7295 talloc_destroy(mem_ctx);
7299 for (i = 0; i < num_domains; i++) {
7301 char *str = discard_const_p(char, trusts->entries[i].name.string);
7303 found_domain = true;
7306 * get each single domain's sid (do we _really_ need this ?):
7307 * 1) connect to domain's pdc
7308 * 2) query the pdc for domain's sid
7311 /* get rid of '$' tail */
7312 ascii_dom_name_len = strlen(str);
7313 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
7314 str[ascii_dom_name_len - 1] = '\0';
7316 /* set opt_* variables to remote domain */
7317 if (!strupper_m(str)) {
7319 talloc_destroy(mem_ctx);
7322 c->opt_workgroup = talloc_strdup(mem_ctx, str);
7323 c->opt_target_workgroup = c->opt_workgroup;
7325 d_printf("%-20s", str);
7327 /* connect to remote domain controller */
7328 nt_status = net_make_ipc_connection(c,
7329 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
7331 if (NT_STATUS_IS_OK(nt_status)) {
7332 /* query for domain's sid */
7333 if (run_rpc_command(
7335 &ndr_table_lsarpc, 0,
7336 rpc_query_domain_sid, argc,
7338 d_printf(_("strange - couldn't get domain's sid\n"));
7340 cli_shutdown(remote_cli);
7343 d_fprintf(stderr, _("domain controller is not "
7344 "responding: %s\n"),
7345 nt_errstr(nt_status));
7346 d_printf(_("couldn't get domain's sid\n"));
7350 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
7352 if (!found_domain) {
7356 /* close opened samr and domain policy handles */
7357 nt_status = dcerpc_samr_Close(b, mem_ctx, &domain_hnd, &result);
7358 if (!NT_STATUS_IS_OK(nt_status)) {
7359 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
7362 nt_status = dcerpc_samr_Close(b, mem_ctx, &connect_hnd, &result);
7363 if (!NT_STATUS_IS_OK(nt_status)) {
7364 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
7367 /* close samr pipe and connection to IPC$ */
7370 talloc_destroy(mem_ctx);
7375 * Entrypoint for 'net rpc trustdom' code.
7377 * @param argc Standard argc.
7378 * @param argv Standard argv without initial components.
7380 * @return Integer status (0 means success).
7383 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
7385 struct functable func[] = {
7390 N_("Add trusting domain's account"),
7391 N_("net rpc trustdom add\n"
7392 " Add trusting domain's account")
7398 N_("Remove trusting domain's account"),
7399 N_("net rpc trustdom del\n"
7400 " Remove trusting domain's account")
7404 rpc_trustdom_establish,
7406 N_("Establish outgoing trust relationship"),
7407 N_("net rpc trustdom establish\n"
7408 " Establish outgoing trust relationship")
7412 rpc_trustdom_revoke,
7414 N_("Revoke outgoing trust relationship"),
7415 N_("net rpc trustdom revoke\n"
7416 " Revoke outgoing trust relationship")
7422 N_("List in- and outgoing domain trusts"),
7423 N_("net rpc trustdom list\n"
7424 " List in- and outgoing domain trusts")
7428 rpc_trustdom_vampire,
7430 N_("Vampire trusts from remote server"),
7431 N_("net rpc trustdom vampire\n"
7432 " Vampire trusts from remote server")
7434 {NULL, NULL, 0, NULL, NULL}
7437 return net_run_function(c, argc, argv, "net rpc trustdom", func);
7441 * Check if a server will take rpc commands
7442 * @param flags Type of server to connect to (PDC, DMB, localhost)
7443 * if the host is not explicitly specified
7444 * @return bool (true means rpc supported)
7446 bool net_rpc_check(struct net_context *c, unsigned flags)
7448 struct cli_state *cli;
7450 struct sockaddr_storage server_ss;
7451 char *server_name = NULL;
7454 /* flags (i.e. server type) may depend on command */
7455 if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
7458 status = cli_connect_nb(server_name, &server_ss, 0, 0x20,
7459 lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT,
7461 if (!NT_STATUS_IS_OK(status)) {
7462 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
7463 DBG_ERR("NetBIOS support disabled, unable to connect\n");
7467 status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
7469 if (!NT_STATUS_IS_OK(status))
7471 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1)
7480 /* syncronise sam database via samsync rpc calls */
7481 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
7483 struct functable func[] = {
7488 N_("Dump remote SAM database to Kerberos Keytab"),
7489 N_("net rpc vampire keytab\n"
7490 " Dump remote SAM database to Kerberos keytab "
7497 N_("Dump remote SAM database to passdb"),
7498 N_("net rpc vampire passdb\n"
7499 " Dump remote SAM database to passdb")
7502 {NULL, NULL, 0, NULL, NULL}
7506 if (c->display_usage) {
7511 _("Vampire remote SAM database"));
7515 return rpc_vampire_passdb(c, argc, argv);
7518 return net_run_function(c, argc, argv, "net rpc vampire", func);
7522 * Migrate everything from a print server.
7524 * @param c A net_context structure.
7525 * @param argc Standard main() style argc.
7526 * @param argv Standard main() style argv. Initial components are already
7529 * @return A shell status integer (0 for success).
7531 * The order is important !
7532 * To successfully add drivers the print queues have to exist !
7533 * Applying ACLs should be the last step, because you're easily locked out.
7536 static int rpc_printer_migrate_all(struct net_context *c, int argc,
7541 if (c->display_usage) {
7543 "net rpc printer migrate all\n"
7546 _("Migrate everything from a print server"));
7551 d_printf(_("no server to migrate\n"));
7555 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7556 rpc_printer_migrate_printers_internals, argc,
7561 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7562 rpc_printer_migrate_drivers_internals, argc,
7567 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7568 rpc_printer_migrate_forms_internals, argc, argv);
7572 ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7573 rpc_printer_migrate_settings_internals, argc,
7578 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7579 rpc_printer_migrate_security_internals, argc,
7585 * Migrate print drivers from a print server.
7587 * @param c A net_context structure.
7588 * @param argc Standard main() style argc.
7589 * @param argv Standard main() style argv. Initial components are already
7592 * @return A shell status integer (0 for success).
7594 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
7597 if (c->display_usage) {
7599 "net rpc printer migrate drivers\n"
7602 _("Migrate print-drivers from a print-server"));
7607 d_printf(_("no server to migrate\n"));
7611 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7612 rpc_printer_migrate_drivers_internals,
7617 * Migrate print-forms from a print-server.
7619 * @param c A net_context structure.
7620 * @param argc Standard main() style argc.
7621 * @param argv Standard main() style argv. Initial components are already
7624 * @return A shell status integer (0 for success).
7626 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
7629 if (c->display_usage) {
7631 "net rpc printer migrate forms\n"
7634 _("Migrate print-forms from a print-server"));
7639 d_printf(_("no server to migrate\n"));
7643 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7644 rpc_printer_migrate_forms_internals,
7649 * Migrate printers from a print-server.
7651 * @param c A net_context structure.
7652 * @param argc Standard main() style argc.
7653 * @param argv Standard main() style argv. Initial components are already
7656 * @return A shell status integer (0 for success).
7658 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
7661 if (c->display_usage) {
7663 "net rpc printer migrate printers\n"
7666 _("Migrate printers from a print-server"));
7671 d_printf(_("no server to migrate\n"));
7675 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7676 rpc_printer_migrate_printers_internals,
7681 * Migrate printer-ACLs from a print-server
7683 * @param c A net_context structure.
7684 * @param argc Standard main() style argc.
7685 * @param argv Standard main() style argv. Initial components are already
7688 * @return A shell status integer (0 for success).
7690 static int rpc_printer_migrate_security(struct net_context *c, int argc,
7693 if (c->display_usage) {
7695 "net rpc printer migrate security\n"
7698 _("Migrate printer-ACLs from a print-server"));
7703 d_printf(_("no server to migrate\n"));
7707 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7708 rpc_printer_migrate_security_internals,
7713 * Migrate printer-settings from a print-server.
7715 * @param c A net_context structure.
7716 * @param argc Standard main() style argc.
7717 * @param argv Standard main() style argv. Initial components are already
7720 * @return A shell status integer (0 for success).
7722 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
7725 if (c->display_usage) {
7727 "net rpc printer migrate settings\n"
7730 _("Migrate printer-settings from a "
7736 d_printf(_("no server to migrate\n"));
7740 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7741 rpc_printer_migrate_settings_internals,
7746 * 'net rpc printer' entrypoint.
7748 * @param c A net_context structure.
7749 * @param argc Standard main() style argc.
7750 * @param argv Standard main() style argv. Initial components are already
7754 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
7757 /* ouch: when addriver and setdriver are called from within
7758 rpc_printer_migrate_drivers_internals, the printer-queue already
7761 struct functable func[] = {
7764 rpc_printer_migrate_all,
7766 N_("Migrate all from remote to local print server"),
7767 N_("net rpc printer migrate all\n"
7768 " Migrate all from remote to local print server")
7772 rpc_printer_migrate_drivers,
7774 N_("Migrate drivers to local server"),
7775 N_("net rpc printer migrate drivers\n"
7776 " Migrate drivers to local server")
7780 rpc_printer_migrate_forms,
7782 N_("Migrate froms to local server"),
7783 N_("net rpc printer migrate forms\n"
7784 " Migrate froms to local server")
7788 rpc_printer_migrate_printers,
7790 N_("Migrate printers to local server"),
7791 N_("net rpc printer migrate printers\n"
7792 " Migrate printers to local server")
7796 rpc_printer_migrate_security,
7798 N_("Mirgate printer ACLs to local server"),
7799 N_("net rpc printer migrate security\n"
7800 " Mirgate printer ACLs to local server")
7804 rpc_printer_migrate_settings,
7806 N_("Migrate printer settings to local server"),
7807 N_("net rpc printer migrate settings\n"
7808 " Migrate printer settings to local server")
7810 {NULL, NULL, 0, NULL, NULL}
7813 return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7818 * List printers on a remote RPC server.
7820 * @param c A net_context structure.
7821 * @param argc Standard main() style argc.
7822 * @param argv Standard main() style argv. Initial components are already
7825 * @return A shell status integer (0 for success).
7827 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7829 if (c->display_usage) {
7831 "net rpc printer list\n"
7834 _("List printers on a remote RPC server"));
7838 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7839 rpc_printer_list_internals,
7844 * List printer-drivers on a remote RPC server.
7846 * @param c A net_context structure.
7847 * @param argc Standard main() style argc.
7848 * @param argv Standard main() style argv. Initial components are already
7851 * @return A shell status integer (0 for success).
7853 static int rpc_printer_driver_list(struct net_context *c, int argc,
7856 if (c->display_usage) {
7858 "net rpc printer driver\n"
7861 _("List printer-drivers on a remote RPC server"));
7865 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7866 rpc_printer_driver_list_internals,
7871 * Publish printer in ADS via MSRPC.
7873 * @param c A net_context structure.
7874 * @param argc Standard main() style argc.
7875 * @param argv Standard main() style argv. Initial components are already
7878 * @return A shell status integer (0 for success).
7880 static int rpc_printer_publish_publish(struct net_context *c, int argc,
7883 if (c->display_usage) {
7885 "net rpc printer publish publish\n"
7888 _("Publish printer in ADS via MSRPC"));
7892 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7893 rpc_printer_publish_publish_internals,
7898 * Update printer in ADS via MSRPC.
7900 * @param c A net_context structure.
7901 * @param argc Standard main() style argc.
7902 * @param argv Standard main() style argv. Initial components are already
7905 * @return A shell status integer (0 for success).
7907 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7909 if (c->display_usage) {
7911 "net rpc printer publish update\n"
7914 _("Update printer in ADS via MSRPC"));
7918 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7919 rpc_printer_publish_update_internals,
7924 * UnPublish printer in ADS via MSRPC.
7926 * @param c A net_context structure.
7927 * @param argc Standard main() style argc.
7928 * @param argv Standard main() style argv. Initial components are already
7931 * @return A shell status integer (0 for success).
7933 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7936 if (c->display_usage) {
7938 "net rpc printer publish unpublish\n"
7941 _("UnPublish printer in ADS via MSRPC"));
7945 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7946 rpc_printer_publish_unpublish_internals,
7951 * List published printers via MSRPC.
7953 * @param c A net_context structure.
7954 * @param argc Standard main() style argc.
7955 * @param argv Standard main() style argv. Initial components are already
7958 * @return A shell status integer (0 for success).
7960 static int rpc_printer_publish_list(struct net_context *c, int argc,
7963 if (c->display_usage) {
7965 "net rpc printer publish list\n"
7968 _("List published printers via MSRPC"));
7972 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7973 rpc_printer_publish_list_internals,
7979 * Publish printer in ADS.
7981 * @param c A net_context structure.
7982 * @param argc Standard main() style argc.
7983 * @param argv Standard main() style argv. Initial components are already
7986 * @return A shell status integer (0 for success).
7988 static int rpc_printer_publish(struct net_context *c, int argc,
7992 struct functable func[] = {
7995 rpc_printer_publish_publish,
7997 N_("Publish printer in AD"),
7998 N_("net rpc printer publish publish\n"
7999 " Publish printer in AD")
8003 rpc_printer_publish_update,
8005 N_("Update printer in AD"),
8006 N_("net rpc printer publish update\n"
8007 " Update printer in AD")
8011 rpc_printer_publish_unpublish,
8013 N_("Unpublish printer"),
8014 N_("net rpc printer publish unpublish\n"
8015 " Unpublish printer")
8019 rpc_printer_publish_list,
8021 N_("List published printers"),
8022 N_("net rpc printer publish list\n"
8023 " List published printers")
8025 {NULL, NULL, 0, NULL, NULL}
8029 if (c->display_usage) {
8030 d_printf(_("Usage:\n"));
8031 d_printf(_("net rpc printer publish\n"
8032 " List published printers\n"
8033 " Alias of net rpc printer publish "
8035 net_display_usage_from_functable(func);
8038 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8039 rpc_printer_publish_list_internals,
8043 return net_run_function(c, argc, argv, "net rpc printer publish",func);
8049 * Display rpc printer help page.
8051 * @param c A net_context structure.
8052 * @param argc Standard main() style argc.
8053 * @param argv Standard main() style argv. Initial components are already
8056 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
8058 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
8059 "\tlists all printers on print-server\n\n"));
8060 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
8061 "\tlists all printer-drivers on print-server\n\n"));
8062 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
8063 "\tpublishes printer settings in Active Directory\n"
8064 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
8065 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
8066 "\n\tmigrates printers from remote to local server\n\n"));
8067 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
8068 "\n\tmigrates printer-settings from remote to local server\n\n"));
8069 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
8070 "\n\tmigrates printer-drivers from remote to local server\n\n"));
8071 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
8072 "\n\tmigrates printer-forms from remote to local server\n\n"));
8073 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
8074 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
8075 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
8076 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
8077 "\tremote to local print-server\n\n"));
8078 net_common_methods_usage(c, argc, argv);
8079 net_common_flags_usage(c, argc, argv);
8081 "\t-v or --verbose\t\t\tgive verbose output\n"
8082 "\t --destination\t\tmigration target server (default: localhost)\n"));
8088 * 'net rpc printer' entrypoint.
8090 * @param c A net_context structure.
8091 * @param argc Standard main() style argc.
8092 * @param argv Standard main() style argv. Initial components are already
8095 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
8097 struct functable func[] = {
8102 N_("List all printers on print server"),
8103 N_("net rpc printer list\n"
8104 " List all printers on print server")
8108 rpc_printer_migrate,
8110 N_("Migrate printer to local server"),
8111 N_("net rpc printer migrate\n"
8112 " Migrate printer to local server")
8116 rpc_printer_driver_list,
8118 N_("List printer drivers"),
8119 N_("net rpc printer driver\n"
8120 " List printer drivers")
8124 rpc_printer_publish,
8126 N_("Publish printer in AD"),
8127 N_("net rpc printer publish\n"
8128 " Publish printer in AD")
8130 {NULL, NULL, 0, NULL, NULL}
8134 if (c->display_usage) {
8135 d_printf(_("Usage:\n"));
8136 d_printf(_("net rpc printer\n"
8137 " List printers\n"));
8138 net_display_usage_from_functable(func);
8141 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8142 rpc_printer_list_internals,
8146 return net_run_function(c, argc, argv, "net rpc printer", func);
8150 * 'net rpc' entrypoint.
8152 * @param c A net_context structure.
8153 * @param argc Standard main() style argc.
8154 * @param argv Standard main() style argv. Initial components are already
8158 int net_rpc(struct net_context *c, int argc, const char **argv)
8160 NET_API_STATUS status;
8162 struct functable func[] = {
8167 N_("Modify global audit settings"),
8168 N_("net rpc audit\n"
8169 " Modify global audit settings")
8175 N_("Show basic info about a domain"),
8177 " Show basic info about a domain")
8183 N_("Join a domain"),
8191 N_("Join a domain created in server manager"),
8192 N_("net rpc oldjoin\n"
8193 " Join a domain created in server manager")
8199 N_("Test that a join is valid"),
8200 N_("net rpc testjoin\n"
8201 " Test that a join is valid")
8207 N_("List/modify users"),
8209 " List/modify users")
8215 N_("Change a user password"),
8216 N_("net rpc password\n"
8217 " Change a user password\n"
8218 " Alias for net rpc user password")
8224 N_("List/modify groups"),
8225 N_("net rpc group\n"
8226 " List/modify groups")
8232 N_("List/modify shares"),
8233 N_("net rpc share\n"
8234 " List/modify shares")
8240 N_("List open files"),
8248 N_("List/modify printers"),
8249 N_("net rpc printer\n"
8250 " List/modify printers")
8254 net_rpc_changetrustpw,
8256 N_("Change trust account password"),
8257 N_("net rpc changetrustpw\n"
8258 " Change trust account password")
8264 N_("Modify domain trusts"),
8265 N_("net rpc trustdom\n"
8266 " Modify domain trusts")
8272 N_("Abort a remote shutdown"),
8273 N_("net rpc abortshutdown\n"
8274 " Abort a remote shutdown")
8280 N_("Shutdown a remote server"),
8281 N_("net rpc shutdown\n"
8282 " Shutdown a remote server")
8288 N_("Sync a remote NT PDC's data into local passdb"),
8289 N_("net rpc vampire\n"
8290 " Sync a remote NT PDC's data into local passdb")
8296 N_("Fetch the domain sid into local secrets.tdb"),
8297 N_("net rpc getsid\n"
8298 " Fetch the domain sid into local secrets.tdb")
8304 N_("Manage privileges assigned to SID"),
8305 N_("net rpc rights\n"
8306 " Manage privileges assigned to SID")
8312 N_("Start/stop/query remote services"),
8313 N_("net rpc service\n"
8314 " Start/stop/query remote services")
8320 N_("Manage registry hives"),
8321 N_("net rpc registry\n"
8322 " Manage registry hives")
8328 N_("Open interactive shell on remote server"),
8329 N_("net rpc shell\n"
8330 " Open interactive shell on remote server")
8336 N_("Manage trusts"),
8337 N_("net rpc trust\n"
8344 N_("Configure a remote samba server"),
8346 " Configure a remote samba server")
8348 {NULL, NULL, 0, NULL, NULL}
8351 status = libnetapi_net_init(&c->netapi_ctx);
8355 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
8356 libnetapi_set_password(c->netapi_ctx, c->opt_password);
8357 if (c->opt_kerberos) {
8358 libnetapi_set_use_kerberos(c->netapi_ctx);
8360 if (c->opt_ccache) {
8361 libnetapi_set_use_ccache(c->netapi_ctx);
8364 return net_run_function(c, argc, argv, "net rpc", func);