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 "rpc_client/cli_pipe.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/cli_samr.h"
29 #include "rpc_client/init_samr.h"
30 #include "../librpc/gen_ndr/ndr_lsa_c.h"
31 #include "rpc_client/cli_lsarpc.h"
32 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
33 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
34 #include "../librpc/gen_ndr/ndr_spoolss.h"
35 #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
36 #include "../librpc/gen_ndr/ndr_winreg_c.h"
38 #include "lib/netapi/netapi.h"
39 #include "lib/netapi/netapi_net.h"
40 #include "librpc/gen_ndr/libnet_join.h"
41 #include "libnet/libnet_join.h"
42 #include "rpc_client/init_lsa.h"
43 #include "../libcli/security/security.h"
44 #include "libsmb/libsmb.h"
45 #include "libsmb/clirap.h"
46 #include "nsswitch/libwbclient/wbclient.h"
48 #include "../libcli/smb/smbXcli_base.h"
50 static int net_mode_share
;
51 static NTSTATUS
sync_files(struct copy_clistate
*cp_clistate
, const char *mask
);
56 * @brief RPC based subcommands for the 'net' utility.
58 * This file should contain much of the functionality that used to
59 * be found in rpcclient, execpt that the commands should change
60 * less often, and the fucntionality should be sane (the user is not
61 * expected to know a rid/sid before they conduct an operation etc.)
63 * @todo Perhaps eventually these should be split out into a number
64 * of files, as this could get quite big.
69 * Many of the RPC functions need the domain sid. This function gets
70 * it at the start of every run
72 * @param cli A cli_state already connected to the remote machine
74 * @return The Domain SID of the remote machine.
77 NTSTATUS
net_get_remote_domain_sid(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
78 struct dom_sid
**domain_sid
,
79 const char **domain_name
)
81 struct rpc_pipe_client
*lsa_pipe
= NULL
;
82 struct policy_handle pol
;
83 NTSTATUS status
, result
;
84 union lsa_PolicyInformation
*info
= NULL
;
85 struct dcerpc_binding_handle
*b
;
87 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
89 if (!NT_STATUS_IS_OK(status
)) {
90 d_fprintf(stderr
, _("Could not initialise lsa pipe\n"));
94 b
= lsa_pipe
->binding_handle
;
96 status
= rpccli_lsa_open_policy(lsa_pipe
, mem_ctx
, false,
97 SEC_FLAG_MAXIMUM_ALLOWED
,
99 if (!NT_STATUS_IS_OK(status
)) {
100 d_fprintf(stderr
, "open_policy %s: %s\n",
106 status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
108 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
111 if (!NT_STATUS_IS_OK(status
)) {
112 d_fprintf(stderr
, "lsaquery %s: %s\n",
117 if (!NT_STATUS_IS_OK(result
)) {
118 d_fprintf(stderr
, "lsaquery %s: %s\n",
124 *domain_name
= info
->account_domain
.name
.string
;
125 *domain_sid
= info
->account_domain
.sid
;
127 dcerpc_lsa_Close(b
, mem_ctx
, &pol
, &result
);
128 TALLOC_FREE(lsa_pipe
);
134 * Run a single RPC command, from start to finish.
136 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
137 * @param conn_flag a NET_FLAG_ combination. Passed to
138 * net_make_ipc_connection.
139 * @param argc Standard main() style argc.
140 * @param argv Standard main() style argv. Initial components are already
142 * @return A shell status integer (0 for success).
145 int run_rpc_command(struct net_context
*c
,
146 struct cli_state
*cli_arg
,
147 const struct ndr_interface_table
*table
,
153 struct cli_state
*cli
= NULL
;
154 struct rpc_pipe_client
*pipe_hnd
= NULL
;
157 struct dom_sid
*domain_sid
;
158 const char *domain_name
;
161 /* make use of cli_state handed over as an argument, if possible */
163 nt_status
= net_make_ipc_connection(c
, conn_flags
, &cli
);
164 if (!NT_STATUS_IS_OK(nt_status
)) {
165 DEBUG(1, ("failed to make ipc connection: %s\n",
166 nt_errstr(nt_status
)));
179 if (!(mem_ctx
= talloc_init("run_rpc_command"))) {
180 DEBUG(0, ("talloc_init() failed\n"));
184 nt_status
= net_get_remote_domain_sid(cli
, mem_ctx
, &domain_sid
,
186 if (!NT_STATUS_IS_OK(nt_status
)) {
190 if (!(conn_flags
& NET_FLAGS_NO_PIPE
)) {
191 if (lp_client_schannel()
192 && (ndr_syntax_id_equal(&table
->syntax_id
,
193 &ndr_table_netlogon
.syntax_id
))) {
194 /* Always try and create an schannel netlogon pipe. */
195 TALLOC_FREE(c
->netlogon_creds
);
196 nt_status
= cli_rpc_pipe_open_schannel(
197 cli
, c
->msg_ctx
, table
, NCACN_NP
,
198 DCERPC_AUTH_LEVEL_PRIVACY
, domain_name
,
199 &pipe_hnd
, c
, &c
->netlogon_creds
);
200 if (!NT_STATUS_IS_OK(nt_status
)) {
201 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
202 nt_errstr(nt_status
) ));
206 if (conn_flags
& NET_FLAGS_SEAL
) {
207 nt_status
= cli_rpc_pipe_open_generic_auth(
209 (conn_flags
& NET_FLAGS_TCP
) ?
210 NCACN_IP_TCP
: NCACN_NP
,
211 DCERPC_AUTH_TYPE_NTLMSSP
,
212 DCERPC_AUTH_LEVEL_PRIVACY
,
213 smbXcli_conn_remote_name(cli
->conn
),
214 lp_workgroup(), c
->opt_user_name
,
215 c
->opt_password
, &pipe_hnd
);
217 nt_status
= cli_rpc_pipe_open_noauth(
221 if (!NT_STATUS_IS_OK(nt_status
)) {
222 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
224 nt_errstr(nt_status
) ));
230 nt_status
= fn(c
, domain_sid
, domain_name
, cli
, pipe_hnd
, mem_ctx
, argc
, argv
);
232 if (!NT_STATUS_IS_OK(nt_status
)) {
233 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status
)));
236 DEBUG(5, ("rpc command function succedded\n"));
239 if (!(conn_flags
& NET_FLAGS_NO_PIPE
)) {
241 TALLOC_FREE(pipe_hnd
);
246 /* close the connection only if it was opened here */
251 talloc_destroy(mem_ctx
);
256 * Force a change of the trust acccount password.
258 * All parameters are provided by the run_rpc_command function, except for
259 * argc, argv which are passed through.
261 * @param domain_sid The domain sid acquired from the remote server.
262 * @param cli A cli_state connected to the server.
263 * @param mem_ctx Talloc context, destroyed on completion of the function.
264 * @param argc Standard main() style argc.
265 * @param argv Standard main() style argv. Initial components are already
268 * @return Normal NTSTATUS return.
271 static NTSTATUS
rpc_changetrustpw_internals(struct net_context
*c
,
272 const struct dom_sid
*domain_sid
,
273 const char *domain_name
,
274 struct cli_state
*cli
,
275 struct rpc_pipe_client
*pipe_hnd
,
282 status
= trust_pw_change(c
->netlogon_creds
,
284 pipe_hnd
->binding_handle
,
285 c
->opt_target_workgroup
,
287 if (!NT_STATUS_IS_OK(status
)) {
288 d_fprintf(stderr
, _("Failed to change machine account password: %s\n"),
297 * Force a change of the trust acccount password.
299 * @param argc Standard main() style argc.
300 * @param argv Standard main() style argv. Initial components are already
303 * @return A shell status integer (0 for success).
306 int net_rpc_changetrustpw(struct net_context
*c
, int argc
, const char **argv
)
308 if (c
->display_usage
) {
310 "net rpc changetrustpw\n"
313 _("Change the machine trust password"));
317 return run_rpc_command(c
, NULL
, &ndr_table_netlogon
,
318 NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
,
319 rpc_changetrustpw_internals
,
324 * Join a domain, the old way. This function exists to allow
325 * the message to be displayed when oldjoin was explicitly
326 * requested, but not when it was implied by "net rpc join".
328 * This uses 'machinename' as the inital password, and changes it.
330 * The password should be created with 'server manager' or equiv first.
332 * @param argc Standard main() style argc.
333 * @param argv Standard main() style argv. Initial components are already
336 * @return A shell status integer (0 for success).
339 static int net_rpc_oldjoin(struct net_context
*c
, int argc
, const char **argv
)
341 struct libnet_JoinCtx
*r
= NULL
;
344 const char *domain
= lp_workgroup(); /* FIXME */
345 bool modify_config
= lp_config_backend_is_registry();
346 enum netr_SchannelType sec_chan_type
;
349 if (c
->display_usage
) {
352 " Join a domain the old way\n");
356 mem_ctx
= talloc_init("net_rpc_oldjoin");
361 werr
= libnet_init_JoinCtx(mem_ctx
, &r
);
362 if (!W_ERROR_IS_OK(werr
)) {
367 check what type of join - if the user want's to join as
368 a BDC, the server must agree that we are a BDC.
371 sec_chan_type
= get_sec_channel_type(argv
[0]);
373 sec_chan_type
= get_sec_channel_type(NULL
);
377 d_fprintf(stderr
, _("Could not initialise message context. "
378 "Try running as root\n"));
379 werr
= WERR_ACCESS_DENIED
;
383 pw
= talloc_strndup(r
, lp_netbios_name(), 14);
389 r
->in
.msg_ctx
= c
->msg_ctx
;
390 r
->in
.domain_name
= domain
;
391 r
->in
.secure_channel_type
= sec_chan_type
;
392 r
->in
.dc_name
= c
->opt_host
;
393 r
->in
.admin_account
= "";
394 r
->in
.admin_password
= strlower_talloc(r
, pw
);
395 if (r
->in
.admin_password
== NULL
) {
400 r
->in
.modify_config
= modify_config
;
401 r
->in
.join_flags
= WKSSVC_JOIN_FLAGS_JOIN_TYPE
|
402 WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
|
403 WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
;
405 werr
= libnet_Join(mem_ctx
, r
);
406 if (!W_ERROR_IS_OK(werr
)) {
410 /* Check the short name of the domain */
412 if (!modify_config
&& !strequal(lp_workgroup(), r
->out
.netbios_domain_name
)) {
413 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
414 d_printf("domain name obtained from the server.\n");
415 d_printf("Using the name [%s] from the server.\n", r
->out
.netbios_domain_name
);
416 d_printf("You should set \"workgroup = %s\" in %s.\n",
417 r
->out
.netbios_domain_name
, get_dyn_CONFIGFILE());
420 d_printf("Using short domain name -- %s\n", r
->out
.netbios_domain_name
);
422 if (r
->out
.dns_domain_name
) {
423 d_printf("Joined '%s' to realm '%s'\n", r
->in
.machine_name
,
424 r
->out
.dns_domain_name
);
426 d_printf("Joined '%s' to domain '%s'\n", r
->in
.machine_name
,
427 r
->out
.netbios_domain_name
);
430 TALLOC_FREE(mem_ctx
);
435 if (c
->opt_flags
& NET_FLAGS_EXPECT_FALLBACK
) {
439 /* issue an overall failure message at the end. */
440 d_fprintf(stderr
, _("Failed to join domain: %s\n"),
441 r
&& r
->out
.error_string
? r
->out
.error_string
:
442 get_friendly_werror_msg(werr
));
445 TALLOC_FREE(mem_ctx
);
451 * check that a join is OK
453 * @return A shell status integer (0 for success)
456 int net_rpc_testjoin(struct net_context
*c
, int argc
, const char **argv
)
460 const char *domain
= c
->opt_target_workgroup
;
461 const char *dc
= c
->opt_host
;
463 if (c
->display_usage
) {
466 " Test if a join is OK\n");
470 mem_ctx
= talloc_init("net_rpc_testjoin");
476 struct netr_DsRGetDCNameInfo
*info
;
479 d_fprintf(stderr
, _("Could not initialise message context. "
480 "Try running as root\n"));
481 talloc_destroy(mem_ctx
);
485 status
= dsgetdcname(mem_ctx
,
492 if (!NT_STATUS_IS_OK(status
)) {
493 talloc_destroy(mem_ctx
);
497 dc
= strip_hostname(info
->dc_unc
);
500 /* Display success or failure */
501 status
= libnet_join_ok(c
->msg_ctx
,
505 if (!NT_STATUS_IS_OK(status
)) {
506 fprintf(stderr
,"Join to domain '%s' is not valid: %s\n",
507 domain
, nt_errstr(status
));
508 talloc_destroy(mem_ctx
);
512 printf("Join to '%s' is OK\n",domain
);
513 talloc_destroy(mem_ctx
);
519 * Join a domain using the administrator username and password
521 * @param argc Standard main() style argc
522 * @param argc Standard main() style argv. Initial components are already
523 * stripped. Currently not used.
524 * @return A shell status integer (0 for success)
528 static int net_rpc_join_newstyle(struct net_context
*c
, int argc
, const char **argv
)
530 struct libnet_JoinCtx
*r
= NULL
;
533 const char *domain
= lp_workgroup(); /* FIXME */
534 bool modify_config
= lp_config_backend_is_registry();
535 enum netr_SchannelType sec_chan_type
;
537 if (c
->display_usage
) {
540 " Join a domain the new way\n");
544 mem_ctx
= talloc_init("net_rpc_join_newstyle");
549 werr
= libnet_init_JoinCtx(mem_ctx
, &r
);
550 if (!W_ERROR_IS_OK(werr
)) {
555 check what type of join - if the user want's to join as
556 a BDC, the server must agree that we are a BDC.
559 sec_chan_type
= get_sec_channel_type(argv
[0]);
561 sec_chan_type
= get_sec_channel_type(NULL
);
565 d_fprintf(stderr
, _("Could not initialise message context. "
566 "Try running as root\n"));
567 werr
= WERR_ACCESS_DENIED
;
571 r
->in
.msg_ctx
= c
->msg_ctx
;
572 r
->in
.domain_name
= domain
;
573 r
->in
.secure_channel_type
= sec_chan_type
;
574 r
->in
.dc_name
= c
->opt_host
;
575 r
->in
.admin_account
= c
->opt_user_name
;
576 r
->in
.admin_password
= net_prompt_pass(c
, c
->opt_user_name
);
578 r
->in
.use_kerberos
= c
->opt_kerberos
;
579 r
->in
.modify_config
= modify_config
;
580 r
->in
.join_flags
= WKSSVC_JOIN_FLAGS_JOIN_TYPE
|
581 WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE
|
582 WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED
;
584 werr
= libnet_Join(mem_ctx
, r
);
585 if (!W_ERROR_IS_OK(werr
)) {
589 /* Check the short name of the domain */
591 if (!modify_config
&& !strequal(lp_workgroup(), r
->out
.netbios_domain_name
)) {
592 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
593 d_printf("domain name obtained from the server.\n");
594 d_printf("Using the name [%s] from the server.\n", r
->out
.netbios_domain_name
);
595 d_printf("You should set \"workgroup = %s\" in %s.\n",
596 r
->out
.netbios_domain_name
, get_dyn_CONFIGFILE());
599 d_printf("Using short domain name -- %s\n", r
->out
.netbios_domain_name
);
601 if (r
->out
.dns_domain_name
) {
602 d_printf("Joined '%s' to realm '%s'\n", r
->in
.machine_name
,
603 r
->out
.dns_domain_name
);
605 d_printf("Joined '%s' to domain '%s'\n", r
->in
.machine_name
,
606 r
->out
.netbios_domain_name
);
609 TALLOC_FREE(mem_ctx
);
614 /* issue an overall failure message at the end. */
615 d_printf("Failed to join domain: %s\n",
616 r
&& r
->out
.error_string
? r
->out
.error_string
:
617 get_friendly_werror_msg(werr
));
619 TALLOC_FREE(mem_ctx
);
625 * 'net rpc join' entrypoint.
626 * @param argc Standard main() style argc.
627 * @param argv Standard main() style argv. Initial components are already
630 * Main 'net_rpc_join()' (where the admin username/password is used) is
632 * Try to just change the password, but if that doesn't work, use/prompt
633 * for a username/password.
636 int net_rpc_join(struct net_context
*c
, int argc
, const char **argv
)
640 if (c
->display_usage
) {
643 _("net rpc join -U <username>[%%password] <type>\n"
645 " username\tName of the admin user"
646 " password\tPassword of the admin user, will "
647 "prompt if not specified\n"
648 " type\tCan be one of the following:\n"
649 "\t\tMEMBER\tJoin as member server (default)\n"
650 "\t\tBDC\tJoin as BDC\n"
651 "\t\tPDC\tJoin as PDC\n"));
655 if (lp_server_role() == ROLE_STANDALONE
) {
656 d_printf(_("cannot join as standalone machine\n"));
660 if (strlen(lp_netbios_name()) > 15) {
661 d_printf(_("Our netbios name can be at most 15 chars long, "
662 "\"%s\" is %u chars long\n"),
663 lp_netbios_name(), (unsigned int)strlen(lp_netbios_name()));
667 c
->opt_flags
|= NET_FLAGS_EXPECT_FALLBACK
;
668 ret
= net_rpc_oldjoin(c
, argc
, argv
);
669 c
->opt_flags
&= ~NET_FLAGS_EXPECT_FALLBACK
;
674 return net_rpc_join_newstyle(c
, argc
, argv
);
678 * display info about a rpc domain
680 * All parameters are provided by the run_rpc_command function, except for
681 * argc, argv which are passed through.
683 * @param domain_sid The domain sid acquired from the remote server
684 * @param cli A cli_state connected to the server.
685 * @param mem_ctx Talloc context, destroyed on completion of the function.
686 * @param argc Standard main() style argc.
687 * @param argv Standard main() style argv. Initial components are already
690 * @return Normal NTSTATUS return.
693 NTSTATUS
rpc_info_internals(struct net_context
*c
,
694 const struct dom_sid
*domain_sid
,
695 const char *domain_name
,
696 struct cli_state
*cli
,
697 struct rpc_pipe_client
*pipe_hnd
,
702 struct policy_handle connect_pol
, domain_pol
;
703 NTSTATUS status
, result
;
704 union samr_DomainInfo
*info
= NULL
;
706 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
708 sid_to_fstring(sid_str
, domain_sid
);
710 /* Get sam policy handle */
711 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
713 MAXIMUM_ALLOWED_ACCESS
,
716 if (!NT_STATUS_IS_OK(status
)) {
717 d_fprintf(stderr
, _("Could not connect to SAM: %s\n"),
722 if (!NT_STATUS_IS_OK(result
)) {
724 d_fprintf(stderr
, _("Could not connect to SAM: %s\n"),
729 /* Get domain policy handle */
730 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
732 MAXIMUM_ALLOWED_ACCESS
,
733 discard_const_p(struct dom_sid2
, domain_sid
),
736 if (!NT_STATUS_IS_OK(status
)) {
737 d_fprintf(stderr
, _("Could not open domain: %s\n"),
741 if (!NT_STATUS_IS_OK(result
)) {
743 d_fprintf(stderr
, _("Could not open domain: %s\n"),
748 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
753 if (!NT_STATUS_IS_OK(status
)) {
757 if (NT_STATUS_IS_OK(result
)) {
758 d_printf(_("Domain Name: %s\n"),
759 info
->general
.domain_name
.string
);
760 d_printf(_("Domain SID: %s\n"), sid_str
);
761 d_printf(_("Sequence number: %llu\n"),
762 (unsigned long long)info
->general
.sequence_num
);
763 d_printf(_("Num users: %u\n"), info
->general
.num_users
);
764 d_printf(_("Num domain groups: %u\n"),info
->general
.num_groups
);
765 d_printf(_("Num local groups: %u\n"),info
->general
.num_aliases
);
773 * 'net rpc info' entrypoint.
774 * @param argc Standard main() style argc.
775 * @param argv Standard main() style argv. Initial components are already
779 int net_rpc_info(struct net_context
*c
, int argc
, const char **argv
)
781 if (c
->display_usage
) {
786 _("Display information about the domain"));
790 return run_rpc_command(c
, NULL
, &ndr_table_samr
,
791 NET_FLAGS_PDC
, rpc_info_internals
,
796 * Fetch domain SID into the local secrets.tdb.
798 * All parameters are provided by the run_rpc_command function, except for
799 * argc, argv which are passed through.
801 * @param domain_sid The domain sid acquired from the remote server.
802 * @param cli A cli_state connected to the server.
803 * @param mem_ctx Talloc context, destroyed on completion of the function.
804 * @param argc Standard main() style argc.
805 * @param argv Standard main() style argv. Initial components are already
808 * @return Normal NTSTATUS return.
811 static NTSTATUS
rpc_getsid_internals(struct net_context
*c
,
812 const struct dom_sid
*domain_sid
,
813 const char *domain_name
,
814 struct cli_state
*cli
,
815 struct rpc_pipe_client
*pipe_hnd
,
822 sid_to_fstring(sid_str
, domain_sid
);
823 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
824 sid_str
, domain_name
);
826 if (!secrets_store_domain_sid(domain_name
, domain_sid
)) {
827 DEBUG(0,("Can't store domain SID\n"));
828 return NT_STATUS_UNSUCCESSFUL
;
835 * 'net rpc getsid' entrypoint.
836 * @param argc Standard main() style argc.
837 * @param argv Standard main() style argv. Initial components are already
841 int net_rpc_getsid(struct net_context
*c
, int argc
, const char **argv
)
843 int conn_flags
= NET_FLAGS_PDC
;
845 if (!c
->opt_user_specified
) {
846 conn_flags
|= NET_FLAGS_ANONYMOUS
;
849 if (c
->display_usage
) {
854 _("Fetch domain SID into local secrets.tdb"));
858 return run_rpc_command(c
, NULL
, &ndr_table_samr
,
860 rpc_getsid_internals
,
864 /****************************************************************************/
867 * Basic usage function for 'net rpc user'.
868 * @param argc Standard main() style argc.
869 * @param argv Standard main() style argv. Initial components are already
873 static int rpc_user_usage(struct net_context
*c
, int argc
, const char **argv
)
875 return net_user_usage(c
, argc
, argv
);
879 * Add a new user to a remote RPC server.
881 * @param argc Standard main() style argc.
882 * @param argv Standard main() style argv. Initial components are already
885 * @return A shell status integer (0 for success).
888 static int rpc_user_add(struct net_context
*c
, int argc
, const char **argv
)
890 NET_API_STATUS status
;
891 struct USER_INFO_1 info1
;
892 uint32_t parm_error
= 0;
894 if (argc
< 1 || c
->display_usage
) {
895 rpc_user_usage(c
, argc
, argv
);
901 info1
.usri1_name
= argv
[0];
903 info1
.usri1_password
= argv
[1];
906 status
= NetUserAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
909 d_fprintf(stderr
,_("Failed to add user '%s' with error: %s.\n"),
910 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
914 d_printf(_("Added user '%s'.\n"), argv
[0]);
921 * Rename a user on a remote RPC server.
923 * @param argc Standard main() style argc.
924 * @param argv Standard main() style argv. Initial components are already
927 * @return A shell status integer (0 for success).
930 static int rpc_user_rename(struct net_context
*c
, int argc
, const char **argv
)
932 NET_API_STATUS status
;
933 struct USER_INFO_0 u0
;
934 uint32_t parm_err
= 0;
936 if (argc
!= 2 || c
->display_usage
) {
937 rpc_user_usage(c
, argc
, argv
);
941 u0
.usri0_name
= argv
[1];
943 status
= NetUserSetInfo(c
->opt_host
, argv
[0],
944 0, (uint8_t *)&u0
, &parm_err
);
947 _("Failed to rename user from %s to %s - %s\n"),
949 libnetapi_get_error_string(c
->netapi_ctx
, status
));
951 d_printf(_("Renamed user from %s to %s\n"), argv
[0], argv
[1]);
958 * Set a user's primary group
960 * @param argc Standard main() style argc.
961 * @param argv Standard main() style argv. Initial components are already
964 * @return A shell status integer (0 for success).
967 static int rpc_user_setprimarygroup(struct net_context
*c
, int argc
,
970 NET_API_STATUS status
;
972 struct GROUP_INFO_2
*g2
;
973 struct USER_INFO_1051 u1051
;
974 uint32_t parm_err
= 0;
976 if (argc
!= 2 || c
->display_usage
) {
977 rpc_user_usage(c
, argc
, argv
);
981 status
= NetGroupGetInfo(c
->opt_host
, argv
[1], 2, &buffer
);
983 d_fprintf(stderr
, _("Failed to find group name %s -- %s\n"),
985 libnetapi_get_error_string(c
->netapi_ctx
, status
));
988 g2
= (struct GROUP_INFO_2
*)buffer
;
990 u1051
.usri1051_primary_group_id
= g2
->grpi2_group_id
;
992 NetApiBufferFree(buffer
);
994 status
= NetUserSetInfo(c
->opt_host
, argv
[0], 1051,
995 (uint8_t *)&u1051
, &parm_err
);
998 _("Failed to set user's primary group %s to %s - "
999 "%s\n"), argv
[0], argv
[1],
1000 libnetapi_get_error_string(c
->netapi_ctx
, status
));
1002 d_printf(_("Set primary group of user %s to %s\n"), argv
[0],
1009 * Delete a user from a remote RPC server.
1011 * @param argc Standard main() style argc.
1012 * @param argv Standard main() style argv. Initial components are already
1015 * @return A shell status integer (0 for success).
1018 static int rpc_user_delete(struct net_context
*c
, int argc
, const char **argv
)
1020 NET_API_STATUS status
;
1022 if (argc
< 1 || c
->display_usage
) {
1023 rpc_user_usage(c
, argc
, argv
);
1027 status
= NetUserDel(c
->opt_host
, argv
[0]);
1030 d_fprintf(stderr
, _("Failed to delete user '%s' with: %s.\n"),
1032 libnetapi_get_error_string(c
->netapi_ctx
, status
));
1035 d_printf(_("Deleted user '%s'.\n"), argv
[0]);
1042 * Set a user's password on a remote RPC server.
1044 * @param argc Standard main() style argc.
1045 * @param argv Standard main() style argv. Initial components are already
1048 * @return A shell status integer (0 for success).
1051 static int rpc_user_password(struct net_context
*c
, int argc
, const char **argv
)
1053 NET_API_STATUS status
;
1054 char *prompt
= NULL
;
1055 struct USER_INFO_1003 u1003
;
1056 uint32_t parm_err
= 0;
1059 if (argc
< 1 || c
->display_usage
) {
1060 rpc_user_usage(c
, argc
, argv
);
1065 u1003
.usri1003_password
= argv
[1];
1067 char pwd
[256] = {0};
1068 ret
= asprintf(&prompt
, _("Enter new password for %s:"),
1074 ret
= samba_getpass(prompt
, pwd
, sizeof(pwd
), false, false);
1080 u1003
.usri1003_password
= talloc_strdup(c
, pwd
);
1081 if (u1003
.usri1003_password
== NULL
) {
1086 status
= NetUserSetInfo(c
->opt_host
, argv
[0], 1003, (uint8_t *)&u1003
, &parm_err
);
1088 /* Display results */
1091 _("Failed to set password for '%s' with error: %s.\n"),
1092 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
1101 * List a user's groups from a remote RPC server.
1103 * @param argc Standard main() style argc.
1104 * @param argv Standard main() style argv. Initial components are already
1107 * @return A shell status integer (0 for success)
1110 static int rpc_user_info(struct net_context
*c
, int argc
, const char **argv
)
1113 NET_API_STATUS status
;
1114 struct GROUP_USERS_INFO_0
*u0
= NULL
;
1115 uint32_t entries_read
= 0;
1116 uint32_t total_entries
= 0;
1120 if (argc
< 1 || c
->display_usage
) {
1121 rpc_user_usage(c
, argc
, argv
);
1125 status
= NetUserGetGroups(c
->opt_host
,
1128 (uint8_t **)(void *)&u0
,
1134 _("Failed to get groups for '%s' with error: %s.\n"),
1135 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
1140 for (i
=0; i
< entries_read
; i
++) {
1141 printf("%s\n", u0
->grui0_name
);
1149 * List users on a remote RPC server.
1151 * All parameters are provided by the run_rpc_command function, except for
1152 * argc, argv which are passed through.
1154 * @param domain_sid The domain sid acquired from the remote server.
1155 * @param cli A cli_state connected to the server.
1156 * @param mem_ctx Talloc context, destroyed on completion of the function.
1157 * @param argc Standard main() style argc.
1158 * @param argv Standard main() style argv. Initial components are already
1161 * @return Normal NTSTATUS return.
1164 static int rpc_user_list(struct net_context
*c
, int argc
, const char **argv
)
1166 NET_API_STATUS status
;
1167 uint32_t start_idx
=0, num_entries
, i
, loop_count
= 0;
1168 struct NET_DISPLAY_USER
*info
= NULL
;
1169 void *buffer
= NULL
;
1171 /* Query domain users */
1172 if (c
->opt_long_list_entries
)
1173 d_printf(_("\nUser name Comment"
1174 "\n-----------------------------\n"));
1176 uint32_t max_entries
, max_size
;
1178 dcerpc_get_query_dispinfo_params(
1179 loop_count
, &max_entries
, &max_size
);
1181 status
= NetQueryDisplayInformation(c
->opt_host
,
1188 if (status
!= 0 && status
!= ERROR_MORE_DATA
) {
1192 info
= (struct NET_DISPLAY_USER
*)buffer
;
1194 for (i
= 0; i
< num_entries
; i
++) {
1196 if (c
->opt_long_list_entries
)
1197 printf("%-21.21s %s\n", info
->usri1_name
,
1198 info
->usri1_comment
);
1200 printf("%s\n", info
->usri1_name
);
1204 NetApiBufferFree(buffer
);
1207 start_idx
+= num_entries
;
1209 } while (status
== ERROR_MORE_DATA
);
1215 * 'net rpc user' entrypoint.
1216 * @param argc Standard main() style argc.
1217 * @param argv Standard main() style argv. Initial components are already
1221 int net_rpc_user(struct net_context
*c
, int argc
, const char **argv
)
1223 NET_API_STATUS status
;
1225 struct functable func
[] = {
1230 N_("Add specified user"),
1231 N_("net rpc user add\n"
1232 " Add specified user")
1238 N_("List domain groups of user"),
1239 N_("net rpc user info\n"
1240 " List domain groups of user")
1246 N_("Remove specified user"),
1247 N_("net rpc user delete\n"
1248 " Remove specified user")
1254 N_("Change user password"),
1255 N_("net rpc user password\n"
1256 " Change user password")
1262 N_("Rename specified user"),
1263 N_("net rpc user rename\n"
1264 " Rename specified user")
1268 rpc_user_setprimarygroup
,
1270 "Set a user's primary group",
1271 "net rpc user setprimarygroup\n"
1272 " Set a user's primary group"
1274 {NULL
, NULL
, 0, NULL
, NULL
}
1277 status
= libnetapi_net_init(&c
->netapi_ctx
);
1281 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
1282 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
1283 if (c
->opt_kerberos
) {
1284 libnetapi_set_use_kerberos(c
->netapi_ctx
);
1288 if (c
->display_usage
) {
1293 _("List all users"));
1294 net_display_usage_from_functable(func
);
1298 return rpc_user_list(c
, argc
, argv
);
1301 return net_run_function(c
, argc
, argv
, "net rpc user", func
);
1304 static NTSTATUS
rpc_sh_user_list(struct net_context
*c
,
1305 TALLOC_CTX
*mem_ctx
,
1306 struct rpc_sh_ctx
*ctx
,
1307 struct rpc_pipe_client
*pipe_hnd
,
1308 int argc
, const char **argv
)
1310 return werror_to_ntstatus(W_ERROR(rpc_user_list(c
, argc
, argv
)));
1313 static NTSTATUS
rpc_sh_user_info(struct net_context
*c
,
1314 TALLOC_CTX
*mem_ctx
,
1315 struct rpc_sh_ctx
*ctx
,
1316 struct rpc_pipe_client
*pipe_hnd
,
1317 int argc
, const char **argv
)
1319 return werror_to_ntstatus(W_ERROR(rpc_user_info(c
, argc
, argv
)));
1322 static NTSTATUS
rpc_sh_handle_user(struct net_context
*c
,
1323 TALLOC_CTX
*mem_ctx
,
1324 struct rpc_sh_ctx
*ctx
,
1325 struct rpc_pipe_client
*pipe_hnd
,
1326 int argc
, const char **argv
,
1328 struct net_context
*c
,
1329 TALLOC_CTX
*mem_ctx
,
1330 struct rpc_sh_ctx
*ctx
,
1331 struct rpc_pipe_client
*pipe_hnd
,
1332 struct policy_handle
*user_hnd
,
1333 int argc
, const char **argv
))
1335 struct policy_handle connect_pol
, domain_pol
, user_pol
;
1336 NTSTATUS status
, result
;
1339 enum lsa_SidType type
;
1340 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1343 d_fprintf(stderr
, "%s %s <username>\n", _("Usage:"),
1345 return NT_STATUS_INVALID_PARAMETER
;
1348 ZERO_STRUCT(connect_pol
);
1349 ZERO_STRUCT(domain_pol
);
1350 ZERO_STRUCT(user_pol
);
1352 status
= net_rpc_lookup_name(c
, mem_ctx
, ctx
->cli
,
1353 argv
[0], NULL
, NULL
, &sid
, &type
);
1354 if (!NT_STATUS_IS_OK(status
)) {
1355 d_fprintf(stderr
, _("Could not lookup %s: %s\n"), argv
[0],
1360 if (type
!= SID_NAME_USER
) {
1361 d_fprintf(stderr
, _("%s is a %s, not a user\n"), argv
[0],
1362 sid_type_lookup(type
));
1363 status
= NT_STATUS_NO_SUCH_USER
;
1367 if (!sid_peek_check_rid(ctx
->domain_sid
, &sid
, &rid
)) {
1368 d_fprintf(stderr
, _("%s is not in our domain\n"), argv
[0]);
1369 status
= NT_STATUS_NO_SUCH_USER
;
1373 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
1375 MAXIMUM_ALLOWED_ACCESS
,
1378 if (!NT_STATUS_IS_OK(status
)) {
1381 if (!NT_STATUS_IS_OK(result
)) {
1386 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
1388 MAXIMUM_ALLOWED_ACCESS
,
1392 if (!NT_STATUS_IS_OK(status
)) {
1395 if (!NT_STATUS_IS_OK(result
)) {
1400 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
1402 MAXIMUM_ALLOWED_ACCESS
,
1406 if (!NT_STATUS_IS_OK(status
)) {
1409 if (!NT_STATUS_IS_OK(result
)) {
1414 status
= fn(c
, mem_ctx
, ctx
, pipe_hnd
, &user_pol
, argc
-1, argv
+1);
1417 if (is_valid_policy_hnd(&user_pol
)) {
1418 dcerpc_samr_Close(b
, mem_ctx
, &user_pol
, &result
);
1420 if (is_valid_policy_hnd(&domain_pol
)) {
1421 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
1423 if (is_valid_policy_hnd(&connect_pol
)) {
1424 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
1429 static NTSTATUS
rpc_sh_user_show_internals(struct net_context
*c
,
1430 TALLOC_CTX
*mem_ctx
,
1431 struct rpc_sh_ctx
*ctx
,
1432 struct rpc_pipe_client
*pipe_hnd
,
1433 struct policy_handle
*user_hnd
,
1434 int argc
, const char **argv
)
1436 NTSTATUS status
, result
;
1437 union samr_UserInfo
*info
= NULL
;
1438 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1441 d_fprintf(stderr
, "%s %s show <username>\n", _("Usage:"),
1443 return NT_STATUS_INVALID_PARAMETER
;
1446 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1451 if (!NT_STATUS_IS_OK(status
)) {
1454 if (!NT_STATUS_IS_OK(result
)) {
1458 d_printf(_("user rid: %d, group rid: %d\n"),
1460 info
->info21
.primary_gid
);
1465 static NTSTATUS
rpc_sh_user_show(struct net_context
*c
,
1466 TALLOC_CTX
*mem_ctx
,
1467 struct rpc_sh_ctx
*ctx
,
1468 struct rpc_pipe_client
*pipe_hnd
,
1469 int argc
, const char **argv
)
1471 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1472 rpc_sh_user_show_internals
);
1475 #define FETCHSTR(name, rec) \
1476 do { if (strequal(ctx->thiscmd, name)) { \
1477 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1480 #define SETSTR(name, rec, flag) \
1481 do { if (strequal(ctx->thiscmd, name)) { \
1482 init_lsa_String(&(info->info21.rec), argv[0]); \
1483 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1486 static NTSTATUS
rpc_sh_user_str_edit_internals(struct net_context
*c
,
1487 TALLOC_CTX
*mem_ctx
,
1488 struct rpc_sh_ctx
*ctx
,
1489 struct rpc_pipe_client
*pipe_hnd
,
1490 struct policy_handle
*user_hnd
,
1491 int argc
, const char **argv
)
1493 NTSTATUS status
, result
;
1494 const char *username
;
1495 const char *oldval
= "";
1496 union samr_UserInfo
*info
= NULL
;
1497 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1500 d_fprintf(stderr
, "%s %s <username> [new value|NULL]\n",
1501 _("Usage:"), ctx
->whoami
);
1502 return NT_STATUS_INVALID_PARAMETER
;
1505 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1510 if (!NT_STATUS_IS_OK(status
)) {
1513 if (!NT_STATUS_IS_OK(result
)) {
1517 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1519 FETCHSTR("fullname", full_name
);
1520 FETCHSTR("homedir", home_directory
);
1521 FETCHSTR("homedrive", home_drive
);
1522 FETCHSTR("logonscript", logon_script
);
1523 FETCHSTR("profilepath", profile_path
);
1524 FETCHSTR("description", description
);
1527 d_printf(_("%s's %s: [%s]\n"), username
, ctx
->thiscmd
, oldval
);
1531 if (strcmp(argv
[0], "NULL") == 0) {
1535 ZERO_STRUCT(info
->info21
);
1537 SETSTR("fullname", full_name
, FULL_NAME
);
1538 SETSTR("homedir", home_directory
, HOME_DIRECTORY
);
1539 SETSTR("homedrive", home_drive
, HOME_DRIVE
);
1540 SETSTR("logonscript", logon_script
, LOGON_SCRIPT
);
1541 SETSTR("profilepath", profile_path
, PROFILE_PATH
);
1542 SETSTR("description", description
, DESCRIPTION
);
1544 status
= dcerpc_samr_SetUserInfo(b
, mem_ctx
,
1549 if (!NT_STATUS_IS_OK(status
)) {
1555 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username
,
1556 ctx
->thiscmd
, oldval
, argv
[0]);
1563 #define HANDLEFLG(name, rec) \
1564 do { if (strequal(ctx->thiscmd, name)) { \
1565 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1567 newflags = oldflags | ACB_##rec; \
1569 newflags = oldflags & ~ACB_##rec; \
1572 static NTSTATUS
rpc_sh_user_str_edit(struct net_context
*c
,
1573 TALLOC_CTX
*mem_ctx
,
1574 struct rpc_sh_ctx
*ctx
,
1575 struct rpc_pipe_client
*pipe_hnd
,
1576 int argc
, const char **argv
)
1578 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1579 rpc_sh_user_str_edit_internals
);
1582 static NTSTATUS
rpc_sh_user_flag_edit_internals(struct net_context
*c
,
1583 TALLOC_CTX
*mem_ctx
,
1584 struct rpc_sh_ctx
*ctx
,
1585 struct rpc_pipe_client
*pipe_hnd
,
1586 struct policy_handle
*user_hnd
,
1587 int argc
, const char **argv
)
1589 NTSTATUS status
, result
;
1590 const char *username
;
1591 const char *oldval
= "unknown";
1592 uint32 oldflags
, newflags
;
1594 union samr_UserInfo
*info
= NULL
;
1595 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1598 ((argc
== 1) && !strequal(argv
[0], "yes") &&
1599 !strequal(argv
[0], "no"))) {
1600 /* TRANSATORS: The yes|no here are program keywords. Please do
1602 d_fprintf(stderr
, _("Usage: %s <username> [yes|no]\n"),
1604 return NT_STATUS_INVALID_PARAMETER
;
1607 newval
= strequal(argv
[0], "yes");
1609 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1614 if (!NT_STATUS_IS_OK(status
)) {
1617 if (!NT_STATUS_IS_OK(result
)) {
1621 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1622 oldflags
= info
->info21
.acct_flags
;
1623 newflags
= info
->info21
.acct_flags
;
1625 HANDLEFLG("disabled", DISABLED
);
1626 HANDLEFLG("pwnotreq", PWNOTREQ
);
1627 HANDLEFLG("autolock", AUTOLOCK
);
1628 HANDLEFLG("pwnoexp", PWNOEXP
);
1631 d_printf(_("%s's %s flag: %s\n"), username
, ctx
->thiscmd
,
1636 ZERO_STRUCT(info
->info21
);
1638 info
->info21
.acct_flags
= newflags
;
1639 info
->info21
.fields_present
= SAMR_FIELD_ACCT_FLAGS
;
1641 status
= dcerpc_samr_SetUserInfo(b
, mem_ctx
,
1646 if (!NT_STATUS_IS_OK(status
)) {
1650 if (NT_STATUS_IS_OK(result
)) {
1651 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username
,
1652 ctx
->thiscmd
, oldval
, argv
[0]);
1660 static NTSTATUS
rpc_sh_user_flag_edit(struct net_context
*c
,
1661 TALLOC_CTX
*mem_ctx
,
1662 struct rpc_sh_ctx
*ctx
,
1663 struct rpc_pipe_client
*pipe_hnd
,
1664 int argc
, const char **argv
)
1666 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1667 rpc_sh_user_flag_edit_internals
);
1670 struct rpc_sh_cmd
*net_rpc_user_edit_cmds(struct net_context
*c
,
1671 TALLOC_CTX
*mem_ctx
,
1672 struct rpc_sh_ctx
*ctx
)
1674 static struct rpc_sh_cmd cmds
[] = {
1676 { "fullname", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1677 N_("Show/Set a user's full name") },
1679 { "homedir", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1680 N_("Show/Set a user's home directory") },
1682 { "homedrive", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1683 N_("Show/Set a user's home drive") },
1685 { "logonscript", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1686 N_("Show/Set a user's logon script") },
1688 { "profilepath", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1689 N_("Show/Set a user's profile path") },
1691 { "description", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1692 N_("Show/Set a user's description") },
1694 { "disabled", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1695 N_("Show/Set whether a user is disabled") },
1697 { "autolock", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1698 N_("Show/Set whether a user locked out") },
1700 { "pwnotreq", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1701 N_("Show/Set whether a user does not need a password") },
1703 { "pwnoexp", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1704 N_("Show/Set whether a user's password does not expire") },
1706 { NULL
, NULL
, 0, NULL
, NULL
}
1712 struct rpc_sh_cmd
*net_rpc_user_cmds(struct net_context
*c
,
1713 TALLOC_CTX
*mem_ctx
,
1714 struct rpc_sh_ctx
*ctx
)
1716 static struct rpc_sh_cmd cmds
[] = {
1718 { "list", NULL
, &ndr_table_samr
, rpc_sh_user_list
,
1719 N_("List available users") },
1721 { "info", NULL
, &ndr_table_samr
, rpc_sh_user_info
,
1722 N_("List the domain groups a user is member of") },
1724 { "show", NULL
, &ndr_table_samr
, rpc_sh_user_show
,
1725 N_("Show info about a user") },
1727 { "edit", net_rpc_user_edit_cmds
, 0, NULL
,
1728 N_("Show/Modify a user's fields") },
1730 { NULL
, NULL
, 0, NULL
, NULL
}
1736 /****************************************************************************/
1739 * Basic usage function for 'net rpc group'.
1740 * @param argc Standard main() style argc.
1741 * @param argv Standard main() style argv. Initial components are already
1745 static int rpc_group_usage(struct net_context
*c
, int argc
, const char **argv
)
1747 return net_group_usage(c
, argc
, argv
);
1751 * Delete group on a remote RPC server.
1753 * All parameters are provided by the run_rpc_command function, except for
1754 * argc, argv which are passed through.
1756 * @param domain_sid The domain sid acquired from the remote server.
1757 * @param cli A cli_state connected to the server.
1758 * @param mem_ctx Talloc context, destroyed on completion of the function.
1759 * @param argc Standard main() style argc.
1760 * @param argv Standard main() style argv. Initial components are already
1763 * @return Normal NTSTATUS return.
1766 static NTSTATUS
rpc_group_delete_internals(struct net_context
*c
,
1767 const struct dom_sid
*domain_sid
,
1768 const char *domain_name
,
1769 struct cli_state
*cli
,
1770 struct rpc_pipe_client
*pipe_hnd
,
1771 TALLOC_CTX
*mem_ctx
,
1775 struct policy_handle connect_pol
, domain_pol
, group_pol
, user_pol
;
1776 bool group_is_primary
= false;
1777 NTSTATUS status
, result
;
1779 struct samr_RidAttrArray
*rids
= NULL
;
1782 /* struct samr_RidWithAttribute *user_gids; */
1783 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1785 struct samr_Ids group_rids
, name_types
;
1786 struct lsa_String lsa_acct_name
;
1787 union samr_UserInfo
*info
= NULL
;
1789 if (argc
< 1 || c
->display_usage
) {
1790 rpc_group_usage(c
, argc
,argv
);
1791 return NT_STATUS_OK
; /* ok? */
1794 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
1796 MAXIMUM_ALLOWED_ACCESS
,
1799 if (!NT_STATUS_IS_OK(status
)) {
1800 d_fprintf(stderr
, _("Request samr_Connect2 failed\n"));
1804 if (!NT_STATUS_IS_OK(result
)) {
1806 d_fprintf(stderr
, _("Request samr_Connect2 failed\n"));
1810 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
1812 MAXIMUM_ALLOWED_ACCESS
,
1813 discard_const_p(struct dom_sid2
, domain_sid
),
1816 if (!NT_STATUS_IS_OK(status
)) {
1817 d_fprintf(stderr
, _("Request open_domain failed\n"));
1821 if (!NT_STATUS_IS_OK(result
)) {
1823 d_fprintf(stderr
, _("Request open_domain failed\n"));
1827 init_lsa_String(&lsa_acct_name
, argv
[0]);
1829 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
1836 if (!NT_STATUS_IS_OK(status
)) {
1837 d_fprintf(stderr
, _("Lookup of '%s' failed\n"),argv
[0]);
1841 if (!NT_STATUS_IS_OK(result
)) {
1843 d_fprintf(stderr
, _("Lookup of '%s' failed\n"),argv
[0]);
1846 if (group_rids
.count
!= 1) {
1847 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
1850 if (name_types
.count
!= 1) {
1851 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
1855 switch (name_types
.ids
[0])
1857 case SID_NAME_DOM_GRP
:
1858 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
1860 MAXIMUM_ALLOWED_ACCESS
,
1864 if (!NT_STATUS_IS_OK(status
)) {
1865 d_fprintf(stderr
, _("Request open_group failed"));
1869 if (!NT_STATUS_IS_OK(result
)) {
1871 d_fprintf(stderr
, _("Request open_group failed"));
1875 group_rid
= group_rids
.ids
[0];
1877 status
= dcerpc_samr_QueryGroupMember(b
, mem_ctx
,
1881 if (!NT_STATUS_IS_OK(status
)) {
1883 _("Unable to query group members of %s"),
1888 if (!NT_STATUS_IS_OK(result
)) {
1891 _("Unable to query group members of %s"),
1896 if (c
->opt_verbose
) {
1898 _("Domain Group %s (rid: %d) has %d members\n"),
1899 argv
[0],group_rid
, rids
->count
);
1902 /* Check if group is anyone's primary group */
1903 for (i
= 0; i
< rids
->count
; i
++)
1905 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
1907 MAXIMUM_ALLOWED_ACCESS
,
1911 if (!NT_STATUS_IS_OK(status
)) {
1913 _("Unable to open group member %d\n"),
1918 if (!NT_STATUS_IS_OK(result
)) {
1921 _("Unable to open group member %d\n"),
1926 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1931 if (!NT_STATUS_IS_OK(status
)) {
1933 _("Unable to lookup userinfo for group "
1939 if (!NT_STATUS_IS_OK(result
)) {
1942 _("Unable to lookup userinfo for group "
1948 if (info
->info21
.primary_gid
== group_rid
) {
1949 if (c
->opt_verbose
) {
1950 d_printf(_("Group is primary group "
1952 info
->info21
.account_name
.string
);
1954 group_is_primary
= true;
1957 dcerpc_samr_Close(b
, mem_ctx
, &user_pol
, &result
);
1960 if (group_is_primary
) {
1961 d_fprintf(stderr
, _("Unable to delete group because "
1962 "some of it's members have it as primary "
1964 status
= NT_STATUS_MEMBERS_PRIMARY_GROUP
;
1968 /* remove all group members */
1969 for (i
= 0; i
< rids
->count
; i
++)
1972 d_printf(_("Remove group member %d..."),
1974 status
= dcerpc_samr_DeleteGroupMember(b
, mem_ctx
,
1978 if (!NT_STATUS_IS_OK(status
)) {
1982 if (NT_STATUS_IS_OK(result
)) {
1984 d_printf(_("ok\n"));
1987 d_printf("%s\n", _("failed"));
1992 status
= dcerpc_samr_DeleteDomainGroup(b
, mem_ctx
,
1995 if (!NT_STATUS_IS_OK(status
)) {
2002 /* removing a local group is easier... */
2003 case SID_NAME_ALIAS
:
2004 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2006 MAXIMUM_ALLOWED_ACCESS
,
2010 if (!NT_STATUS_IS_OK(status
)) {
2011 d_fprintf(stderr
, _("Request open_alias failed\n"));
2014 if (!NT_STATUS_IS_OK(result
)) {
2016 d_fprintf(stderr
, _("Request open_alias failed\n"));
2020 status
= dcerpc_samr_DeleteDomAlias(b
, mem_ctx
,
2023 if (!NT_STATUS_IS_OK(status
)) {
2031 d_fprintf(stderr
, _("%s is of type %s. This command is only "
2032 "for deleting local or global groups\n"),
2033 argv
[0],sid_type_lookup(name_types
.ids
[0]));
2034 status
= NT_STATUS_UNSUCCESSFUL
;
2038 if (NT_STATUS_IS_OK(status
)) {
2040 d_printf(_("Deleted %s '%s'\n"),
2041 sid_type_lookup(name_types
.ids
[0]), argv
[0]);
2043 d_fprintf(stderr
, _("Deleting of %s failed: %s\n"), argv
[0],
2044 get_friendly_nt_error_msg(status
));
2052 static int rpc_group_delete(struct net_context
*c
, int argc
, const char **argv
)
2054 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2055 rpc_group_delete_internals
, argc
,argv
);
2058 static int rpc_group_add_internals(struct net_context
*c
, int argc
, const char **argv
)
2060 NET_API_STATUS status
;
2061 struct GROUP_INFO_1 info1
;
2062 uint32_t parm_error
= 0;
2064 if (argc
!= 1 || c
->display_usage
) {
2065 rpc_group_usage(c
, argc
, argv
);
2071 info1
.grpi1_name
= argv
[0];
2072 if (c
->opt_comment
&& strlen(c
->opt_comment
) > 0) {
2073 info1
.grpi1_comment
= c
->opt_comment
;
2076 status
= NetGroupAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
2080 _("Failed to add group '%s' with error: %s.\n"),
2081 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
2085 d_printf(_("Added group '%s'.\n"), argv
[0]);
2091 static int rpc_alias_add_internals(struct net_context
*c
, int argc
, const char **argv
)
2093 NET_API_STATUS status
;
2094 struct LOCALGROUP_INFO_1 info1
;
2095 uint32_t parm_error
= 0;
2097 if (argc
!= 1 || c
->display_usage
) {
2098 rpc_group_usage(c
, argc
, argv
);
2104 info1
.lgrpi1_name
= argv
[0];
2105 if (c
->opt_comment
&& strlen(c
->opt_comment
) > 0) {
2106 info1
.lgrpi1_comment
= c
->opt_comment
;
2109 status
= NetLocalGroupAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
2113 _("Failed to add alias '%s' with error: %s.\n"),
2114 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
2118 d_printf(_("Added alias '%s'.\n"), argv
[0]);
2124 static int rpc_group_add(struct net_context
*c
, int argc
, const char **argv
)
2126 if (c
->opt_localgroup
)
2127 return rpc_alias_add_internals(c
, argc
, argv
);
2129 return rpc_group_add_internals(c
, argc
, argv
);
2132 static NTSTATUS
get_sid_from_name(struct cli_state
*cli
,
2133 TALLOC_CTX
*mem_ctx
,
2135 struct dom_sid
*sid
,
2136 enum lsa_SidType
*type
)
2138 struct dom_sid
*sids
= NULL
;
2139 enum lsa_SidType
*types
= NULL
;
2140 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2141 struct policy_handle lsa_pol
;
2142 NTSTATUS status
, result
;
2143 struct dcerpc_binding_handle
*b
;
2145 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
2147 if (!NT_STATUS_IS_OK(status
)) {
2151 b
= pipe_hnd
->binding_handle
;
2153 status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, false,
2154 SEC_FLAG_MAXIMUM_ALLOWED
, &lsa_pol
);
2156 if (!NT_STATUS_IS_OK(status
)) {
2160 status
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
2161 &name
, NULL
, 1, &sids
, &types
);
2163 if (NT_STATUS_IS_OK(status
)) {
2164 sid_copy(sid
, &sids
[0]);
2168 dcerpc_lsa_Close(b
, mem_ctx
, &lsa_pol
, &result
);
2172 TALLOC_FREE(pipe_hnd
);
2175 if (!NT_STATUS_IS_OK(status
) && (strncasecmp_m(name
, "S-", 2) == 0)) {
2177 /* Try as S-1-5-whatever */
2179 struct dom_sid tmp_sid
;
2181 if (string_to_sid(&tmp_sid
, name
)) {
2182 sid_copy(sid
, &tmp_sid
);
2183 *type
= SID_NAME_UNKNOWN
;
2184 status
= NT_STATUS_OK
;
2191 static NTSTATUS
rpc_add_groupmem(struct rpc_pipe_client
*pipe_hnd
,
2192 TALLOC_CTX
*mem_ctx
,
2193 const struct dom_sid
*group_sid
,
2196 struct policy_handle connect_pol
, domain_pol
;
2197 NTSTATUS status
, result
;
2199 struct policy_handle group_pol
;
2200 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2202 struct samr_Ids rids
, rid_types
;
2203 struct lsa_String lsa_acct_name
;
2207 sid_copy(&sid
, group_sid
);
2209 if (!sid_split_rid(&sid
, &group_rid
)) {
2210 return NT_STATUS_UNSUCCESSFUL
;
2213 /* Get sam policy handle */
2214 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2216 MAXIMUM_ALLOWED_ACCESS
,
2219 if (!NT_STATUS_IS_OK(status
)) {
2222 if (!NT_STATUS_IS_OK(result
)) {
2226 /* Get domain policy handle */
2227 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2229 MAXIMUM_ALLOWED_ACCESS
,
2233 if (!NT_STATUS_IS_OK(status
)) {
2236 if (!NT_STATUS_IS_OK(result
)) {
2240 init_lsa_String(&lsa_acct_name
, member
);
2242 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
2249 if (!NT_STATUS_IS_OK(status
)) {
2250 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2255 if (!NT_STATUS_IS_OK(result
)) {
2257 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2261 if (rids
.count
!= 1) {
2262 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2265 if (rid_types
.count
!= 1) {
2266 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2270 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
2272 MAXIMUM_ALLOWED_ACCESS
,
2276 if (!NT_STATUS_IS_OK(status
)) {
2280 if (!NT_STATUS_IS_OK(result
)) {
2285 status
= dcerpc_samr_AddGroupMember(b
, mem_ctx
,
2288 0x0005, /* unknown flags */
2290 if (!NT_STATUS_IS_OK(status
)) {
2297 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2301 static NTSTATUS
rpc_add_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2302 struct cli_state
*cli
,
2303 TALLOC_CTX
*mem_ctx
,
2304 const struct dom_sid
*alias_sid
,
2307 struct policy_handle connect_pol
, domain_pol
;
2308 NTSTATUS status
, result
;
2310 struct policy_handle alias_pol
;
2311 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2313 struct dom_sid member_sid
;
2314 enum lsa_SidType member_type
;
2318 sid_copy(&sid
, alias_sid
);
2320 if (!sid_split_rid(&sid
, &alias_rid
)) {
2321 return NT_STATUS_UNSUCCESSFUL
;
2324 result
= get_sid_from_name(cli
, mem_ctx
,
2325 member
, &member_sid
, &member_type
);
2327 if (!NT_STATUS_IS_OK(result
)) {
2328 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2333 /* Get sam policy handle */
2334 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2336 MAXIMUM_ALLOWED_ACCESS
,
2339 if (!NT_STATUS_IS_OK(status
)) {
2342 if (!NT_STATUS_IS_OK(result
)) {
2347 /* Get domain policy handle */
2348 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2350 MAXIMUM_ALLOWED_ACCESS
,
2354 if (!NT_STATUS_IS_OK(status
)) {
2357 if (!NT_STATUS_IS_OK(result
)) {
2362 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2364 MAXIMUM_ALLOWED_ACCESS
,
2368 if (!NT_STATUS_IS_OK(status
)) {
2371 if (!NT_STATUS_IS_OK(result
)) {
2375 status
= dcerpc_samr_AddAliasMember(b
, mem_ctx
,
2379 if (!NT_STATUS_IS_OK(status
)) {
2386 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2390 static NTSTATUS
rpc_group_addmem_internals(struct net_context
*c
,
2391 const struct dom_sid
*domain_sid
,
2392 const char *domain_name
,
2393 struct cli_state
*cli
,
2394 struct rpc_pipe_client
*pipe_hnd
,
2395 TALLOC_CTX
*mem_ctx
,
2399 struct dom_sid group_sid
;
2400 enum lsa_SidType group_type
;
2402 if (argc
!= 2 || c
->display_usage
) {
2405 _("net rpc group addmem <group> <member>\n"
2406 " Add a member to a group\n"
2407 " group\tGroup to add member to\n"
2408 " member\tMember to add to group\n"));
2409 return NT_STATUS_UNSUCCESSFUL
;
2412 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2413 &group_sid
, &group_type
))) {
2414 d_fprintf(stderr
, _("Could not lookup group name %s\n"),
2416 return NT_STATUS_UNSUCCESSFUL
;
2419 if (group_type
== SID_NAME_DOM_GRP
) {
2420 NTSTATUS result
= rpc_add_groupmem(pipe_hnd
, mem_ctx
,
2421 &group_sid
, argv
[1]);
2423 if (!NT_STATUS_IS_OK(result
)) {
2424 d_fprintf(stderr
, _("Could not add %s to %s: %s\n"),
2425 argv
[1], argv
[0], nt_errstr(result
));
2430 if (group_type
== SID_NAME_ALIAS
) {
2431 NTSTATUS result
= rpc_add_aliasmem(pipe_hnd
, cli
, mem_ctx
,
2432 &group_sid
, argv
[1]);
2434 if (!NT_STATUS_IS_OK(result
)) {
2435 d_fprintf(stderr
, _("Could not add %s to %s: %s\n"),
2436 argv
[1], argv
[0], nt_errstr(result
));
2441 d_fprintf(stderr
, _("Can only add members to global or local groups "
2442 "which %s is not\n"), argv
[0]);
2444 return NT_STATUS_UNSUCCESSFUL
;
2447 static int rpc_group_addmem(struct net_context
*c
, int argc
, const char **argv
)
2449 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2450 rpc_group_addmem_internals
,
2454 static NTSTATUS
rpc_del_groupmem(struct net_context
*c
,
2455 struct rpc_pipe_client
*pipe_hnd
,
2456 TALLOC_CTX
*mem_ctx
,
2457 const struct dom_sid
*group_sid
,
2460 struct policy_handle connect_pol
, domain_pol
;
2461 NTSTATUS status
, result
;
2463 struct policy_handle group_pol
;
2464 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2466 struct samr_Ids rids
, rid_types
;
2467 struct lsa_String lsa_acct_name
;
2471 sid_copy(&sid
, group_sid
);
2473 if (!sid_split_rid(&sid
, &group_rid
))
2474 return NT_STATUS_UNSUCCESSFUL
;
2476 /* Get sam policy handle */
2477 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2479 MAXIMUM_ALLOWED_ACCESS
,
2482 if (!NT_STATUS_IS_OK(status
)) {
2485 if (!NT_STATUS_IS_OK(result
)) {
2490 /* Get domain policy handle */
2491 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2493 MAXIMUM_ALLOWED_ACCESS
,
2497 if (!NT_STATUS_IS_OK(status
)) {
2500 if (!NT_STATUS_IS_OK(result
)) {
2504 init_lsa_String(&lsa_acct_name
, member
);
2506 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
2513 if (!NT_STATUS_IS_OK(status
)) {
2514 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2519 if (!NT_STATUS_IS_OK(result
)) {
2521 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2525 if (rids
.count
!= 1) {
2526 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2529 if (rid_types
.count
!= 1) {
2530 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2534 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
2536 MAXIMUM_ALLOWED_ACCESS
,
2540 if (!NT_STATUS_IS_OK(status
)) {
2543 if (!NT_STATUS_IS_OK(result
)) {
2548 status
= dcerpc_samr_DeleteGroupMember(b
, mem_ctx
,
2552 if (!NT_STATUS_IS_OK(status
)) {
2558 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2562 static NTSTATUS
rpc_del_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2563 struct cli_state
*cli
,
2564 TALLOC_CTX
*mem_ctx
,
2565 const struct dom_sid
*alias_sid
,
2568 struct policy_handle connect_pol
, domain_pol
;
2569 NTSTATUS status
, result
;
2571 struct policy_handle alias_pol
;
2572 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2574 struct dom_sid member_sid
;
2575 enum lsa_SidType member_type
;
2579 sid_copy(&sid
, alias_sid
);
2581 if (!sid_split_rid(&sid
, &alias_rid
))
2582 return NT_STATUS_UNSUCCESSFUL
;
2584 result
= get_sid_from_name(cli
, mem_ctx
,
2585 member
, &member_sid
, &member_type
);
2587 if (!NT_STATUS_IS_OK(result
)) {
2588 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2593 /* Get sam policy handle */
2594 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2596 MAXIMUM_ALLOWED_ACCESS
,
2599 if (!NT_STATUS_IS_OK(status
)) {
2602 if (!NT_STATUS_IS_OK(result
)) {
2607 /* Get domain policy handle */
2608 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2610 MAXIMUM_ALLOWED_ACCESS
,
2614 if (!NT_STATUS_IS_OK(status
)) {
2617 if (!NT_STATUS_IS_OK(result
)) {
2622 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2624 MAXIMUM_ALLOWED_ACCESS
,
2628 if (!NT_STATUS_IS_OK(status
)) {
2632 if (!NT_STATUS_IS_OK(result
)) {
2636 status
= dcerpc_samr_DeleteAliasMember(b
, mem_ctx
,
2641 if (!NT_STATUS_IS_OK(status
)) {
2648 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2652 static NTSTATUS
rpc_group_delmem_internals(struct net_context
*c
,
2653 const struct dom_sid
*domain_sid
,
2654 const char *domain_name
,
2655 struct cli_state
*cli
,
2656 struct rpc_pipe_client
*pipe_hnd
,
2657 TALLOC_CTX
*mem_ctx
,
2661 struct dom_sid group_sid
;
2662 enum lsa_SidType group_type
;
2664 if (argc
!= 2 || c
->display_usage
) {
2667 _("net rpc group delmem <group> <member>\n"
2668 " Delete a member from a group\n"
2669 " group\tGroup to delete member from\n"
2670 " member\tMember to delete from group\n"));
2671 return NT_STATUS_UNSUCCESSFUL
;
2674 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2675 &group_sid
, &group_type
))) {
2676 d_fprintf(stderr
, _("Could not lookup group name %s\n"),
2678 return NT_STATUS_UNSUCCESSFUL
;
2681 if (group_type
== SID_NAME_DOM_GRP
) {
2682 NTSTATUS result
= rpc_del_groupmem(c
, pipe_hnd
, mem_ctx
,
2683 &group_sid
, argv
[1]);
2685 if (!NT_STATUS_IS_OK(result
)) {
2686 d_fprintf(stderr
, _("Could not del %s from %s: %s\n"),
2687 argv
[1], argv
[0], nt_errstr(result
));
2692 if (group_type
== SID_NAME_ALIAS
) {
2693 NTSTATUS result
= rpc_del_aliasmem(pipe_hnd
, cli
, mem_ctx
,
2694 &group_sid
, argv
[1]);
2696 if (!NT_STATUS_IS_OK(result
)) {
2697 d_fprintf(stderr
, _("Could not del %s from %s: %s\n"),
2698 argv
[1], argv
[0], nt_errstr(result
));
2703 d_fprintf(stderr
, _("Can only delete members from global or local "
2704 "groups which %s is not\n"), argv
[0]);
2706 return NT_STATUS_UNSUCCESSFUL
;
2709 static int rpc_group_delmem(struct net_context
*c
, int argc
, const char **argv
)
2711 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2712 rpc_group_delmem_internals
,
2717 * List groups on a remote RPC server.
2719 * All parameters are provided by the run_rpc_command function, except for
2720 * argc, argv which are passes through.
2722 * @param domain_sid The domain sid acquired from the remote server.
2723 * @param cli A cli_state connected to the server.
2724 * @param mem_ctx Talloc context, destroyed on completion of the function.
2725 * @param argc Standard main() style argc.
2726 * @param argv Standard main() style argv. Initial components are already
2729 * @return Normal NTSTATUS return.
2732 static NTSTATUS
rpc_group_list_internals(struct net_context
*c
,
2733 const struct dom_sid
*domain_sid
,
2734 const char *domain_name
,
2735 struct cli_state
*cli
,
2736 struct rpc_pipe_client
*pipe_hnd
,
2737 TALLOC_CTX
*mem_ctx
,
2741 struct policy_handle connect_pol
, domain_pol
;
2742 NTSTATUS status
, result
;
2743 uint32 start_idx
=0, max_entries
=250, num_entries
, i
, loop_count
= 0;
2744 struct samr_SamArray
*groups
= NULL
;
2745 bool global
= false;
2747 bool builtin
= false;
2748 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2750 if (c
->display_usage
) {
2753 _("net rpc group list [global] [local] [builtin]\n"
2754 " List groups on RPC server\n"
2755 " global\tList global groups\n"
2756 " local\tList local groups\n"
2757 " builtin\tList builtin groups\n"
2758 " If none of global, local or builtin is "
2759 "specified, all three options are considered "
2761 return NT_STATUS_OK
;
2770 for (i
=0; i
<argc
; i
++) {
2771 if (strequal(argv
[i
], "global"))
2774 if (strequal(argv
[i
], "local"))
2777 if (strequal(argv
[i
], "builtin"))
2781 /* Get sam policy handle */
2783 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2785 MAXIMUM_ALLOWED_ACCESS
,
2788 if (!NT_STATUS_IS_OK(status
)) {
2791 if (!NT_STATUS_IS_OK(result
)) {
2796 /* Get domain policy handle */
2798 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2800 MAXIMUM_ALLOWED_ACCESS
,
2801 discard_const_p(struct dom_sid2
, domain_sid
),
2804 if (!NT_STATUS_IS_OK(status
)) {
2807 if (!NT_STATUS_IS_OK(result
)) {
2812 /* Query domain groups */
2813 if (c
->opt_long_list_entries
)
2814 d_printf(_("\nGroup name Comment"
2815 "\n-----------------------------\n"));
2817 uint32_t max_size
, total_size
, returned_size
;
2818 union samr_DispInfo info
;
2822 dcerpc_get_query_dispinfo_params(
2823 loop_count
, &max_entries
, &max_size
);
2825 status
= dcerpc_samr_QueryDisplayInfo(b
, mem_ctx
,
2835 if (!NT_STATUS_IS_OK(status
)) {
2838 num_entries
= info
.info3
.count
;
2839 start_idx
+= info
.info3
.count
;
2841 if (!NT_STATUS_IS_OK(result
) &&
2842 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2845 for (i
= 0; i
< num_entries
; i
++) {
2847 const char *group
= NULL
;
2848 const char *desc
= NULL
;
2850 group
= info
.info3
.entries
[i
].account_name
.string
;
2851 desc
= info
.info3
.entries
[i
].description
.string
;
2853 if (c
->opt_long_list_entries
)
2854 printf("%-21.21s %-50.50s\n",
2857 printf("%s\n", group
);
2859 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2860 /* query domain aliases */
2865 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
2872 if (!NT_STATUS_IS_OK(status
)) {
2875 if (!NT_STATUS_IS_OK(result
) &&
2876 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2879 for (i
= 0; i
< num_entries
; i
++) {
2881 const char *description
= NULL
;
2883 if (c
->opt_long_list_entries
) {
2885 struct policy_handle alias_pol
;
2886 union samr_AliasInfo
*info
= NULL
;
2889 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2892 groups
->entries
[i
].idx
,
2895 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2896 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
2901 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2902 status
= dcerpc_samr_Close(b
, mem_ctx
,
2905 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2906 description
= info
->description
.string
;
2912 if (description
!= NULL
) {
2913 printf("%-21.21s %-50.50s\n",
2914 groups
->entries
[i
].name
.string
,
2917 printf("%s\n", groups
->entries
[i
].name
.string
);
2920 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2921 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
2922 /* Get builtin policy handle */
2924 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2926 MAXIMUM_ALLOWED_ACCESS
,
2927 discard_const_p(struct dom_sid2
, &global_sid_Builtin
),
2930 if (!NT_STATUS_IS_OK(status
)) {
2933 if (!NT_STATUS_IS_OK(result
)) {
2938 /* query builtin aliases */
2941 if (!builtin
) break;
2943 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
2950 if (!NT_STATUS_IS_OK(status
)) {
2953 if (!NT_STATUS_IS_OK(result
) &&
2954 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
2959 for (i
= 0; i
< num_entries
; i
++) {
2961 const char *description
= NULL
;
2963 if (c
->opt_long_list_entries
) {
2965 struct policy_handle alias_pol
;
2966 union samr_AliasInfo
*info
= NULL
;
2969 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2972 groups
->entries
[i
].idx
,
2975 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2976 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
2981 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2982 status
= dcerpc_samr_Close(b
, mem_ctx
,
2985 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2986 description
= info
->description
.string
;
2992 if (description
!= NULL
) {
2993 printf("%-21.21s %-50.50s\n",
2994 groups
->entries
[i
].name
.string
,
2997 printf("%s\n", groups
->entries
[i
].name
.string
);
3000 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
3008 static int rpc_group_list(struct net_context
*c
, int argc
, const char **argv
)
3010 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3011 rpc_group_list_internals
,
3015 static NTSTATUS
rpc_list_group_members(struct net_context
*c
,
3016 struct rpc_pipe_client
*pipe_hnd
,
3017 TALLOC_CTX
*mem_ctx
,
3018 const char *domain_name
,
3019 const struct dom_sid
*domain_sid
,
3020 struct policy_handle
*domain_pol
,
3023 NTSTATUS result
, status
;
3024 struct policy_handle group_pol
;
3025 uint32 num_members
, *group_rids
;
3027 struct samr_RidAttrArray
*rids
= NULL
;
3028 struct lsa_Strings names
;
3029 struct samr_Ids types
;
3030 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3033 sid_to_fstring(sid_str
, domain_sid
);
3035 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
3037 MAXIMUM_ALLOWED_ACCESS
,
3041 if (!NT_STATUS_IS_OK(status
)) {
3044 if (!NT_STATUS_IS_OK(result
)) {
3048 status
= dcerpc_samr_QueryGroupMember(b
, mem_ctx
,
3052 if (!NT_STATUS_IS_OK(status
)) {
3055 if (!NT_STATUS_IS_OK(result
)) {
3059 num_members
= rids
->count
;
3060 group_rids
= rids
->rids
;
3062 while (num_members
> 0) {
3063 int this_time
= 512;
3065 if (num_members
< this_time
)
3066 this_time
= num_members
;
3068 status
= dcerpc_samr_LookupRids(b
, mem_ctx
,
3075 if (!NT_STATUS_IS_OK(status
)) {
3078 if (!NT_STATUS_IS_OK(result
)) {
3081 if (names
.count
!= this_time
) {
3082 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3084 if (types
.count
!= this_time
) {
3085 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3087 /* We only have users as members, but make the output
3088 the same as the output of alias members */
3090 for (i
= 0; i
< this_time
; i
++) {
3092 if (c
->opt_long_list_entries
) {
3093 printf("%s-%d %s\\%s %d\n", sid_str
,
3094 group_rids
[i
], domain_name
,
3095 names
.names
[i
].string
,
3098 printf("%s\\%s\n", domain_name
,
3099 names
.names
[i
].string
);
3103 num_members
-= this_time
;
3107 return NT_STATUS_OK
;
3110 static NTSTATUS
rpc_list_alias_members(struct net_context
*c
,
3111 struct rpc_pipe_client
*pipe_hnd
,
3112 struct cli_state
*cli
,
3113 TALLOC_CTX
*mem_ctx
,
3114 struct policy_handle
*domain_pol
,
3117 NTSTATUS result
, status
;
3118 struct rpc_pipe_client
*lsa_pipe
;
3119 struct policy_handle alias_pol
, lsa_pol
;
3121 struct dom_sid
*alias_sids
;
3124 enum lsa_SidType
*types
;
3126 struct lsa_SidArray sid_array
;
3127 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3129 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
3131 MAXIMUM_ALLOWED_ACCESS
,
3135 if (!NT_STATUS_IS_OK(status
)) {
3138 if (!NT_STATUS_IS_OK(result
)) {
3142 status
= dcerpc_samr_GetMembersInAlias(b
, mem_ctx
,
3146 if (!NT_STATUS_IS_OK(status
)) {
3147 d_fprintf(stderr
, _("Couldn't list alias members\n"));
3150 if (!NT_STATUS_IS_OK(result
)) {
3151 d_fprintf(stderr
, _("Couldn't list alias members\n"));
3155 num_members
= sid_array
.num_sids
;
3157 if (num_members
== 0) {
3158 return NT_STATUS_OK
;
3161 result
= cli_rpc_pipe_open_noauth(cli
,
3164 if (!NT_STATUS_IS_OK(result
)) {
3165 d_fprintf(stderr
, _("Couldn't open LSA pipe. Error was %s\n"),
3166 nt_errstr(result
) );
3170 result
= rpccli_lsa_open_policy(lsa_pipe
, mem_ctx
, true,
3171 SEC_FLAG_MAXIMUM_ALLOWED
, &lsa_pol
);
3173 if (!NT_STATUS_IS_OK(result
)) {
3174 d_fprintf(stderr
, _("Couldn't open LSA policy handle\n"));
3175 TALLOC_FREE(lsa_pipe
);
3179 alias_sids
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_members
);
3181 d_fprintf(stderr
, _("Out of memory\n"));
3182 TALLOC_FREE(lsa_pipe
);
3183 return NT_STATUS_NO_MEMORY
;
3186 for (i
=0; i
<num_members
; i
++) {
3187 sid_copy(&alias_sids
[i
], sid_array
.sids
[i
].sid
);
3190 result
= rpccli_lsa_lookup_sids(lsa_pipe
, mem_ctx
, &lsa_pol
,
3191 num_members
, alias_sids
,
3192 &domains
, &names
, &types
);
3194 if (!NT_STATUS_IS_OK(result
) &&
3195 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3196 d_fprintf(stderr
, _("Couldn't lookup SIDs\n"));
3197 TALLOC_FREE(lsa_pipe
);
3201 for (i
= 0; i
< num_members
; i
++) {
3203 sid_to_fstring(sid_str
, &alias_sids
[i
]);
3205 if (c
->opt_long_list_entries
) {
3206 printf("%s %s\\%s %d\n", sid_str
,
3207 domains
[i
] ? domains
[i
] : _("*unknown*"),
3208 names
[i
] ? names
[i
] : _("*unknown*"), types
[i
]);
3211 printf("%s\\%s\n", domains
[i
], names
[i
]);
3213 printf("%s\n", sid_str
);
3217 TALLOC_FREE(lsa_pipe
);
3218 return NT_STATUS_OK
;
3221 static NTSTATUS
rpc_group_members_internals(struct net_context
*c
,
3222 const struct dom_sid
*domain_sid
,
3223 const char *domain_name
,
3224 struct cli_state
*cli
,
3225 struct rpc_pipe_client
*pipe_hnd
,
3226 TALLOC_CTX
*mem_ctx
,
3230 NTSTATUS result
, status
;
3231 struct policy_handle connect_pol
, domain_pol
;
3232 struct samr_Ids rids
, rid_types
;
3233 struct lsa_String lsa_acct_name
;
3234 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3236 /* Get sam policy handle */
3238 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
3240 MAXIMUM_ALLOWED_ACCESS
,
3243 if (!NT_STATUS_IS_OK(status
)) {
3246 if (!NT_STATUS_IS_OK(result
)) {
3250 /* Get domain policy handle */
3252 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
3254 MAXIMUM_ALLOWED_ACCESS
,
3255 discard_const_p(struct dom_sid2
, domain_sid
),
3258 if (!NT_STATUS_IS_OK(status
)) {
3261 if (!NT_STATUS_IS_OK(result
)) {
3265 init_lsa_String(&lsa_acct_name
, argv
[0]); /* sure? */
3267 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
3274 if (!NT_STATUS_IS_OK(status
)) {
3278 if (!NT_STATUS_IS_OK(result
)) {
3280 /* Ok, did not find it in the global sam, try with builtin */
3282 struct dom_sid sid_Builtin
;
3284 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
3286 sid_copy(&sid_Builtin
, &global_sid_Builtin
);
3288 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
3290 MAXIMUM_ALLOWED_ACCESS
,
3294 if (!NT_STATUS_IS_OK(status
)) {
3297 if (!NT_STATUS_IS_OK(result
)) {
3298 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3303 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
3310 if (!NT_STATUS_IS_OK(status
)) {
3313 if (!NT_STATUS_IS_OK(result
)) {
3314 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3320 if (rids
.count
!= 1) {
3321 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3323 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3325 if (rid_types
.count
!= 1) {
3326 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3328 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3332 if (rid_types
.ids
[0] == SID_NAME_DOM_GRP
) {
3333 return rpc_list_group_members(c
, pipe_hnd
, mem_ctx
, domain_name
,
3334 domain_sid
, &domain_pol
,
3338 if (rid_types
.ids
[0] == SID_NAME_ALIAS
) {
3339 return rpc_list_alias_members(c
, pipe_hnd
, cli
, mem_ctx
, &domain_pol
,
3343 return NT_STATUS_NO_SUCH_GROUP
;
3346 static int rpc_group_members(struct net_context
*c
, int argc
, const char **argv
)
3348 if (argc
!= 1 || c
->display_usage
) {
3349 return rpc_group_usage(c
, argc
, argv
);
3352 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3353 rpc_group_members_internals
,
3357 static int rpc_group_rename_internals(struct net_context
*c
, int argc
, const char **argv
)
3359 NET_API_STATUS status
;
3360 struct GROUP_INFO_0 g0
;
3364 d_printf(_("Usage:\n"));
3365 d_printf("net rpc group rename group newname\n");
3369 g0
.grpi0_name
= argv
[1];
3371 status
= NetGroupSetInfo(c
->opt_host
,
3378 d_fprintf(stderr
, _("Renaming group %s failed with: %s\n"),
3379 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
3387 static int rpc_group_rename(struct net_context
*c
, int argc
, const char **argv
)
3389 if (argc
!= 2 || c
->display_usage
) {
3390 return rpc_group_usage(c
, argc
, argv
);
3393 return rpc_group_rename_internals(c
, argc
, argv
);
3397 * 'net rpc group' entrypoint.
3398 * @param argc Standard main() style argc.
3399 * @param argv Standard main() style argv. Initial components are already
3403 int net_rpc_group(struct net_context
*c
, int argc
, const char **argv
)
3405 NET_API_STATUS status
;
3407 struct functable func
[] = {
3412 N_("Create specified group"),
3413 N_("net rpc group add\n"
3414 " Create specified group")
3420 N_("Delete specified group"),
3421 N_("net rpc group delete\n"
3422 " Delete specified group")
3428 N_("Add member to group"),
3429 N_("net rpc group addmem\n"
3430 " Add member to group")
3436 N_("Remove member from group"),
3437 N_("net rpc group delmem\n"
3438 " Remove member from group")
3445 N_("net rpc group list\n"
3452 N_("List group members"),
3453 N_("net rpc group members\n"
3454 " List group members")
3461 N_("net rpc group rename\n"
3464 {NULL
, NULL
, 0, NULL
, NULL
}
3467 status
= libnetapi_net_init(&c
->netapi_ctx
);
3471 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
3472 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
3473 if (c
->opt_kerberos
) {
3474 libnetapi_set_use_kerberos(c
->netapi_ctx
);
3478 if (c
->display_usage
) {
3479 d_printf(_("Usage:\n"));
3480 d_printf(_("net rpc group\n"
3481 " Alias for net rpc group list global "
3482 "local builtin\n"));
3483 net_display_usage_from_functable(func
);
3487 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3488 rpc_group_list_internals
,
3492 return net_run_function(c
, argc
, argv
, "net rpc group", func
);
3495 /****************************************************************************/
3497 static int rpc_share_usage(struct net_context
*c
, int argc
, const char **argv
)
3499 return net_share_usage(c
, argc
, argv
);
3503 * Add a share on a remote RPC server.
3505 * @param argc Standard main() style argc.
3506 * @param argv Standard main() style argv. Initial components are already
3509 * @return A shell status integer (0 for success).
3512 static int rpc_share_add(struct net_context
*c
, int argc
, const char **argv
)
3514 NET_API_STATUS status
;
3517 uint32 type
= STYPE_DISKTREE
; /* only allow disk shares to be added */
3518 uint32 num_users
=0, perms
=0;
3519 char *password
=NULL
; /* don't allow a share password */
3520 struct SHARE_INFO_2 i2
;
3521 uint32_t parm_error
= 0;
3523 if ((argc
< 1) || !strchr(argv
[0], '=') || c
->display_usage
) {
3524 return rpc_share_usage(c
, argc
, argv
);
3527 if ((sharename
= talloc_strdup(c
, argv
[0])) == NULL
) {
3531 path
= strchr(sharename
, '=');
3538 i2
.shi2_netname
= sharename
;
3539 i2
.shi2_type
= type
;
3540 i2
.shi2_remark
= c
->opt_comment
;
3541 i2
.shi2_permissions
= perms
;
3542 i2
.shi2_max_uses
= c
->opt_maxusers
;
3543 i2
.shi2_current_uses
= num_users
;
3544 i2
.shi2_path
= path
;
3545 i2
.shi2_passwd
= password
;
3547 status
= NetShareAdd(c
->opt_host
,
3552 printf(_("NetShareAdd failed with: %s\n"),
3553 libnetapi_get_error_string(c
->netapi_ctx
, status
));
3560 * Delete a share on a remote RPC server.
3562 * @param domain_sid The domain sid acquired from the remote server.
3563 * @param argc Standard main() style argc.
3564 * @param argv Standard main() style argv. Initial components are already
3567 * @return A shell status integer (0 for success).
3569 static int rpc_share_delete(struct net_context
*c
, int argc
, const char **argv
)
3571 if (argc
< 1 || c
->display_usage
) {
3572 return rpc_share_usage(c
, argc
, argv
);
3575 return NetShareDel(c
->opt_host
, argv
[0], 0);
3579 * Formatted print of share info
3581 * @param r pointer to SHARE_INFO_1 to format
3584 static void display_share_info_1(struct net_context
*c
,
3585 struct SHARE_INFO_1
*r
)
3587 if (c
->opt_long_list_entries
) {
3588 d_printf("%-12s %-8.8s %-50s\n",
3590 net_share_type_str(r
->shi1_type
& ~(STYPE_TEMPORARY
|STYPE_HIDDEN
)),
3593 d_printf("%s\n", r
->shi1_netname
);
3597 static WERROR
get_share_info(struct net_context
*c
,
3598 struct rpc_pipe_client
*pipe_hnd
,
3599 TALLOC_CTX
*mem_ctx
,
3603 struct srvsvc_NetShareInfoCtr
*info_ctr
)
3607 union srvsvc_NetShareInfo info
;
3608 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3610 /* no specific share requested, enumerate all */
3613 uint32_t preferred_len
= 0xffffffff;
3614 uint32_t total_entries
= 0;
3615 uint32_t resume_handle
= 0;
3617 info_ctr
->level
= level
;
3619 status
= dcerpc_srvsvc_NetShareEnumAll(b
, mem_ctx
,
3626 if (!NT_STATUS_IS_OK(status
)) {
3627 return ntstatus_to_werror(status
);
3632 /* request just one share */
3633 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
3640 if (!NT_STATUS_IS_OK(status
)) {
3641 result
= ntstatus_to_werror(status
);
3645 if (!W_ERROR_IS_OK(result
)) {
3650 ZERO_STRUCTP(info_ctr
);
3652 info_ctr
->level
= level
;
3657 struct srvsvc_NetShareCtr1
*ctr1
;
3659 ctr1
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr1
);
3660 W_ERROR_HAVE_NO_MEMORY(ctr1
);
3663 ctr1
->array
= info
.info1
;
3665 info_ctr
->ctr
.ctr1
= ctr1
;
3671 struct srvsvc_NetShareCtr2
*ctr2
;
3673 ctr2
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr2
);
3674 W_ERROR_HAVE_NO_MEMORY(ctr2
);
3677 ctr2
->array
= info
.info2
;
3679 info_ctr
->ctr
.ctr2
= ctr2
;
3685 struct srvsvc_NetShareCtr502
*ctr502
;
3687 ctr502
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr502
);
3688 W_ERROR_HAVE_NO_MEMORY(ctr502
);
3691 ctr502
->array
= info
.info502
;
3693 info_ctr
->ctr
.ctr502
= ctr502
;
3703 * 'net rpc share list' entrypoint.
3704 * @param argc Standard main() style argc.
3705 * @param argv Standard main() style argv. Initial components are already
3708 static int rpc_share_list(struct net_context
*c
, int argc
, const char **argv
)
3710 NET_API_STATUS status
;
3711 struct SHARE_INFO_1
*i1
= NULL
;
3712 uint32_t entries_read
= 0;
3713 uint32_t total_entries
= 0;
3714 uint32_t resume_handle
= 0;
3715 uint32_t i
, level
= 1;
3717 if (c
->display_usage
) {
3719 "net rpc share list\n"
3722 _("List shares on remote server"));
3726 status
= NetShareEnum(c
->opt_host
,
3728 (uint8_t **)(void *)&i1
,
3737 /* Display results */
3739 if (c
->opt_long_list_entries
) {
3741 "\nEnumerating shared resources (exports) on remote server:\n\n"
3742 "\nShare name Type Description\n"
3743 "---------- ---- -----------\n"));
3745 for (i
= 0; i
< entries_read
; i
++)
3746 display_share_info_1(c
, &i1
[i
]);
3751 static bool check_share_availability(struct cli_state
*cli
, const char *netname
)
3755 status
= cli_tree_connect(cli
, netname
, "A:", "", 0);
3756 if (!NT_STATUS_IS_OK(status
)) {
3757 d_printf(_("skipping [%s]: not a file share.\n"), netname
);
3761 status
= cli_tdis(cli
);
3762 if (!NT_STATUS_IS_OK(status
)) {
3763 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status
));
3770 static bool check_share_sanity(struct net_context
*c
, struct cli_state
*cli
,
3771 const char *netname
, uint32 type
)
3773 /* only support disk shares */
3774 if (! ( type
== STYPE_DISKTREE
|| type
== (STYPE_DISKTREE
| STYPE_HIDDEN
)) ) {
3775 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname
,
3780 /* skip builtin shares */
3781 /* FIXME: should print$ be added too ? */
3782 if (strequal(netname
,"IPC$") || strequal(netname
,"ADMIN$") ||
3783 strequal(netname
,"global"))
3786 if (c
->opt_exclude
&& in_list(netname
, c
->opt_exclude
, false)) {
3787 printf(_("excluding [%s]\n"), netname
);
3791 return check_share_availability(cli
, netname
);
3795 * Migrate shares from a remote RPC server to the local RPC server.
3797 * All parameters are provided by the run_rpc_command function, except for
3798 * argc, argv which are passed through.
3800 * @param domain_sid The domain sid acquired from the remote server.
3801 * @param cli A cli_state connected to the server.
3802 * @param mem_ctx Talloc context, destroyed on completion of the function.
3803 * @param argc Standard main() style argc.
3804 * @param argv Standard main() style argv. Initial components are already
3807 * @return Normal NTSTATUS return.
3810 static NTSTATUS
rpc_share_migrate_shares_internals(struct net_context
*c
,
3811 const struct dom_sid
*domain_sid
,
3812 const char *domain_name
,
3813 struct cli_state
*cli
,
3814 struct rpc_pipe_client
*pipe_hnd
,
3815 TALLOC_CTX
*mem_ctx
,
3820 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3821 struct srvsvc_NetShareInfoCtr ctr_src
;
3823 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
3824 struct cli_state
*cli_dst
= NULL
;
3825 uint32 level
= 502; /* includes secdesc */
3826 uint32_t parm_error
= 0;
3827 struct dcerpc_binding_handle
*b
;
3829 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3831 if (!W_ERROR_IS_OK(result
))
3834 /* connect destination PI_SRVSVC */
3835 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
,
3837 if (!NT_STATUS_IS_OK(nt_status
))
3840 b
= srvsvc_pipe
->binding_handle
;
3842 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
3844 union srvsvc_NetShareInfo info
;
3845 struct srvsvc_NetShareInfo502 info502
=
3846 ctr_src
.ctr
.ctr502
->array
[i
];
3848 /* reset error-code */
3849 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3851 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
3854 /* finally add the share on the dst server */
3856 printf(_("migrating: [%s], path: %s, comment: %s, without "
3858 info502
.name
, info502
.path
, info502
.comment
);
3860 info
.info502
= &info502
;
3862 nt_status
= dcerpc_srvsvc_NetShareAdd(b
, mem_ctx
,
3863 srvsvc_pipe
->desthost
,
3868 if (!NT_STATUS_IS_OK(nt_status
)) {
3869 printf(_("cannot add share: %s\n"),
3870 nt_errstr(nt_status
));
3873 if (W_ERROR_V(result
) == W_ERROR_V(WERR_FILE_EXISTS
)) {
3874 printf(_(" [%s] does already exist\n"),
3879 if (!W_ERROR_IS_OK(result
)) {
3880 nt_status
= werror_to_ntstatus(result
);
3881 printf(_("cannot add share: %s\n"),
3882 win_errstr(result
));
3888 nt_status
= NT_STATUS_OK
;
3892 cli_shutdown(cli_dst
);
3900 * Migrate shares from a RPC server to another.
3902 * @param argc Standard main() style argc.
3903 * @param argv Standard main() style argv. Initial components are already
3906 * @return A shell status integer (0 for success).
3908 static int rpc_share_migrate_shares(struct net_context
*c
, int argc
,
3911 if (c
->display_usage
) {
3913 "net rpc share migrate shares\n"
3916 _("Migrate shares to local server"));
3921 printf(_("no server to migrate\n"));
3925 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
3926 rpc_share_migrate_shares_internals
,
3933 * @param f file_info
3934 * @param mask current search mask
3935 * @param state arg-pointer
3938 static NTSTATUS
copy_fn(const char *mnt
, struct file_info
*f
,
3939 const char *mask
, void *state
)
3941 static NTSTATUS nt_status
;
3942 static struct copy_clistate
*local_state
;
3943 static fstring filename
, new_mask
;
3946 struct net_context
*c
;
3948 local_state
= (struct copy_clistate
*)state
;
3949 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3953 if (strequal(f
->name
, ".") || strequal(f
->name
, ".."))
3954 return NT_STATUS_OK
;
3956 DEBUG(3,("got mask: %s, name: %s\n", mask
, f
->name
));
3959 if (f
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
3961 DEBUG(3,("got dir: %s\n", f
->name
));
3963 fstrcpy(dir
, local_state
->cwd
);
3965 fstrcat(dir
, f
->name
);
3967 switch (net_mode_share
)
3969 case NET_MODE_SHARE_MIGRATE
:
3970 /* create that directory */
3971 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
3972 local_state
->cli_share_src
,
3973 local_state
->cli_share_dst
,
3975 c
->opt_acls
? true : false,
3976 c
->opt_attrs
? true : false,
3977 c
->opt_timestamps
? true:false,
3981 d_fprintf(stderr
, _("Unsupported mode %d\n"), net_mode_share
);
3982 return NT_STATUS_INTERNAL_ERROR
;
3985 if (!NT_STATUS_IS_OK(nt_status
)) {
3986 printf(_("could not handle dir %s: %s\n"),
3987 dir
, nt_errstr(nt_status
));
3991 /* search below that directory */
3992 if (strlcpy(new_mask
, dir
, sizeof(new_mask
)) >= sizeof(new_mask
)) {
3993 return NT_STATUS_NO_MEMORY
;
3995 if (strlcat(new_mask
, "\\*", sizeof(new_mask
)) >= sizeof(new_mask
)) {
3996 return NT_STATUS_NO_MEMORY
;
3999 old_dir
= local_state
->cwd
;
4000 local_state
->cwd
= dir
;
4001 nt_status
= sync_files(local_state
, new_mask
);
4002 if (!NT_STATUS_IS_OK(nt_status
)) {
4003 printf(_("could not handle files\n"));
4005 local_state
->cwd
= old_dir
;
4012 fstrcpy(filename
, local_state
->cwd
);
4013 fstrcat(filename
, "\\");
4014 fstrcat(filename
, f
->name
);
4016 DEBUG(3,("got file: %s\n", filename
));
4018 switch (net_mode_share
)
4020 case NET_MODE_SHARE_MIGRATE
:
4021 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
4022 local_state
->cli_share_src
,
4023 local_state
->cli_share_dst
,
4025 c
->opt_acls
? true : false,
4026 c
->opt_attrs
? true : false,
4027 c
->opt_timestamps
? true: false,
4031 d_fprintf(stderr
, _("Unsupported file mode %d\n"),
4033 return NT_STATUS_INTERNAL_ERROR
;
4036 if (!NT_STATUS_IS_OK(nt_status
))
4037 printf(_("could not handle file %s: %s\n"),
4038 filename
, nt_errstr(nt_status
));
4043 * sync files, can be called recursivly to list files
4044 * and then call copy_fn for each file
4046 * @param cp_clistate pointer to the copy_clistate we work with
4047 * @param mask the current search mask
4049 * @return Boolean result
4051 static NTSTATUS
sync_files(struct copy_clistate
*cp_clistate
, const char *mask
)
4053 struct cli_state
*targetcli
;
4054 char *targetpath
= NULL
;
4057 DEBUG(3,("calling cli_list with mask: %s\n", mask
));
4059 status
= cli_resolve_path(talloc_tos(), "", NULL
,
4060 cp_clistate
->cli_share_src
,
4061 mask
, &targetcli
, &targetpath
);
4062 if (!NT_STATUS_IS_OK(status
)) {
4063 d_fprintf(stderr
, _("cli_resolve_path %s failed with error: "
4065 mask
, nt_errstr(status
));
4069 status
= cli_list(targetcli
, targetpath
, cp_clistate
->attribute
,
4070 copy_fn
, cp_clistate
);
4071 if (!NT_STATUS_IS_OK(status
)) {
4072 d_fprintf(stderr
, _("listing %s failed with error: %s\n"),
4073 mask
, nt_errstr(status
));
4081 * Set the top level directory permissions before we do any further copies.
4082 * Should set up ACL inheritance.
4085 bool copy_top_level_perms(struct net_context
*c
,
4086 struct copy_clistate
*cp_clistate
,
4087 const char *sharename
)
4089 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4091 switch (net_mode_share
) {
4092 case NET_MODE_SHARE_MIGRATE
:
4093 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename
));
4094 nt_status
= net_copy_fileattr(c
,
4095 cp_clistate
->mem_ctx
,
4096 cp_clistate
->cli_share_src
,
4097 cp_clistate
->cli_share_dst
,
4099 c
->opt_acls
? true : false,
4100 c
->opt_attrs
? true : false,
4101 c
->opt_timestamps
? true: false,
4105 d_fprintf(stderr
, _("Unsupported mode %d\n"), net_mode_share
);
4109 if (!NT_STATUS_IS_OK(nt_status
)) {
4110 printf(_("Could handle directory attributes for top level "
4111 "directory of share %s. Error %s\n"),
4112 sharename
, nt_errstr(nt_status
));
4120 * Sync all files inside a remote share to another share (over smb).
4122 * All parameters are provided by the run_rpc_command function, except for
4123 * argc, argv which are passed through.
4125 * @param domain_sid The domain sid acquired from the remote server.
4126 * @param cli A cli_state connected to the server.
4127 * @param mem_ctx Talloc context, destroyed on completion of the function.
4128 * @param argc Standard main() style argc.
4129 * @param argv Standard main() style argv. Initial components are already
4132 * @return Normal NTSTATUS return.
4135 static NTSTATUS
rpc_share_migrate_files_internals(struct net_context
*c
,
4136 const struct dom_sid
*domain_sid
,
4137 const char *domain_name
,
4138 struct cli_state
*cli
,
4139 struct rpc_pipe_client
*pipe_hnd
,
4140 TALLOC_CTX
*mem_ctx
,
4145 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4146 struct srvsvc_NetShareInfoCtr ctr_src
;
4149 struct copy_clistate cp_clistate
;
4150 bool got_src_share
= false;
4151 bool got_dst_share
= false;
4152 const char *mask
= "\\*";
4155 dst
= SMB_STRDUP(c
->opt_destination
?c
->opt_destination
:"127.0.0.1");
4157 nt_status
= NT_STATUS_NO_MEMORY
;
4161 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
4164 if (!W_ERROR_IS_OK(result
))
4167 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
4169 struct srvsvc_NetShareInfo502 info502
=
4170 ctr_src
.ctr
.ctr502
->array
[i
];
4172 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
4175 /* one might not want to mirror whole discs :) */
4176 if (strequal(info502
.name
, "print$") || info502
.name
[1] == '$') {
4177 d_printf(_("skipping [%s]: builtin/hidden share\n"),
4182 switch (net_mode_share
)
4184 case NET_MODE_SHARE_MIGRATE
:
4188 d_fprintf(stderr
, _("Unsupported mode %d\n"),
4192 printf(_(" [%s] files and directories %s ACLs, %s DOS "
4195 c
->opt_acls
? _("including") : _("without"),
4196 c
->opt_attrs
? _("including") : _("without"),
4197 c
->opt_timestamps
? _("(preserving timestamps)") : "");
4199 cp_clistate
.mem_ctx
= mem_ctx
;
4200 cp_clistate
.cli_share_src
= NULL
;
4201 cp_clistate
.cli_share_dst
= NULL
;
4202 cp_clistate
.cwd
= NULL
;
4203 cp_clistate
.attribute
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_DIRECTORY
;
4206 /* open share source */
4207 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_src
,
4208 smbXcli_conn_remote_sockaddr(cli
->conn
),
4209 smbXcli_conn_remote_name(cli
->conn
),
4210 info502
.name
, "A:");
4211 if (!NT_STATUS_IS_OK(nt_status
))
4214 got_src_share
= true;
4216 if (net_mode_share
== NET_MODE_SHARE_MIGRATE
) {
4217 /* open share destination */
4218 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_dst
,
4219 NULL
, dst
, info502
.name
, "A:");
4220 if (!NT_STATUS_IS_OK(nt_status
))
4223 got_dst_share
= true;
4226 if (!copy_top_level_perms(c
, &cp_clistate
, info502
.name
)) {
4227 d_fprintf(stderr
, _("Could not handle the top level "
4228 "directory permissions for the "
4229 "share: %s\n"), info502
.name
);
4230 nt_status
= NT_STATUS_UNSUCCESSFUL
;
4234 nt_status
= sync_files(&cp_clistate
, mask
);
4235 if (!NT_STATUS_IS_OK(nt_status
)) {
4236 d_fprintf(stderr
, _("could not handle files for share: "
4237 "%s\n"), info502
.name
);
4242 nt_status
= NT_STATUS_OK
;
4247 cli_shutdown(cp_clistate
.cli_share_src
);
4250 cli_shutdown(cp_clistate
.cli_share_dst
);
4257 static int rpc_share_migrate_files(struct net_context
*c
, int argc
, const char **argv
)
4259 if (c
->display_usage
) {
4261 "net share migrate files\n"
4264 _("Migrate files to local server"));
4269 d_printf(_("no server to migrate\n"));
4273 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4274 rpc_share_migrate_files_internals
,
4279 * Migrate share-ACLs from a remote RPC server to the local RPC server.
4281 * All parameters are provided by the run_rpc_command function, except for
4282 * argc, argv which are passed through.
4284 * @param domain_sid The domain sid acquired from the remote server.
4285 * @param cli A cli_state connected to the server.
4286 * @param mem_ctx Talloc context, destroyed on completion of the function.
4287 * @param argc Standard main() style argc.
4288 * @param argv Standard main() style argv. Initial components are already
4291 * @return Normal NTSTATUS return.
4294 static NTSTATUS
rpc_share_migrate_security_internals(struct net_context
*c
,
4295 const struct dom_sid
*domain_sid
,
4296 const char *domain_name
,
4297 struct cli_state
*cli
,
4298 struct rpc_pipe_client
*pipe_hnd
,
4299 TALLOC_CTX
*mem_ctx
,
4304 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4305 struct srvsvc_NetShareInfoCtr ctr_src
;
4306 union srvsvc_NetShareInfo info
;
4308 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
4309 struct cli_state
*cli_dst
= NULL
;
4310 uint32 level
= 502; /* includes secdesc */
4311 uint32_t parm_error
= 0;
4312 struct dcerpc_binding_handle
*b
;
4314 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
4317 if (!W_ERROR_IS_OK(result
))
4320 /* connect destination PI_SRVSVC */
4321 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
,
4323 if (!NT_STATUS_IS_OK(nt_status
))
4326 b
= srvsvc_pipe
->binding_handle
;
4328 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
4330 struct srvsvc_NetShareInfo502 info502
=
4331 ctr_src
.ctr
.ctr502
->array
[i
];
4333 /* reset error-code */
4334 nt_status
= NT_STATUS_UNSUCCESSFUL
;
4336 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
4339 printf(_("migrating: [%s], path: %s, comment: %s, including "
4341 info502
.name
, info502
.path
, info502
.comment
);
4344 display_sec_desc(info502
.sd_buf
.sd
);
4346 /* FIXME: shouldn't we be able to just set the security descriptor ? */
4347 info
.info502
= &info502
;
4349 /* finally modify the share on the dst server */
4350 nt_status
= dcerpc_srvsvc_NetShareSetInfo(b
, mem_ctx
,
4351 srvsvc_pipe
->desthost
,
4357 if (!NT_STATUS_IS_OK(nt_status
)) {
4358 printf(_("cannot set share-acl: %s\n"),
4359 nt_errstr(nt_status
));
4362 if (!W_ERROR_IS_OK(result
)) {
4363 nt_status
= werror_to_ntstatus(result
);
4364 printf(_("cannot set share-acl: %s\n"),
4365 win_errstr(result
));
4371 nt_status
= NT_STATUS_OK
;
4375 cli_shutdown(cli_dst
);
4383 * Migrate share-acls from a RPC server to another.
4385 * @param argc Standard main() style argc.
4386 * @param argv Standard main() style argv. Initial components are already
4389 * @return A shell status integer (0 for success).
4391 static int rpc_share_migrate_security(struct net_context
*c
, int argc
,
4394 if (c
->display_usage
) {
4396 "net rpc share migrate security\n"
4399 _("Migrate share-acls to local server"));
4404 d_printf(_("no server to migrate\n"));
4408 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4409 rpc_share_migrate_security_internals
,
4414 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4415 * from one server to another.
4417 * @param argc Standard main() style argc.
4418 * @param argv Standard main() style argv. Initial components are already
4421 * @return A shell status integer (0 for success).
4424 static int rpc_share_migrate_all(struct net_context
*c
, int argc
,
4429 if (c
->display_usage
) {
4431 "net rpc share migrate all\n"
4434 _("Migrates shares including all share settings"));
4439 d_printf(_("no server to migrate\n"));
4443 /* order is important. we don't want to be locked out by the share-acl
4444 * before copying files - gd */
4446 ret
= run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4447 rpc_share_migrate_shares_internals
, argc
, argv
);
4451 ret
= run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4452 rpc_share_migrate_files_internals
, argc
, argv
);
4456 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4457 rpc_share_migrate_security_internals
, argc
,
4463 * 'net rpc share migrate' entrypoint.
4464 * @param argc Standard main() style argc.
4465 * @param argv Standard main() style argv. Initial components are already
4468 static int rpc_share_migrate(struct net_context
*c
, int argc
, const char **argv
)
4471 struct functable func
[] = {
4474 rpc_share_migrate_all
,
4476 N_("Migrate shares from remote to local server"),
4477 N_("net rpc share migrate all\n"
4478 " Migrate shares from remote to local server")
4482 rpc_share_migrate_files
,
4484 N_("Migrate files from remote to local server"),
4485 N_("net rpc share migrate files\n"
4486 " Migrate files from remote to local server")
4490 rpc_share_migrate_security
,
4492 N_("Migrate share-ACLs from remote to local server"),
4493 N_("net rpc share migrate security\n"
4494 " Migrate share-ACLs from remote to local server")
4498 rpc_share_migrate_shares
,
4500 N_("Migrate shares from remote to local server"),
4501 N_("net rpc share migrate shares\n"
4502 " Migrate shares from remote to local server")
4504 {NULL
, NULL
, 0, NULL
, NULL
}
4507 net_mode_share
= NET_MODE_SHARE_MIGRATE
;
4509 return net_run_function(c
, argc
, argv
, "net rpc share migrate", func
);
4515 struct dom_sid
*members
;
4518 static int num_server_aliases
;
4519 static struct full_alias
*server_aliases
;
4522 * Add an alias to the static list.
4524 static void push_alias(TALLOC_CTX
*mem_ctx
, struct full_alias
*alias
)
4526 if (server_aliases
== NULL
)
4527 server_aliases
= SMB_MALLOC_ARRAY(struct full_alias
, 100);
4529 server_aliases
[num_server_aliases
] = *alias
;
4530 num_server_aliases
+= 1;
4534 * For a specific domain on the server, fetch all the aliases
4535 * and their members. Add all of them to the server_aliases.
4538 static NTSTATUS
rpc_fetch_domain_aliases(struct rpc_pipe_client
*pipe_hnd
,
4539 TALLOC_CTX
*mem_ctx
,
4540 struct policy_handle
*connect_pol
,
4541 const struct dom_sid
*domain_sid
)
4543 uint32 start_idx
, max_entries
, num_entries
, i
;
4544 struct samr_SamArray
*groups
= NULL
;
4545 NTSTATUS result
, status
;
4546 struct policy_handle domain_pol
;
4547 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4549 /* Get domain policy handle */
4551 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
4553 MAXIMUM_ALLOWED_ACCESS
,
4554 discard_const_p(struct dom_sid2
, domain_sid
),
4557 if (!NT_STATUS_IS_OK(status
)) {
4560 if (!NT_STATUS_IS_OK(result
)) {
4568 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
4575 if (!NT_STATUS_IS_OK(status
)) {
4578 for (i
= 0; i
< num_entries
; i
++) {
4580 struct policy_handle alias_pol
;
4581 struct full_alias alias
;
4582 struct lsa_SidArray sid_array
;
4586 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
4588 MAXIMUM_ALLOWED_ACCESS
,
4589 groups
->entries
[i
].idx
,
4592 if (!NT_STATUS_IS_OK(status
)) {
4595 if (!NT_STATUS_IS_OK(_result
)) {
4600 status
= dcerpc_samr_GetMembersInAlias(b
, mem_ctx
,
4604 if (!NT_STATUS_IS_OK(status
)) {
4607 if (!NT_STATUS_IS_OK(_result
)) {
4612 alias
.num_members
= sid_array
.num_sids
;
4614 status
= dcerpc_samr_Close(b
, mem_ctx
, &alias_pol
, &_result
);
4615 if (!NT_STATUS_IS_OK(status
)) {
4618 if (!NT_STATUS_IS_OK(_result
)) {
4623 alias
.members
= NULL
;
4625 if (alias
.num_members
> 0) {
4626 alias
.members
= SMB_MALLOC_ARRAY(struct dom_sid
, alias
.num_members
);
4628 for (j
= 0; j
< alias
.num_members
; j
++)
4629 sid_copy(&alias
.members
[j
],
4630 sid_array
.sids
[j
].sid
);
4633 sid_compose(&alias
.sid
, domain_sid
,
4634 groups
->entries
[i
].idx
);
4636 push_alias(mem_ctx
, &alias
);
4638 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
4640 status
= NT_STATUS_OK
;
4643 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
4649 * Dump server_aliases as names for debugging purposes.
4652 static NTSTATUS
rpc_aliaslist_dump(struct net_context
*c
,
4653 const struct dom_sid
*domain_sid
,
4654 const char *domain_name
,
4655 struct cli_state
*cli
,
4656 struct rpc_pipe_client
*pipe_hnd
,
4657 TALLOC_CTX
*mem_ctx
,
4663 struct policy_handle lsa_pol
;
4664 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4666 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
4667 SEC_FLAG_MAXIMUM_ALLOWED
,
4669 if (!NT_STATUS_IS_OK(result
))
4672 for (i
=0; i
<num_server_aliases
; i
++) {
4675 enum lsa_SidType
*types
;
4678 struct full_alias
*alias
= &server_aliases
[i
];
4680 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
4682 &domains
, &names
, &types
);
4683 if (!NT_STATUS_IS_OK(result
))
4686 DEBUG(1, ("%s\\%s %d: ", domains
[0], names
[0], types
[0]));
4688 if (alias
->num_members
== 0) {
4693 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
,
4696 &domains
, &names
, &types
);
4698 if (!NT_STATUS_IS_OK(result
) &&
4699 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
4702 for (j
=0; j
<alias
->num_members
; j
++)
4703 DEBUG(1, ("%s\\%s (%d); ",
4704 domains
[j
] ? domains
[j
] : "*unknown*",
4705 names
[j
] ? names
[j
] : "*unknown*",types
[j
]));
4709 dcerpc_lsa_Close(b
, mem_ctx
, &lsa_pol
, &result
);
4711 return NT_STATUS_OK
;
4715 * Fetch a list of all server aliases and their members into
4719 static NTSTATUS
rpc_aliaslist_internals(struct net_context
*c
,
4720 const struct dom_sid
*domain_sid
,
4721 const char *domain_name
,
4722 struct cli_state
*cli
,
4723 struct rpc_pipe_client
*pipe_hnd
,
4724 TALLOC_CTX
*mem_ctx
,
4728 NTSTATUS result
, status
;
4729 struct policy_handle connect_pol
;
4730 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4732 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
4734 MAXIMUM_ALLOWED_ACCESS
,
4737 if (!NT_STATUS_IS_OK(status
)) {
4740 if (!NT_STATUS_IS_OK(result
)) {
4745 status
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4746 &global_sid_Builtin
);
4747 if (!NT_STATUS_IS_OK(status
)) {
4751 status
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4754 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
4759 static void init_user_token(struct security_token
*token
, struct dom_sid
*user_sid
)
4761 token
->num_sids
= 4;
4763 if (!(token
->sids
= SMB_MALLOC_ARRAY(struct dom_sid
, 4))) {
4764 d_fprintf(stderr
, "malloc %s\n",_("failed"));
4765 token
->num_sids
= 0;
4769 token
->sids
[0] = *user_sid
;
4770 sid_copy(&token
->sids
[1], &global_sid_World
);
4771 sid_copy(&token
->sids
[2], &global_sid_Network
);
4772 sid_copy(&token
->sids
[3], &global_sid_Authenticated_Users
);
4775 static void free_user_token(struct security_token
*token
)
4777 SAFE_FREE(token
->sids
);
4780 static void add_sid_to_token(struct security_token
*token
, struct dom_sid
*sid
)
4782 if (security_token_has_sid(token
, sid
))
4785 token
->sids
= SMB_REALLOC_ARRAY(token
->sids
, struct dom_sid
, token
->num_sids
+1);
4790 sid_copy(&token
->sids
[token
->num_sids
], sid
);
4792 token
->num_sids
+= 1;
4797 struct security_token token
;
4800 static void dump_user_token(struct user_token
*token
)
4804 d_printf("%s\n", token
->name
);
4806 for (i
=0; i
<token
->token
.num_sids
; i
++) {
4807 d_printf(" %s\n", sid_string_tos(&token
->token
.sids
[i
]));
4811 static bool is_alias_member(struct dom_sid
*sid
, struct full_alias
*alias
)
4815 for (i
=0; i
<alias
->num_members
; i
++) {
4816 if (dom_sid_compare(sid
, &alias
->members
[i
]) == 0)
4823 static void collect_sid_memberships(struct security_token
*token
, struct dom_sid sid
)
4827 for (i
=0; i
<num_server_aliases
; i
++) {
4828 if (is_alias_member(&sid
, &server_aliases
[i
]))
4829 add_sid_to_token(token
, &server_aliases
[i
].sid
);
4834 * We got a user token with all the SIDs we can know about without asking the
4835 * server directly. These are the user and domain group sids. All of these can
4836 * be members of aliases. So scan the list of aliases for each of the SIDs and
4837 * add them to the token.
4840 static void collect_alias_memberships(struct security_token
*token
)
4842 int num_global_sids
= token
->num_sids
;
4845 for (i
=0; i
<num_global_sids
; i
++) {
4846 collect_sid_memberships(token
, token
->sids
[i
]);
4850 static bool get_user_sids(const char *domain
, const char *user
, struct security_token
*token
)
4852 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4853 enum wbcSidType type
;
4855 struct wbcDomainSid wsid
;
4856 char sid_str
[WBC_SID_STRING_BUFLEN
];
4857 struct dom_sid user_sid
;
4858 uint32_t num_groups
;
4859 gid_t
*groups
= NULL
;
4862 fstr_sprintf(full_name
, "%s%c%s",
4863 domain
, *lp_winbind_separator(), user
);
4865 /* First let's find out the user sid */
4867 wbc_status
= wbcLookupName(domain
, user
, &wsid
, &type
);
4869 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4870 DEBUG(1, ("winbind could not find %s: %s\n",
4871 full_name
, wbcErrorString(wbc_status
)));
4875 wbcSidToStringBuf(&wsid
, sid_str
, sizeof(sid_str
));
4877 if (type
!= WBC_SID_NAME_USER
) {
4878 DEBUG(1, ("%s is not a user\n", full_name
));
4882 if (!string_to_sid(&user_sid
, sid_str
)) {
4883 DEBUG(1,("Could not convert sid %s from string\n", sid_str
));
4887 init_user_token(token
, &user_sid
);
4889 /* And now the groups winbind knows about */
4891 wbc_status
= wbcGetGroups(full_name
, &num_groups
, &groups
);
4892 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4893 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4894 full_name
, wbcErrorString(wbc_status
)));
4898 for (i
= 0; i
< num_groups
; i
++) {
4899 gid_t gid
= groups
[i
];
4903 wbc_status
= wbcGidToSid(gid
, &wsid
);
4904 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4905 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4906 (unsigned int)gid
, wbcErrorString(wbc_status
)));
4907 wbcFreeMemory(groups
);
4911 wbcSidToStringBuf(&wsid
, sid_str
, sizeof(sid_str
));
4913 DEBUG(3, (" %s\n", sid_str
));
4915 ok
= string_to_sid(&sid
, sid_str
);
4917 DEBUG(1, ("Failed to convert string to SID\n"));
4918 wbcFreeMemory(groups
);
4921 add_sid_to_token(token
, &sid
);
4923 wbcFreeMemory(groups
);
4929 * Get a list of all user tokens we want to look at
4932 static bool get_user_tokens(struct net_context
*c
, int *num_tokens
,
4933 struct user_token
**user_tokens
)
4935 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4936 uint32_t i
, num_users
;
4938 struct user_token
*result
;
4939 TALLOC_CTX
*frame
= NULL
;
4941 if (lp_winbind_use_default_domain() &&
4942 (c
->opt_target_workgroup
== NULL
)) {
4943 d_fprintf(stderr
, _("winbind use default domain = yes set, "
4944 "please specify a workgroup\n"));
4948 /* Send request to winbind daemon */
4950 wbc_status
= wbcListUsers(NULL
, &num_users
, &users
);
4951 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4952 DEBUG(1, (_("winbind could not list users: %s\n"),
4953 wbcErrorString(wbc_status
)));
4957 result
= SMB_MALLOC_ARRAY(struct user_token
, num_users
);
4959 if (result
== NULL
) {
4960 DEBUG(1, ("Could not malloc sid array\n"));
4961 wbcFreeMemory(users
);
4965 frame
= talloc_stackframe();
4966 for (i
=0; i
< num_users
; i
++) {
4967 fstring domain
, user
;
4970 fstrcpy(result
[i
].name
, users
[i
]);
4972 p
= strchr(users
[i
], *lp_winbind_separator());
4974 DEBUG(3, ("%s\n", users
[i
]));
4977 fstrcpy(domain
, c
->opt_target_workgroup
);
4978 fstrcpy(user
, users
[i
]);
4981 fstrcpy(domain
, users
[i
]);
4982 if (!strupper_m(domain
)) {
4983 DEBUG(1, ("strupper_m %s failed\n", domain
));
4984 wbcFreeMemory(users
);
4990 get_user_sids(domain
, user
, &(result
[i
].token
));
4993 wbcFreeMemory(users
);
4995 *num_tokens
= num_users
;
4996 *user_tokens
= result
;
5001 static bool get_user_tokens_from_file(FILE *f
,
5003 struct user_token
**tokens
)
5005 struct user_token
*token
= NULL
;
5010 if (fgets(line
, sizeof(line
)-1, f
) == NULL
) {
5014 if ((strlen(line
) > 0) && (line
[strlen(line
)-1] == '\n')) {
5015 line
[strlen(line
)-1] = '\0';
5018 if (line
[0] == ' ') {
5022 if(!string_to_sid(&sid
, &line
[1])) {
5023 DEBUG(1,("get_user_tokens_from_file: Could "
5024 "not convert sid %s \n",&line
[1]));
5028 if (token
== NULL
) {
5029 DEBUG(0, ("File does not begin with username"));
5033 add_sid_to_token(&token
->token
, &sid
);
5037 /* And a new user... */
5040 *tokens
= SMB_REALLOC_ARRAY(*tokens
, struct user_token
, *num_tokens
);
5041 if (*tokens
== NULL
) {
5042 DEBUG(0, ("Could not realloc tokens\n"));
5046 token
= &((*tokens
)[*num_tokens
-1]);
5048 if (strlcpy(token
->name
, line
, sizeof(token
->name
)) >= sizeof(token
->name
)) {
5051 token
->token
.num_sids
= 0;
5052 token
->token
.sids
= NULL
;
5061 * Show the list of all users that have access to a share
5064 static void show_userlist(struct rpc_pipe_client
*pipe_hnd
,
5065 struct cli_state
*cli
,
5066 TALLOC_CTX
*mem_ctx
,
5067 const char *netname
,
5069 struct user_token
*tokens
)
5072 struct security_descriptor
*share_sd
= NULL
;
5073 struct security_descriptor
*root_sd
= NULL
;
5075 union srvsvc_NetShareInfo info
;
5079 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5081 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
5088 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
5089 DEBUG(1, ("Coult not query secdesc for share %s\n",
5094 share_sd
= info
.info502
->sd_buf
.sd
;
5095 if (share_sd
== NULL
) {
5096 DEBUG(1, ("Got no secdesc for share %s\n",
5100 cnum
= cli_state_get_tid(cli
);
5102 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, netname
, "A:", "", 0))) {
5106 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, "\\", 0, READ_CONTROL_ACCESS
, 0,
5107 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0x0, 0x0, &fnum
))) {
5108 cli_query_secdesc(cli
, fnum
, mem_ctx
, &root_sd
);
5111 for (i
=0; i
<num_tokens
; i
++) {
5114 if (share_sd
!= NULL
) {
5115 status
= se_access_check(share_sd
, &tokens
[i
].token
,
5118 if (!NT_STATUS_IS_OK(status
)) {
5119 DEBUG(1, ("Could not check share_sd for "
5126 if (root_sd
== NULL
) {
5127 d_printf(" %s\n", tokens
[i
].name
);
5131 status
= se_access_check(root_sd
, &tokens
[i
].token
,
5133 if (!NT_STATUS_IS_OK(status
)) {
5134 DEBUG(1, ("Could not check root_sd for user %s\n",
5138 d_printf(" %s\n", tokens
[i
].name
);
5141 if (fnum
!= (uint16_t)-1)
5142 cli_close(cli
, fnum
);
5144 cli_state_set_tid(cli
, cnum
);
5150 * List shares on a remote RPC server, including the security descriptors.
5152 * All parameters are provided by the run_rpc_command function, except for
5153 * argc, argv which are passed through.
5155 * @param domain_sid The domain sid acquired from the remote server.
5156 * @param cli A cli_state connected to the server.
5157 * @param mem_ctx Talloc context, destroyed on completion of the function.
5158 * @param argc Standard main() style argc.
5159 * @param argv Standard main() style argv. Initial components are already
5162 * @return Normal NTSTATUS return.
5165 static NTSTATUS
rpc_share_allowedusers_internals(struct net_context
*c
,
5166 const struct dom_sid
*domain_sid
,
5167 const char *domain_name
,
5168 struct cli_state
*cli
,
5169 struct rpc_pipe_client
*pipe_hnd
,
5170 TALLOC_CTX
*mem_ctx
,
5176 NTSTATUS nt_status
= NT_STATUS_OK
;
5177 uint32_t total_entries
= 0;
5178 uint32_t resume_handle
= 0;
5179 uint32_t preferred_len
= 0xffffffff;
5181 struct dcerpc_binding_handle
*b
= NULL
;
5182 struct srvsvc_NetShareInfoCtr info_ctr
;
5183 struct srvsvc_NetShareCtr1 ctr1
;
5186 struct user_token
*tokens
= NULL
;
5192 f
= fopen(argv
[0], "r");
5196 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno
)));
5197 return NT_STATUS_UNSUCCESSFUL
;
5200 r
= get_user_tokens_from_file(f
, &num_tokens
, &tokens
);
5206 DEBUG(0, ("Could not read users from file\n"));
5207 return NT_STATUS_UNSUCCESSFUL
;
5210 for (i
=0; i
<num_tokens
; i
++)
5211 collect_alias_memberships(&tokens
[i
].token
);
5213 ZERO_STRUCT(info_ctr
);
5217 info_ctr
.ctr
.ctr1
= &ctr1
;
5219 b
= pipe_hnd
->binding_handle
;
5221 /* Issue the NetShareEnum RPC call and retrieve the response */
5222 nt_status
= dcerpc_srvsvc_NetShareEnumAll(b
,
5231 /* Was it successful? */
5232 if (!NT_STATUS_IS_OK(nt_status
)) {
5233 /* Nope. Go clean up. */
5237 if (!W_ERROR_IS_OK(result
)) {
5238 /* Nope. Go clean up. */
5239 nt_status
= werror_to_ntstatus(result
);
5243 if (total_entries
== 0) {
5247 /* For each returned entry... */
5248 for (i
= 0; i
< info_ctr
.ctr
.ctr1
->count
; i
++) {
5249 const char *netname
= info_ctr
.ctr
.ctr1
->array
[i
].name
;
5251 if (info_ctr
.ctr
.ctr1
->array
[i
].type
!= STYPE_DISKTREE
) {
5255 d_printf("%s\n", netname
);
5257 show_userlist(pipe_hnd
, cli
, mem_ctx
, netname
,
5258 num_tokens
, tokens
);
5261 for (i
=0; i
<num_tokens
; i
++) {
5262 free_user_token(&tokens
[i
].token
);
5269 static int rpc_share_allowedusers(struct net_context
*c
, int argc
,
5274 if (c
->display_usage
) {
5276 "net rpc share allowedusers\n"
5279 _("List allowed users"));
5283 result
= run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
5284 rpc_aliaslist_internals
,
5289 result
= run_rpc_command(c
, NULL
, &ndr_table_lsarpc
, 0,
5295 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
5296 rpc_share_allowedusers_internals
,
5300 int net_usersidlist(struct net_context
*c
, int argc
, const char **argv
)
5303 struct user_token
*tokens
= NULL
;
5307 net_usersidlist_usage(c
, argc
, argv
);
5311 if (!get_user_tokens(c
, &num_tokens
, &tokens
)) {
5312 DEBUG(0, ("Could not get the user/sid list\n"));
5316 for (i
=0; i
<num_tokens
; i
++) {
5317 dump_user_token(&tokens
[i
]);
5318 free_user_token(&tokens
[i
].token
);
5325 int net_usersidlist_usage(struct net_context
*c
, int argc
, const char **argv
)
5327 d_printf(_("net usersidlist\n"
5328 "\tprints out a list of all users the running winbind knows\n"
5329 "\tabout, together with all their SIDs. This is used as\n"
5330 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5332 net_common_flags_usage(c
, argc
, argv
);
5337 * 'net rpc share' entrypoint.
5338 * @param argc Standard main() style argc.
5339 * @param argv Standard main() style argv. Initial components are already
5343 int net_rpc_share(struct net_context
*c
, int argc
, const char **argv
)
5345 NET_API_STATUS status
;
5347 struct functable func
[] = {
5353 N_("net rpc share add\n"
5361 N_("net rpc share delete\n"
5366 rpc_share_allowedusers
,
5368 N_("Modify allowed users"),
5369 N_("net rpc share allowedusers\n"
5370 " Modify allowed users")
5376 N_("Migrate share to local server"),
5377 N_("net rpc share migrate\n"
5378 " Migrate share to local server")
5385 N_("net rpc share list\n"
5388 {NULL
, NULL
, 0, NULL
, NULL
}
5391 status
= libnetapi_net_init(&c
->netapi_ctx
);
5395 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
5396 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
5397 if (c
->opt_kerberos
) {
5398 libnetapi_set_use_kerberos(c
->netapi_ctx
);
5402 if (c
->display_usage
) {
5407 " Alias for net rpc share list\n"));
5408 net_display_usage_from_functable(func
);
5412 return rpc_share_list(c
, argc
, argv
);
5415 return net_run_function(c
, argc
, argv
, "net rpc share", func
);
5418 static NTSTATUS
rpc_sh_share_list(struct net_context
*c
,
5419 TALLOC_CTX
*mem_ctx
,
5420 struct rpc_sh_ctx
*ctx
,
5421 struct rpc_pipe_client
*pipe_hnd
,
5422 int argc
, const char **argv
)
5425 return werror_to_ntstatus(W_ERROR(rpc_share_list(c
, argc
, argv
)));
5428 static NTSTATUS
rpc_sh_share_add(struct net_context
*c
,
5429 TALLOC_CTX
*mem_ctx
,
5430 struct rpc_sh_ctx
*ctx
,
5431 struct rpc_pipe_client
*pipe_hnd
,
5432 int argc
, const char **argv
)
5434 NET_API_STATUS status
;
5435 uint32_t parm_err
= 0;
5436 struct SHARE_INFO_2 i2
;
5438 if ((argc
< 2) || (argc
> 3)) {
5439 d_fprintf(stderr
, _("Usage: %s <share> <path> [comment]\n"),
5441 return NT_STATUS_INVALID_PARAMETER
;
5444 i2
.shi2_netname
= argv
[0];
5445 i2
.shi2_type
= STYPE_DISKTREE
;
5446 i2
.shi2_remark
= (argc
== 3) ? argv
[2] : "";
5447 i2
.shi2_permissions
= 0;
5448 i2
.shi2_max_uses
= 0;
5449 i2
.shi2_current_uses
= 0;
5450 i2
.shi2_path
= argv
[1];
5451 i2
.shi2_passwd
= NULL
;
5453 status
= NetShareAdd(pipe_hnd
->desthost
,
5458 return werror_to_ntstatus(W_ERROR(status
));
5461 static NTSTATUS
rpc_sh_share_delete(struct net_context
*c
,
5462 TALLOC_CTX
*mem_ctx
,
5463 struct rpc_sh_ctx
*ctx
,
5464 struct rpc_pipe_client
*pipe_hnd
,
5465 int argc
, const char **argv
)
5468 d_fprintf(stderr
, "%s %s <share>\n", _("Usage:"), ctx
->whoami
);
5469 return NT_STATUS_INVALID_PARAMETER
;
5472 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd
->desthost
, argv
[0], 0)));
5475 static NTSTATUS
rpc_sh_share_info(struct net_context
*c
,
5476 TALLOC_CTX
*mem_ctx
,
5477 struct rpc_sh_ctx
*ctx
,
5478 struct rpc_pipe_client
*pipe_hnd
,
5479 int argc
, const char **argv
)
5481 union srvsvc_NetShareInfo info
;
5484 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5487 d_fprintf(stderr
, "%s %s <share>\n", _("Usage:"), ctx
->whoami
);
5488 return NT_STATUS_INVALID_PARAMETER
;
5491 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
5497 if (!NT_STATUS_IS_OK(status
)) {
5498 result
= ntstatus_to_werror(status
);
5501 if (!W_ERROR_IS_OK(result
)) {
5505 d_printf(_("Name: %s\n"), info
.info2
->name
);
5506 d_printf(_("Comment: %s\n"), info
.info2
->comment
);
5507 d_printf(_("Path: %s\n"), info
.info2
->path
);
5508 d_printf(_("Password: %s\n"), info
.info2
->password
);
5511 return werror_to_ntstatus(result
);
5514 struct rpc_sh_cmd
*net_rpc_share_cmds(struct net_context
*c
, TALLOC_CTX
*mem_ctx
,
5515 struct rpc_sh_ctx
*ctx
)
5517 static struct rpc_sh_cmd cmds
[] = {
5519 { "list", NULL
, &ndr_table_srvsvc
, rpc_sh_share_list
,
5520 N_("List available shares") },
5522 { "add", NULL
, &ndr_table_srvsvc
, rpc_sh_share_add
,
5523 N_("Add a share") },
5525 { "delete", NULL
, &ndr_table_srvsvc
, rpc_sh_share_delete
,
5526 N_("Delete a share") },
5528 { "info", NULL
, &ndr_table_srvsvc
, rpc_sh_share_info
,
5529 N_("Get information about a share") },
5531 { NULL
, NULL
, 0, NULL
, NULL
}
5537 /****************************************************************************/
5539 static int rpc_file_usage(struct net_context
*c
, int argc
, const char **argv
)
5541 return net_file_usage(c
, argc
, argv
);
5545 * Close a file on a remote RPC server.
5547 * @param argc Standard main() style argc.
5548 * @param argv Standard main() style argv. Initial components are already
5551 * @return A shell status integer (0 for success).
5553 static int rpc_file_close(struct net_context
*c
, int argc
, const char **argv
)
5555 if (argc
< 1 || c
->display_usage
) {
5556 return rpc_file_usage(c
, argc
, argv
);
5559 return NetFileClose(c
->opt_host
, atoi(argv
[0]));
5563 * Formatted print of open file info
5565 * @param r struct FILE_INFO_3 contents
5568 static void display_file_info_3(struct FILE_INFO_3
*r
)
5570 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5571 r
->fi3_id
, r
->fi3_username
, r
->fi3_permissions
,
5572 r
->fi3_num_locks
, r
->fi3_pathname
);
5576 * List files for a user on a remote RPC server.
5578 * @param argc Standard main() style argc.
5579 * @param argv Standard main() style argv. Initial components are already
5582 * @return A shell status integer (0 for success)..
5585 static int rpc_file_user(struct net_context
*c
, int argc
, const char **argv
)
5587 NET_API_STATUS status
;
5588 uint32 preferred_len
= 0xffffffff, i
;
5589 char *username
=NULL
;
5590 uint32_t total_entries
= 0;
5591 uint32_t entries_read
= 0;
5592 uint32_t resume_handle
= 0;
5593 struct FILE_INFO_3
*i3
= NULL
;
5595 if (c
->display_usage
) {
5596 return rpc_file_usage(c
, argc
, argv
);
5599 /* if argc > 0, must be user command */
5601 username
= smb_xstrdup(argv
[0]);
5604 status
= NetFileEnum(c
->opt_host
,
5608 (uint8_t **)(void *)&i3
,
5618 /* Display results */
5621 "\nEnumerating open files on remote server:\n\n"
5622 "\nFileId Opened by Perms Locks Path"
5623 "\n------ --------- ----- ----- ---- \n"));
5624 for (i
= 0; i
< entries_read
; i
++) {
5625 display_file_info_3(&i3
[i
]);
5628 SAFE_FREE(username
);
5633 * 'net rpc file' entrypoint.
5634 * @param argc Standard main() style argc.
5635 * @param argv Standard main() style argv. Initial components are already
5639 int net_rpc_file(struct net_context
*c
, int argc
, const char **argv
)
5641 NET_API_STATUS status
;
5643 struct functable func
[] = {
5648 N_("Close opened file"),
5649 N_("net rpc file close\n"
5650 " Close opened file")
5656 N_("List files opened by user"),
5657 N_("net rpc file user\n"
5658 " List files opened by user")
5665 N_("Display information about opened file"),
5666 N_("net rpc file info\n"
5667 " Display information about opened file")
5670 {NULL
, NULL
, 0, NULL
, NULL
}
5673 status
= libnetapi_net_init(&c
->netapi_ctx
);
5677 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
5678 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
5679 if (c
->opt_kerberos
) {
5680 libnetapi_set_use_kerberos(c
->netapi_ctx
);
5684 if (c
->display_usage
) {
5685 d_printf(_("Usage:\n"));
5686 d_printf(_("net rpc file\n"
5687 " List opened files\n"));
5688 net_display_usage_from_functable(func
);
5692 return rpc_file_user(c
, argc
, argv
);
5695 return net_run_function(c
, argc
, argv
, "net rpc file", func
);
5699 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5701 * All parameters are provided by the run_rpc_command function, except for
5702 * argc, argv which are passed through.
5704 * @param c A net_context structure.
5705 * @param domain_sid The domain sid acquired from the remote server.
5706 * @param cli A cli_state connected to the server.
5707 * @param mem_ctx Talloc context, destroyed on completion of the function.
5708 * @param argc Standard main() style argc.
5709 * @param argv Standard main() style argv. Initial components are already
5712 * @return Normal NTSTATUS return.
5715 static NTSTATUS
rpc_shutdown_abort_internals(struct net_context
*c
,
5716 const struct dom_sid
*domain_sid
,
5717 const char *domain_name
,
5718 struct cli_state
*cli
,
5719 struct rpc_pipe_client
*pipe_hnd
,
5720 TALLOC_CTX
*mem_ctx
,
5724 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5726 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5728 status
= dcerpc_initshutdown_Abort(b
, mem_ctx
, NULL
, &result
);
5729 if (!NT_STATUS_IS_OK(status
)) {
5732 if (W_ERROR_IS_OK(result
)) {
5733 d_printf(_("\nShutdown successfully aborted\n"));
5734 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5736 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5738 return werror_to_ntstatus(result
);
5742 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5744 * All parameters are provided by the run_rpc_command function, except for
5745 * argc, argv which are passed through.
5747 * @param c A net_context structure.
5748 * @param domain_sid The domain sid acquired from the remote server.
5749 * @param cli A cli_state connected to the server.
5750 * @param mem_ctx Talloc context, destroyed on completion of the function.
5751 * @param argc Standard main() style argc.
5752 * @param argv Standard main() style argv. Initial components are already
5755 * @return Normal NTSTATUS return.
5758 static NTSTATUS
rpc_reg_shutdown_abort_internals(struct net_context
*c
,
5759 const struct dom_sid
*domain_sid
,
5760 const char *domain_name
,
5761 struct cli_state
*cli
,
5762 struct rpc_pipe_client
*pipe_hnd
,
5763 TALLOC_CTX
*mem_ctx
,
5767 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5769 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5771 result
= dcerpc_winreg_AbortSystemShutdown(b
, mem_ctx
, NULL
, &werr
);
5773 if (!NT_STATUS_IS_OK(result
)) {
5774 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5777 if (W_ERROR_IS_OK(werr
)) {
5778 d_printf(_("\nShutdown successfully aborted\n"));
5779 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5781 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5783 return werror_to_ntstatus(werr
);
5787 * ABORT the shutdown of a remote RPC server.
5789 * @param argc Standard main() style argc.
5790 * @param argv Standard main() style argv. Initial components are already
5793 * @return A shell status integer (0 for success).
5796 static int rpc_shutdown_abort(struct net_context
*c
, int argc
,
5801 if (c
->display_usage
) {
5803 "net rpc abortshutdown\n"
5806 _("Abort a scheduled shutdown"));
5810 rc
= run_rpc_command(c
, NULL
, &ndr_table_initshutdown
, 0,
5811 rpc_shutdown_abort_internals
, argc
, argv
);
5816 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5818 return run_rpc_command(c
, NULL
, &ndr_table_winreg
, 0,
5819 rpc_reg_shutdown_abort_internals
,
5824 * Shut down a remote RPC Server via initshutdown pipe.
5826 * All parameters are provided by the run_rpc_command function, except for
5827 * argc, argv which are passed through.
5829 * @param c A net_context structure.
5830 * @param domain_sid The domain sid acquired from the remote server.
5831 * @param cli A cli_state connected to the server.
5832 * @param mem_ctx Talloc context, destroyed on completion of the function.
5833 * @param argc Standard main() style argc.
5834 * @param argv Standard main() style argv. Initial components are already
5837 * @return Normal NTSTATUS return.
5840 NTSTATUS
rpc_init_shutdown_internals(struct net_context
*c
,
5841 const struct dom_sid
*domain_sid
,
5842 const char *domain_name
,
5843 struct cli_state
*cli
,
5844 struct rpc_pipe_client
*pipe_hnd
,
5845 TALLOC_CTX
*mem_ctx
,
5849 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5851 const char *msg
= N_("This machine will be shutdown shortly");
5852 uint32 timeout
= 20;
5853 struct lsa_StringLarge msg_string
;
5854 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5856 if (c
->opt_comment
) {
5857 msg
= c
->opt_comment
;
5859 if (c
->opt_timeout
) {
5860 timeout
= c
->opt_timeout
;
5863 msg_string
.string
= msg
;
5865 /* create an entry */
5866 status
= dcerpc_initshutdown_Init(b
, mem_ctx
, NULL
,
5867 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5869 if (!NT_STATUS_IS_OK(status
)) {
5872 if (W_ERROR_IS_OK(result
)) {
5873 d_printf(_("\nShutdown of remote machine succeeded\n"));
5874 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5876 DEBUG(1,("Shutdown of remote machine failed!\n"));
5878 return werror_to_ntstatus(result
);
5882 * Shut down a remote RPC Server via winreg pipe.
5884 * All parameters are provided by the run_rpc_command function, except for
5885 * argc, argv which are passed through.
5887 * @param c A net_context structure.
5888 * @param domain_sid The domain sid acquired from the remote server.
5889 * @param cli A cli_state connected to the server.
5890 * @param mem_ctx Talloc context, destroyed on completion of the function.
5891 * @param argc Standard main() style argc.
5892 * @param argv Standard main() style argv. Initial components are already
5895 * @return Normal NTSTATUS return.
5898 NTSTATUS
rpc_reg_shutdown_internals(struct net_context
*c
,
5899 const struct dom_sid
*domain_sid
,
5900 const char *domain_name
,
5901 struct cli_state
*cli
,
5902 struct rpc_pipe_client
*pipe_hnd
,
5903 TALLOC_CTX
*mem_ctx
,
5907 const char *msg
= N_("This machine will be shutdown shortly");
5908 uint32 timeout
= 20;
5909 struct lsa_StringLarge msg_string
;
5912 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5914 if (c
->opt_comment
) {
5915 msg
= c
->opt_comment
;
5917 msg_string
.string
= msg
;
5919 if (c
->opt_timeout
) {
5920 timeout
= c
->opt_timeout
;
5923 /* create an entry */
5924 result
= dcerpc_winreg_InitiateSystemShutdown(b
, mem_ctx
, NULL
,
5925 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5927 if (!NT_STATUS_IS_OK(result
)) {
5928 d_fprintf(stderr
, "\nShutdown of remote machine failed\n");
5932 if (W_ERROR_IS_OK(werr
)) {
5933 d_printf(_("\nShutdown of remote machine succeeded\n"));
5935 d_fprintf(stderr
, "\nShutdown of remote machine failed\n");
5936 if ( W_ERROR_EQUAL(werr
, WERR_MACHINE_LOCKED
) )
5937 d_fprintf(stderr
, "\nMachine locked, use -f switch to force\n");
5939 d_fprintf(stderr
, "\nresult was: %s\n", win_errstr(werr
));
5942 return werror_to_ntstatus(werr
);
5946 * Shut down a remote RPC server.
5948 * @param argc Standard main() style argc.
5949 * @param argv Standard main() style argv. Initial components are already
5952 * @return A shell status integer (0 for success).
5955 static int rpc_shutdown(struct net_context
*c
, int argc
, const char **argv
)
5959 if (c
->display_usage
) {
5961 "net rpc shutdown\n"
5964 _("Shut down a remote RPC server"));
5968 rc
= run_rpc_command(c
, NULL
, &ndr_table_initshutdown
, 0,
5969 rpc_init_shutdown_internals
, argc
, argv
);
5972 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5973 rc
= run_rpc_command(c
, NULL
, &ndr_table_winreg
, 0,
5974 rpc_reg_shutdown_internals
, argc
, argv
);
5980 /***************************************************************************
5981 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5982 ***************************************************************************/
5985 * Add interdomain trust account to the RPC server.
5986 * All parameters (except for argc and argv) are passed by run_rpc_command
5989 * @param c A net_context structure.
5990 * @param domain_sid The domain sid acquired from the server.
5991 * @param cli A cli_state connected to the server.
5992 * @param mem_ctx Talloc context, destroyed on completion of the function.
5993 * @param argc Standard main() style argc.
5994 * @param argv Standard main() style argv. Initial components are already
5997 * @return normal NTSTATUS return code.
6000 static NTSTATUS
rpc_trustdom_add_internals(struct net_context
*c
,
6001 const struct dom_sid
*domain_sid
,
6002 const char *domain_name
,
6003 struct cli_state
*cli
,
6004 struct rpc_pipe_client
*pipe_hnd
,
6005 TALLOC_CTX
*mem_ctx
,
6009 struct policy_handle connect_pol
, domain_pol
, user_pol
;
6010 NTSTATUS status
, result
;
6012 struct lsa_String lsa_acct_name
;
6014 uint32 acct_flags
=0;
6016 uint32_t access_granted
= 0;
6017 union samr_UserInfo info
;
6018 unsigned int orig_timeout
;
6019 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6020 DATA_BLOB session_key
= data_blob_null
;
6025 _(" net rpc trustdom add <domain_name> "
6026 "<trust password>\n"));
6027 return NT_STATUS_INVALID_PARAMETER
;
6031 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6034 if (asprintf(&acct_name
, "%s$", argv
[0]) < 0) {
6035 return NT_STATUS_NO_MEMORY
;
6038 if (!strupper_m(acct_name
)) {
6039 SAFE_FREE(acct_name
);
6040 return NT_STATUS_INVALID_PARAMETER
;
6043 init_lsa_String(&lsa_acct_name
, acct_name
);
6045 status
= cli_get_session_key(mem_ctx
, pipe_hnd
, &session_key
);
6046 if (!NT_STATUS_IS_OK(status
)) {
6047 DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
6048 nt_errstr(status
)));
6052 /* Get samr policy handle */
6053 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
6055 MAXIMUM_ALLOWED_ACCESS
,
6058 if (!NT_STATUS_IS_OK(status
)) {
6061 if (!NT_STATUS_IS_OK(result
)) {
6066 /* Get domain policy handle */
6067 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
6069 MAXIMUM_ALLOWED_ACCESS
,
6070 discard_const_p(struct dom_sid2
, domain_sid
),
6073 if (!NT_STATUS_IS_OK(status
)) {
6076 if (!NT_STATUS_IS_OK(result
)) {
6081 /* This call can take a long time - allow the server to time out.
6082 * 35 seconds should do it. */
6084 orig_timeout
= rpccli_set_timeout(pipe_hnd
, 35000);
6086 /* Create trusting domain's account */
6087 acb_info
= ACB_NORMAL
;
6088 acct_flags
= SEC_GENERIC_READ
| SEC_GENERIC_WRITE
| SEC_GENERIC_EXECUTE
|
6089 SEC_STD_WRITE_DAC
| SEC_STD_DELETE
|
6090 SAMR_USER_ACCESS_SET_PASSWORD
|
6091 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
6092 SAMR_USER_ACCESS_SET_ATTRIBUTES
;
6094 status
= dcerpc_samr_CreateUser2(b
, mem_ctx
,
6103 if (!NT_STATUS_IS_OK(status
)) {
6106 /* And restore our original timeout. */
6107 rpccli_set_timeout(pipe_hnd
, orig_timeout
);
6109 if (!NT_STATUS_IS_OK(result
)) {
6111 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
6112 acct_name
, nt_errstr(result
));
6117 struct samr_CryptPassword crypt_pwd
;
6119 ZERO_STRUCT(info
.info23
);
6121 init_samr_CryptPassword(argv
[1],
6125 info
.info23
.info
.fields_present
= SAMR_FIELD_ACCT_FLAGS
|
6126 SAMR_FIELD_NT_PASSWORD_PRESENT
;
6127 info
.info23
.info
.acct_flags
= ACB_DOMTRUST
;
6128 info
.info23
.password
= crypt_pwd
;
6130 status
= dcerpc_samr_SetUserInfo2(b
, mem_ctx
,
6135 if (!NT_STATUS_IS_OK(status
)) {
6139 if (!NT_STATUS_IS_OK(result
)) {
6141 DEBUG(0,("Could not set trust account password: %s\n",
6142 nt_errstr(result
)));
6148 SAFE_FREE(acct_name
);
6149 data_blob_clear_free(&session_key
);
6154 * Create interdomain trust account for a remote domain.
6156 * @param argc Standard argc.
6157 * @param argv Standard argv without initial components.
6159 * @return Integer status (0 means success).
6162 static int rpc_trustdom_add(struct net_context
*c
, int argc
, const char **argv
)
6164 if (argc
> 0 && !c
->display_usage
) {
6165 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
6166 rpc_trustdom_add_internals
, argc
, argv
);
6170 _("net rpc trustdom add <domain_name> <trust "
6178 * Remove interdomain trust account from the RPC server.
6179 * All parameters (except for argc and argv) are passed by run_rpc_command
6182 * @param c A net_context structure.
6183 * @param domain_sid The domain sid acquired from the server.
6184 * @param cli A cli_state connected to the server.
6185 * @param mem_ctx Talloc context, destroyed on completion of the function.
6186 * @param argc Standard main() style argc.
6187 * @param argv Standard main() style argv. Initial components are already
6190 * @return normal NTSTATUS return code.
6193 static NTSTATUS
rpc_trustdom_del_internals(struct net_context
*c
,
6194 const struct dom_sid
*domain_sid
,
6195 const char *domain_name
,
6196 struct cli_state
*cli
,
6197 struct rpc_pipe_client
*pipe_hnd
,
6198 TALLOC_CTX
*mem_ctx
,
6202 struct policy_handle connect_pol
, domain_pol
, user_pol
;
6203 NTSTATUS status
, result
;
6205 struct dom_sid trust_acct_sid
;
6206 struct samr_Ids user_rids
, name_types
;
6207 struct lsa_String lsa_acct_name
;
6208 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6213 _(" net rpc trustdom del <domain_name>\n"));
6214 return NT_STATUS_INVALID_PARAMETER
;
6218 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6220 acct_name
= talloc_asprintf(mem_ctx
, "%s$", argv
[0]);
6222 if (acct_name
== NULL
)
6223 return NT_STATUS_NO_MEMORY
;
6225 if (!strupper_m(acct_name
)) {
6226 TALLOC_FREE(acct_name
);
6227 return NT_STATUS_INVALID_PARAMETER
;
6230 /* Get samr policy handle */
6231 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
6233 MAXIMUM_ALLOWED_ACCESS
,
6236 if (!NT_STATUS_IS_OK(status
)) {
6239 if (!NT_STATUS_IS_OK(result
)) {
6244 /* Get domain policy handle */
6245 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
6247 MAXIMUM_ALLOWED_ACCESS
,
6248 discard_const_p(struct dom_sid2
, domain_sid
),
6251 if (!NT_STATUS_IS_OK(status
)) {
6254 if (!NT_STATUS_IS_OK(result
)) {
6259 init_lsa_String(&lsa_acct_name
, acct_name
);
6261 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
6268 if (!NT_STATUS_IS_OK(status
)) {
6269 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6271 acct_name
, nt_errstr(status
));
6274 if (!NT_STATUS_IS_OK(result
)) {
6276 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6278 acct_name
, nt_errstr(result
) );
6281 if (user_rids
.count
!= 1) {
6282 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
6285 if (name_types
.count
!= 1) {
6286 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
6290 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
6292 MAXIMUM_ALLOWED_ACCESS
,
6296 if (!NT_STATUS_IS_OK(status
)) {
6297 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6299 acct_name
, nt_errstr(status
) );
6303 if (!NT_STATUS_IS_OK(result
)) {
6305 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6307 acct_name
, nt_errstr(result
) );
6311 /* append the rid to the domain sid */
6312 if (!sid_compose(&trust_acct_sid
, domain_sid
, user_rids
.ids
[0])) {
6316 /* remove the sid */
6318 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, mem_ctx
,
6322 if (!NT_STATUS_IS_OK(status
)) {
6323 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6324 " on user %s failed %s\n"),
6325 acct_name
, nt_errstr(status
));
6328 if (!NT_STATUS_IS_OK(result
)) {
6330 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6331 " on user %s failed %s\n"),
6332 acct_name
, nt_errstr(result
) );
6339 status
= dcerpc_samr_DeleteUser(b
, mem_ctx
,
6342 if (!NT_STATUS_IS_OK(status
)) {
6343 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6345 acct_name
, nt_errstr(status
));
6349 if (!NT_STATUS_IS_OK(result
)) {
6351 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6353 acct_name
, nt_errstr(result
) );
6357 if (!NT_STATUS_IS_OK(result
)) {
6358 d_printf(_("Could not set trust account password: %s\n"),
6368 * Delete interdomain trust account for a remote domain.
6370 * @param argc Standard argc.
6371 * @param argv Standard argv without initial components.
6373 * @return Integer status (0 means success).
6376 static int rpc_trustdom_del(struct net_context
*c
, int argc
, const char **argv
)
6378 if (argc
> 0 && !c
->display_usage
) {
6379 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
6380 rpc_trustdom_del_internals
, argc
, argv
);
6384 _("net rpc trustdom del <domain>\n"));
6389 static NTSTATUS
rpc_trustdom_get_pdc(struct net_context
*c
,
6390 struct cli_state
*cli
,
6391 TALLOC_CTX
*mem_ctx
,
6392 const char *domain_name
)
6394 char *dc_name
= NULL
;
6395 const char *buffer
= NULL
;
6396 struct rpc_pipe_client
*netr
;
6399 struct dcerpc_binding_handle
*b
;
6401 /* Use NetServerEnum2 */
6403 if (cli_get_pdc_name(cli
, domain_name
, &dc_name
)) {
6405 return NT_STATUS_OK
;
6408 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6409 for domain %s\n", domain_name
));
6411 /* Try netr_GetDcName */
6413 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
,
6415 if (!NT_STATUS_IS_OK(status
)) {
6419 b
= netr
->binding_handle
;
6421 status
= dcerpc_netr_GetDcName(b
, mem_ctx
,
6428 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
6432 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6433 for domain %s\n", domain_name
));
6435 if (!NT_STATUS_IS_OK(status
)) {
6439 return werror_to_ntstatus(result
);
6443 * Establish trust relationship to a trusting domain.
6444 * Interdomain account must already be created on remote PDC.
6446 * @param c A net_context structure.
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_establish(struct net_context
*c
, int argc
,
6456 struct cli_state
*cli
= NULL
;
6457 struct sockaddr_storage server_ss
;
6458 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6459 struct policy_handle connect_hnd
;
6460 TALLOC_CTX
*mem_ctx
;
6461 NTSTATUS nt_status
, result
;
6462 struct dom_sid
*domain_sid
;
6467 union lsa_PolicyInformation
*info
= NULL
;
6468 struct dcerpc_binding_handle
*b
;
6471 * Connect to \\server\ipc$ as 'our domain' account with password
6474 if (argc
!= 1 || c
->display_usage
) {
6477 _("net rpc trustdom establish <domain_name>\n"));
6481 domain_name
= smb_xstrdup(argv
[0]);
6482 if (!strupper_m(domain_name
)) {
6483 SAFE_FREE(domain_name
);
6487 /* account name used at first is our domain's name with '$' */
6488 if (asprintf(&acct_name
, "%s$", lp_workgroup()) == -1) {
6491 if (!strupper_m(acct_name
)) {
6492 SAFE_FREE(domain_name
);
6493 SAFE_FREE(acct_name
);
6498 * opt_workgroup will be used by connection functions further,
6499 * hence it should be set to remote domain name instead of ours
6501 if (c
->opt_workgroup
) {
6502 c
->opt_workgroup
= smb_xstrdup(domain_name
);
6505 c
->opt_user_name
= acct_name
;
6507 /* find the domain controller */
6508 if (!net_find_pdc(&server_ss
, pdc_name
, domain_name
)) {
6509 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name
));
6513 /* connect to ipc$ as username/password */
6514 nt_status
= connect_to_ipc(c
, &cli
, &server_ss
, pdc_name
);
6515 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
)) {
6517 /* Is it trusting domain account for sure ? */
6518 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6519 nt_errstr(nt_status
)));
6523 /* store who we connected to */
6525 saf_store( domain_name
, pdc_name
);
6528 * Connect to \\server\ipc$ again (this time anonymously)
6531 nt_status
= connect_to_ipc_anonymous(c
, &cli
, &server_ss
,
6534 if (NT_STATUS_IS_ERR(nt_status
)) {
6535 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6536 domain_name
, nt_errstr(nt_status
)));
6540 if (!(mem_ctx
= talloc_init("establishing trust relationship to "
6541 "domain %s", domain_name
))) {
6542 DEBUG(0, ("talloc_init() failed\n"));
6547 /* Make sure we're talking to a proper server */
6549 nt_status
= rpc_trustdom_get_pdc(c
, cli
, mem_ctx
, domain_name
);
6550 if (!NT_STATUS_IS_OK(nt_status
)) {
6552 talloc_destroy(mem_ctx
);
6557 * Call LsaOpenPolicy and LsaQueryInfo
6560 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
6562 if (!NT_STATUS_IS_OK(nt_status
)) {
6563 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status
) ));
6565 talloc_destroy(mem_ctx
);
6569 b
= pipe_hnd
->binding_handle
;
6571 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true, KEY_QUERY_VALUE
,
6573 if (NT_STATUS_IS_ERR(nt_status
)) {
6574 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6575 nt_errstr(nt_status
)));
6577 talloc_destroy(mem_ctx
);
6581 /* Querying info level 5 */
6583 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
6585 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6588 if (NT_STATUS_IS_ERR(nt_status
)) {
6589 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6590 nt_errstr(nt_status
)));
6592 talloc_destroy(mem_ctx
);
6595 if (NT_STATUS_IS_ERR(result
)) {
6596 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6597 nt_errstr(result
)));
6599 talloc_destroy(mem_ctx
);
6603 domain_sid
= info
->account_domain
.sid
;
6605 /* There should be actually query info level 3 (following nt serv behaviour),
6606 but I still don't know if it's _really_ necessary */
6609 * Store the password in secrets db
6612 if (!pdb_set_trusteddom_pw(domain_name
, c
->opt_password
, domain_sid
)) {
6613 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6615 talloc_destroy(mem_ctx
);
6620 * Close the pipes and clean up
6623 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
6624 if (NT_STATUS_IS_ERR(nt_status
)) {
6625 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6626 nt_errstr(nt_status
)));
6628 talloc_destroy(mem_ctx
);
6634 talloc_destroy(mem_ctx
);
6636 d_printf(_("Trust to domain %s established\n"), domain_name
);
6641 * Revoke trust relationship to the remote domain.
6643 * @param c A net_context structure.
6644 * @param argc Standard argc.
6645 * @param argv Standard argv without initial components.
6647 * @return Integer status (0 means success).
6650 static int rpc_trustdom_revoke(struct net_context
*c
, int argc
,
6656 if (argc
< 1 || c
->display_usage
) {
6659 _("net rpc trustdom revoke <domain_name>\n"
6660 " Revoke trust relationship\n"
6661 " domain_name\tName of domain to revoke trust\n"));
6665 /* generate upper cased domain name */
6666 domain_name
= smb_xstrdup(argv
[0]);
6667 if (!strupper_m(domain_name
)) {
6668 SAFE_FREE(domain_name
);
6672 /* delete password of the trust */
6673 if (!pdb_del_trusteddom_pw(domain_name
)) {
6674 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6681 SAFE_FREE(domain_name
);
6685 static NTSTATUS
rpc_query_domain_sid(struct net_context
*c
,
6686 const struct dom_sid
*domain_sid
,
6687 const char *domain_name
,
6688 struct cli_state
*cli
,
6689 struct rpc_pipe_client
*pipe_hnd
,
6690 TALLOC_CTX
*mem_ctx
,
6695 if (!sid_to_fstring(str_sid
, domain_sid
)) {
6696 return NT_STATUS_UNSUCCESSFUL
;
6698 d_printf("%s\n", str_sid
);
6699 return NT_STATUS_OK
;
6702 static void print_trusted_domain(struct dom_sid
*dom_sid
, const char *trusted_dom_name
)
6706 /* convert sid into ascii string */
6707 sid_to_fstring(ascii_sid
, dom_sid
);
6709 d_printf("%-20s%s\n", trusted_dom_name
, ascii_sid
);
6712 static NTSTATUS
vampire_trusted_domain(struct rpc_pipe_client
*pipe_hnd
,
6713 TALLOC_CTX
*mem_ctx
,
6714 struct policy_handle
*pol
,
6715 struct dom_sid dom_sid
,
6716 const char *trusted_dom_name
)
6718 NTSTATUS nt_status
, result
;
6719 union lsa_TrustedDomainInfo
*info
= NULL
;
6720 char *cleartextpwd
= NULL
;
6721 DATA_BLOB session_key
;
6722 DATA_BLOB data
= data_blob_null
;
6723 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6725 nt_status
= dcerpc_lsa_QueryTrustedDomainInfoBySid(b
, mem_ctx
,
6728 LSA_TRUSTED_DOMAIN_INFO_PASSWORD
,
6731 if (NT_STATUS_IS_ERR(nt_status
)) {
6732 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6733 nt_errstr(nt_status
)));
6736 if (NT_STATUS_IS_ERR(result
)) {
6738 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6739 nt_errstr(result
)));
6743 data
= data_blob(info
->password
.password
->data
,
6744 info
->password
.password
->length
);
6746 nt_status
= cli_get_session_key(mem_ctx
, pipe_hnd
, &session_key
);
6747 if (!NT_STATUS_IS_OK(nt_status
)) {
6748 DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status
)));
6752 cleartextpwd
= sess_decrypt_string(mem_ctx
, &data
, &session_key
);
6753 data_blob_free(&session_key
);
6755 if (cleartextpwd
== NULL
) {
6756 DEBUG(0,("retrieved NULL password\n"));
6757 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6761 if (!pdb_set_trusteddom_pw(trusted_dom_name
, cleartextpwd
, &dom_sid
)) {
6762 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6763 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6767 #ifdef DEBUG_PASSWORD
6768 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6769 "password: [%s]\n", trusted_dom_name
,
6770 sid_string_dbg(&dom_sid
), cleartextpwd
));
6774 SAFE_FREE(cleartextpwd
);
6775 data_blob_free(&data
);
6780 static int rpc_trustdom_vampire(struct net_context
*c
, int argc
,
6783 /* common variables */
6784 TALLOC_CTX
* mem_ctx
;
6785 struct cli_state
*cli
= NULL
;
6786 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6787 NTSTATUS nt_status
, result
;
6788 const char *domain_name
= NULL
;
6789 struct policy_handle connect_hnd
;
6790 union lsa_PolicyInformation
*info
= NULL
;
6792 /* trusted domains listing variables */
6793 unsigned int enum_ctx
= 0;
6795 struct lsa_DomainList dom_list
;
6797 struct dcerpc_binding_handle
*b
;
6799 if (c
->display_usage
) {
6801 "net rpc trustdom vampire\n"
6804 _("Vampire trust relationship from remote server"));
6809 * Listing trusted domains (stored in secrets.tdb, if local)
6812 mem_ctx
= talloc_init("trust relationships vampire");
6815 * set domain and pdc name to local samba server (default)
6816 * or to remote one given in command line
6819 if (strcasecmp_m(c
->opt_workgroup
, lp_workgroup())) {
6820 domain_name
= c
->opt_workgroup
;
6821 c
->opt_target_workgroup
= c
->opt_workgroup
;
6823 fstrcpy(pdc_name
, lp_netbios_name());
6824 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
6825 c
->opt_target_workgroup
= domain_name
;
6828 /* open \PIPE\lsarpc and open policy handle */
6829 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
6830 if (!NT_STATUS_IS_OK(nt_status
)) {
6831 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6832 nt_errstr(nt_status
)));
6833 talloc_destroy(mem_ctx
);
6837 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
6839 if (!NT_STATUS_IS_OK(nt_status
)) {
6840 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6841 nt_errstr(nt_status
) ));
6843 talloc_destroy(mem_ctx
);
6847 b
= pipe_hnd
->binding_handle
;
6849 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, KEY_QUERY_VALUE
,
6851 if (NT_STATUS_IS_ERR(nt_status
)) {
6852 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6853 nt_errstr(nt_status
)));
6855 talloc_destroy(mem_ctx
);
6859 /* query info level 5 to obtain sid of a domain being queried */
6860 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
6862 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6866 if (NT_STATUS_IS_ERR(nt_status
)) {
6867 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6868 nt_errstr(nt_status
)));
6870 talloc_destroy(mem_ctx
);
6873 if (NT_STATUS_IS_ERR(result
)) {
6874 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6875 nt_errstr(result
)));
6877 talloc_destroy(mem_ctx
);
6882 * Keep calling LsaEnumTrustdom over opened pipe until
6883 * the end of enumeration is reached
6886 d_printf(_("Vampire trusted domains:\n\n"));
6889 nt_status
= dcerpc_lsa_EnumTrustDom(b
, mem_ctx
,
6895 if (NT_STATUS_IS_ERR(nt_status
)) {
6896 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6897 nt_errstr(nt_status
)));
6899 talloc_destroy(mem_ctx
);
6902 if (NT_STATUS_IS_ERR(result
)) {
6904 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6905 nt_errstr(result
)));
6907 talloc_destroy(mem_ctx
);
6912 for (i
= 0; i
< dom_list
.count
; i
++) {
6914 print_trusted_domain(dom_list
.domains
[i
].sid
,
6915 dom_list
.domains
[i
].name
.string
);
6917 nt_status
= vampire_trusted_domain(pipe_hnd
, mem_ctx
, &connect_hnd
,
6918 *dom_list
.domains
[i
].sid
,
6919 dom_list
.domains
[i
].name
.string
);
6920 if (!NT_STATUS_IS_OK(nt_status
)) {
6922 talloc_destroy(mem_ctx
);
6928 * in case of no trusted domains say something rather
6929 * than just display blank line
6931 if (!dom_list
.count
) d_printf(_("none\n"));
6933 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
6935 /* close this connection before doing next one */
6936 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
6937 if (NT_STATUS_IS_ERR(nt_status
)) {
6938 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6939 nt_errstr(nt_status
)));
6941 talloc_destroy(mem_ctx
);
6945 /* close lsarpc pipe and connection to IPC$ */
6948 talloc_destroy(mem_ctx
);
6952 static int rpc_trustdom_list(struct net_context
*c
, int argc
, const char **argv
)
6954 /* common variables */
6955 TALLOC_CTX
* mem_ctx
;
6956 struct cli_state
*cli
= NULL
, *remote_cli
= NULL
;
6957 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6958 NTSTATUS nt_status
, result
;
6959 const char *domain_name
= NULL
;
6960 struct dom_sid
*queried_dom_sid
;
6961 int ascii_dom_name_len
;
6962 struct policy_handle connect_hnd
;
6963 union lsa_PolicyInformation
*info
= NULL
;
6964 struct dcerpc_binding_handle
*b
= NULL
;
6966 /* trusted domains listing variables */
6967 unsigned int num_domains
, enum_ctx
= 0;
6969 struct lsa_DomainList dom_list
;
6973 /* trusting domains listing variables */
6974 struct policy_handle domain_hnd
;
6975 struct samr_SamArray
*trusts
= NULL
;
6977 if (c
->display_usage
) {
6979 "net rpc trustdom list\n"
6982 _("List incoming and outgoing trust relationships"));
6987 * Listing trusted domains (stored in secrets.tdb, if local)
6990 mem_ctx
= talloc_init("trust relationships listing");
6993 * set domain and pdc name to local samba server (default)
6994 * or to remote one given in command line
6997 if (strcasecmp_m(c
->opt_workgroup
, lp_workgroup())) {
6998 domain_name
= c
->opt_workgroup
;
6999 c
->opt_target_workgroup
= c
->opt_workgroup
;
7001 fstrcpy(pdc_name
, lp_netbios_name());
7002 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
7003 c
->opt_target_workgroup
= domain_name
;
7006 /* open \PIPE\lsarpc and open policy handle */
7007 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
7008 if (!NT_STATUS_IS_OK(nt_status
)) {
7009 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
7010 nt_errstr(nt_status
)));
7011 talloc_destroy(mem_ctx
);
7015 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
7017 if (!NT_STATUS_IS_OK(nt_status
)) {
7018 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
7019 nt_errstr(nt_status
) ));
7021 talloc_destroy(mem_ctx
);
7025 b
= pipe_hnd
->binding_handle
;
7027 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, KEY_QUERY_VALUE
,
7029 if (NT_STATUS_IS_ERR(nt_status
)) {
7030 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
7031 nt_errstr(nt_status
)));
7033 talloc_destroy(mem_ctx
);
7037 /* query info level 5 to obtain sid of a domain being queried */
7038 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
7040 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
7044 if (NT_STATUS_IS_ERR(nt_status
)) {
7045 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7046 nt_errstr(nt_status
)));
7048 talloc_destroy(mem_ctx
);
7051 if (NT_STATUS_IS_ERR(result
)) {
7052 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7053 nt_errstr(result
)));
7055 talloc_destroy(mem_ctx
);
7059 queried_dom_sid
= info
->account_domain
.sid
;
7062 * Keep calling LsaEnumTrustdom over opened pipe until
7063 * the end of enumeration is reached
7066 d_printf(_("Trusted domains list:\n\n"));
7068 found_domain
= false;
7071 nt_status
= dcerpc_lsa_EnumTrustDom(b
, mem_ctx
,
7077 if (NT_STATUS_IS_ERR(nt_status
)) {
7078 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7079 nt_errstr(nt_status
)));
7081 talloc_destroy(mem_ctx
);
7084 if (NT_STATUS_IS_ERR(result
)) {
7085 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7086 nt_errstr(result
)));
7088 talloc_destroy(mem_ctx
);
7093 for (i
= 0; i
< dom_list
.count
; i
++) {
7094 print_trusted_domain(dom_list
.domains
[i
].sid
,
7095 dom_list
.domains
[i
].name
.string
);
7096 found_domain
= true;
7100 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
7103 * in case of no trusted domains say something rather
7104 * than just display blank line
7106 if (!found_domain
) {
7107 d_printf(_("none\n"));
7110 /* close this connection before doing next one */
7111 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
7112 if (NT_STATUS_IS_ERR(nt_status
)) {
7113 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7114 nt_errstr(nt_status
)));
7116 talloc_destroy(mem_ctx
);
7120 TALLOC_FREE(pipe_hnd
);
7123 * Listing trusting domains (stored in passdb backend, if local)
7126 d_printf(_("\nTrusting domains list:\n\n"));
7129 * Open \PIPE\samr and get needed policy handles
7131 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_samr
,
7133 if (!NT_STATUS_IS_OK(nt_status
)) {
7134 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status
)));
7136 talloc_destroy(mem_ctx
);
7140 b
= pipe_hnd
->binding_handle
;
7143 nt_status
= dcerpc_samr_Connect2(b
, mem_ctx
,
7145 SAMR_ACCESS_LOOKUP_DOMAIN
,
7148 if (!NT_STATUS_IS_OK(nt_status
)) {
7149 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7150 nt_errstr(nt_status
)));
7152 talloc_destroy(mem_ctx
);
7155 if (!NT_STATUS_IS_OK(result
)) {
7157 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7158 nt_errstr(result
)));
7160 talloc_destroy(mem_ctx
);
7164 /* SamrOpenDomain - we have to open domain policy handle in order to be
7165 able to enumerate accounts*/
7166 nt_status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
7168 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
7172 if (!NT_STATUS_IS_OK(nt_status
)) {
7173 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7174 nt_errstr(nt_status
)));
7176 talloc_destroy(mem_ctx
);
7179 if (!NT_STATUS_IS_OK(result
)) {
7181 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7182 nt_errstr(result
)));
7184 talloc_destroy(mem_ctx
);
7189 * perform actual enumeration
7192 found_domain
= false;
7194 enum_ctx
= 0; /* reset enumeration context from last enumeration */
7197 nt_status
= dcerpc_samr_EnumDomainUsers(b
, mem_ctx
,
7205 if (NT_STATUS_IS_ERR(nt_status
)) {
7206 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7207 nt_errstr(nt_status
)));
7209 talloc_destroy(mem_ctx
);
7212 if (NT_STATUS_IS_ERR(result
)) {
7214 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7215 nt_errstr(result
)));
7217 talloc_destroy(mem_ctx
);
7221 for (i
= 0; i
< num_domains
; i
++) {
7223 char *str
= discard_const_p(char, trusts
->entries
[i
].name
.string
);
7225 found_domain
= true;
7228 * get each single domain's sid (do we _really_ need this ?):
7229 * 1) connect to domain's pdc
7230 * 2) query the pdc for domain's sid
7233 /* get rid of '$' tail */
7234 ascii_dom_name_len
= strlen(str
);
7235 if (ascii_dom_name_len
&& ascii_dom_name_len
< FSTRING_LEN
)
7236 str
[ascii_dom_name_len
- 1] = '\0';
7238 /* set opt_* variables to remote domain */
7239 if (!strupper_m(str
)) {
7241 talloc_destroy(mem_ctx
);
7244 c
->opt_workgroup
= talloc_strdup(mem_ctx
, str
);
7245 c
->opt_target_workgroup
= c
->opt_workgroup
;
7247 d_printf("%-20s", str
);
7249 /* connect to remote domain controller */
7250 nt_status
= net_make_ipc_connection(c
,
7251 NET_FLAGS_PDC
| NET_FLAGS_ANONYMOUS
,
7253 if (NT_STATUS_IS_OK(nt_status
)) {
7254 /* query for domain's sid */
7255 if (run_rpc_command(
7257 &ndr_table_lsarpc
, 0,
7258 rpc_query_domain_sid
, argc
,
7260 d_printf(_("strange - couldn't get domain's sid\n"));
7262 cli_shutdown(remote_cli
);
7265 d_fprintf(stderr
, _("domain controller is not "
7266 "responding: %s\n"),
7267 nt_errstr(nt_status
));
7268 d_printf(_("couldn't get domain's sid\n"));
7272 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
7274 if (!found_domain
) {
7278 /* close opened samr and domain policy handles */
7279 nt_status
= dcerpc_samr_Close(b
, mem_ctx
, &domain_hnd
, &result
);
7280 if (!NT_STATUS_IS_OK(nt_status
)) {
7281 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name
));
7284 nt_status
= dcerpc_samr_Close(b
, mem_ctx
, &connect_hnd
, &result
);
7285 if (!NT_STATUS_IS_OK(nt_status
)) {
7286 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name
));
7289 /* close samr pipe and connection to IPC$ */
7292 talloc_destroy(mem_ctx
);
7297 * Entrypoint for 'net rpc trustdom' code.
7299 * @param argc Standard argc.
7300 * @param argv Standard argv without initial components.
7302 * @return Integer status (0 means success).
7305 static int rpc_trustdom(struct net_context
*c
, int argc
, const char **argv
)
7307 struct functable func
[] = {
7312 N_("Add trusting domain's account"),
7313 N_("net rpc trustdom add\n"
7314 " Add trusting domain's account")
7320 N_("Remove trusting domain's account"),
7321 N_("net rpc trustdom del\n"
7322 " Remove trusting domain's account")
7326 rpc_trustdom_establish
,
7328 N_("Establish outgoing trust relationship"),
7329 N_("net rpc trustdom establish\n"
7330 " Establish outgoing trust relationship")
7334 rpc_trustdom_revoke
,
7336 N_("Revoke outgoing trust relationship"),
7337 N_("net rpc trustdom revoke\n"
7338 " Revoke outgoing trust relationship")
7344 N_("List in- and outgoing domain trusts"),
7345 N_("net rpc trustdom list\n"
7346 " List in- and outgoing domain trusts")
7350 rpc_trustdom_vampire
,
7352 N_("Vampire trusts from remote server"),
7353 N_("net rpc trustdom vampire\n"
7354 " Vampire trusts from remote server")
7356 {NULL
, NULL
, 0, NULL
, NULL
}
7359 return net_run_function(c
, argc
, argv
, "net rpc trustdom", func
);
7363 * Check if a server will take rpc commands
7364 * @param flags Type of server to connect to (PDC, DMB, localhost)
7365 * if the host is not explicitly specified
7366 * @return bool (true means rpc supported)
7368 bool net_rpc_check(struct net_context
*c
, unsigned flags
)
7370 struct cli_state
*cli
;
7372 struct sockaddr_storage server_ss
;
7373 char *server_name
= NULL
;
7376 /* flags (i.e. server type) may depend on command */
7377 if (!net_find_server(c
, NULL
, flags
, &server_ss
, &server_name
))
7380 status
= cli_connect_nb(server_name
, &server_ss
, 0, 0x20,
7381 lp_netbios_name(), SMB_SIGNING_DEFAULT
,
7383 if (!NT_STATUS_IS_OK(status
)) {
7386 status
= smbXcli_negprot(cli
->conn
, cli
->timeout
, PROTOCOL_CORE
,
7388 if (!NT_STATUS_IS_OK(status
))
7390 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
)
7399 /* dump sam database via samsync rpc calls */
7400 static int rpc_samdump(struct net_context
*c
, int argc
, const char **argv
) {
7401 if (c
->display_usage
) {
7406 _("Dump remote SAM database"));
7410 return run_rpc_command(c
, NULL
, &ndr_table_netlogon
,
7411 NET_FLAGS_ANONYMOUS
,
7412 rpc_samdump_internals
, argc
, argv
);
7415 /* syncronise sam database via samsync rpc calls */
7416 static int rpc_vampire(struct net_context
*c
, int argc
, const char **argv
)
7418 struct functable func
[] = {
7423 N_("Dump remote SAM database to ldif"),
7424 N_("net rpc vampire ldif\n"
7425 " Dump remote SAM database to LDIF file or "
7432 N_("Dump remote SAM database to Kerberos Keytab"),
7433 N_("net rpc vampire keytab\n"
7434 " Dump remote SAM database to Kerberos keytab "
7441 N_("Dump remote SAM database to passdb"),
7442 N_("net rpc vampire passdb\n"
7443 " Dump remote SAM database to passdb")
7446 {NULL
, NULL
, 0, NULL
, NULL
}
7450 if (c
->display_usage
) {
7455 _("Vampire remote SAM database"));
7459 return rpc_vampire_passdb(c
, argc
, argv
);
7462 return net_run_function(c
, argc
, argv
, "net rpc vampire", func
);
7466 * Migrate everything from a print server.
7468 * @param c A net_context structure.
7469 * @param argc Standard main() style argc.
7470 * @param argv Standard main() style argv. Initial components are already
7473 * @return A shell status integer (0 for success).
7475 * The order is important !
7476 * To successfully add drivers the print queues have to exist !
7477 * Applying ACLs should be the last step, because you're easily locked out.
7480 static int rpc_printer_migrate_all(struct net_context
*c
, int argc
,
7485 if (c
->display_usage
) {
7487 "net rpc printer migrate all\n"
7490 _("Migrate everything from a print server"));
7495 d_printf(_("no server to migrate\n"));
7499 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7500 rpc_printer_migrate_printers_internals
, argc
,
7505 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7506 rpc_printer_migrate_drivers_internals
, argc
,
7511 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7512 rpc_printer_migrate_forms_internals
, argc
, argv
);
7516 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7517 rpc_printer_migrate_settings_internals
, argc
,
7522 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7523 rpc_printer_migrate_security_internals
, argc
,
7529 * Migrate print drivers from a print server.
7531 * @param c A net_context structure.
7532 * @param argc Standard main() style argc.
7533 * @param argv Standard main() style argv. Initial components are already
7536 * @return A shell status integer (0 for success).
7538 static int rpc_printer_migrate_drivers(struct net_context
*c
, int argc
,
7541 if (c
->display_usage
) {
7543 "net rpc printer migrate drivers\n"
7546 _("Migrate print-drivers from a print-server"));
7551 d_printf(_("no server to migrate\n"));
7555 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7556 rpc_printer_migrate_drivers_internals
,
7561 * Migrate print-forms from a print-server.
7563 * @param c A net_context structure.
7564 * @param argc Standard main() style argc.
7565 * @param argv Standard main() style argv. Initial components are already
7568 * @return A shell status integer (0 for success).
7570 static int rpc_printer_migrate_forms(struct net_context
*c
, int argc
,
7573 if (c
->display_usage
) {
7575 "net rpc printer migrate forms\n"
7578 _("Migrate print-forms from a print-server"));
7583 d_printf(_("no server to migrate\n"));
7587 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7588 rpc_printer_migrate_forms_internals
,
7593 * Migrate printers from a print-server.
7595 * @param c A net_context structure.
7596 * @param argc Standard main() style argc.
7597 * @param argv Standard main() style argv. Initial components are already
7600 * @return A shell status integer (0 for success).
7602 static int rpc_printer_migrate_printers(struct net_context
*c
, int argc
,
7605 if (c
->display_usage
) {
7607 "net rpc printer migrate printers\n"
7610 _("Migrate printers from a print-server"));
7615 d_printf(_("no server to migrate\n"));
7619 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7620 rpc_printer_migrate_printers_internals
,
7625 * Migrate printer-ACLs from a print-server
7627 * @param c A net_context structure.
7628 * @param argc Standard main() style argc.
7629 * @param argv Standard main() style argv. Initial components are already
7632 * @return A shell status integer (0 for success).
7634 static int rpc_printer_migrate_security(struct net_context
*c
, int argc
,
7637 if (c
->display_usage
) {
7639 "net rpc printer migrate security\n"
7642 _("Migrate printer-ACLs from a print-server"));
7647 d_printf(_("no server to migrate\n"));
7651 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7652 rpc_printer_migrate_security_internals
,
7657 * Migrate printer-settings from a print-server.
7659 * @param c A net_context structure.
7660 * @param argc Standard main() style argc.
7661 * @param argv Standard main() style argv. Initial components are already
7664 * @return A shell status integer (0 for success).
7666 static int rpc_printer_migrate_settings(struct net_context
*c
, int argc
,
7669 if (c
->display_usage
) {
7671 "net rpc printer migrate settings\n"
7674 _("Migrate printer-settings from a "
7680 d_printf(_("no server to migrate\n"));
7684 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7685 rpc_printer_migrate_settings_internals
,
7690 * 'net rpc printer' entrypoint.
7692 * @param c A net_context structure.
7693 * @param argc Standard main() style argc.
7694 * @param argv Standard main() style argv. Initial components are already
7698 int rpc_printer_migrate(struct net_context
*c
, int argc
, const char **argv
)
7701 /* ouch: when addriver and setdriver are called from within
7702 rpc_printer_migrate_drivers_internals, the printer-queue already
7705 struct functable func
[] = {
7708 rpc_printer_migrate_all
,
7710 N_("Migrate all from remote to local print server"),
7711 N_("net rpc printer migrate all\n"
7712 " Migrate all from remote to local print server")
7716 rpc_printer_migrate_drivers
,
7718 N_("Migrate drivers to local server"),
7719 N_("net rpc printer migrate drivers\n"
7720 " Migrate drivers to local server")
7724 rpc_printer_migrate_forms
,
7726 N_("Migrate froms to local server"),
7727 N_("net rpc printer migrate forms\n"
7728 " Migrate froms to local server")
7732 rpc_printer_migrate_printers
,
7734 N_("Migrate printers to local server"),
7735 N_("net rpc printer migrate printers\n"
7736 " Migrate printers to local server")
7740 rpc_printer_migrate_security
,
7742 N_("Mirgate printer ACLs to local server"),
7743 N_("net rpc printer migrate security\n"
7744 " Mirgate printer ACLs to local server")
7748 rpc_printer_migrate_settings
,
7750 N_("Migrate printer settings to local server"),
7751 N_("net rpc printer migrate settings\n"
7752 " Migrate printer settings to local server")
7754 {NULL
, NULL
, 0, NULL
, NULL
}
7757 return net_run_function(c
, argc
, argv
, "net rpc printer migrate",func
);
7762 * List printers on a remote RPC server.
7764 * @param c A net_context structure.
7765 * @param argc Standard main() style argc.
7766 * @param argv Standard main() style argv. Initial components are already
7769 * @return A shell status integer (0 for success).
7771 static int rpc_printer_list(struct net_context
*c
, int argc
, const char **argv
)
7773 if (c
->display_usage
) {
7775 "net rpc printer list\n"
7778 _("List printers on a remote RPC server"));
7782 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7783 rpc_printer_list_internals
,
7788 * List printer-drivers on a remote RPC server.
7790 * @param c A net_context structure.
7791 * @param argc Standard main() style argc.
7792 * @param argv Standard main() style argv. Initial components are already
7795 * @return A shell status integer (0 for success).
7797 static int rpc_printer_driver_list(struct net_context
*c
, int argc
,
7800 if (c
->display_usage
) {
7802 "net rpc printer driver\n"
7805 _("List printer-drivers on a remote RPC server"));
7809 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7810 rpc_printer_driver_list_internals
,
7815 * Publish printer in ADS via MSRPC.
7817 * @param c A net_context structure.
7818 * @param argc Standard main() style argc.
7819 * @param argv Standard main() style argv. Initial components are already
7822 * @return A shell status integer (0 for success).
7824 static int rpc_printer_publish_publish(struct net_context
*c
, int argc
,
7827 if (c
->display_usage
) {
7829 "net rpc printer publish publish\n"
7832 _("Publish printer in ADS via MSRPC"));
7836 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7837 rpc_printer_publish_publish_internals
,
7842 * Update printer in ADS via MSRPC.
7844 * @param c A net_context structure.
7845 * @param argc Standard main() style argc.
7846 * @param argv Standard main() style argv. Initial components are already
7849 * @return A shell status integer (0 for success).
7851 static int rpc_printer_publish_update(struct net_context
*c
, int argc
, const char **argv
)
7853 if (c
->display_usage
) {
7855 "net rpc printer publish update\n"
7858 _("Update printer in ADS via MSRPC"));
7862 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7863 rpc_printer_publish_update_internals
,
7868 * UnPublish printer in ADS via MSRPC.
7870 * @param c A net_context structure.
7871 * @param argc Standard main() style argc.
7872 * @param argv Standard main() style argv. Initial components are already
7875 * @return A shell status integer (0 for success).
7877 static int rpc_printer_publish_unpublish(struct net_context
*c
, int argc
,
7880 if (c
->display_usage
) {
7882 "net rpc printer publish unpublish\n"
7885 _("UnPublish printer in ADS via MSRPC"));
7889 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7890 rpc_printer_publish_unpublish_internals
,
7895 * List published printers via MSRPC.
7897 * @param c A net_context structure.
7898 * @param argc Standard main() style argc.
7899 * @param argv Standard main() style argv. Initial components are already
7902 * @return A shell status integer (0 for success).
7904 static int rpc_printer_publish_list(struct net_context
*c
, int argc
,
7907 if (c
->display_usage
) {
7909 "net rpc printer publish list\n"
7912 _("List published printers via MSRPC"));
7916 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7917 rpc_printer_publish_list_internals
,
7923 * Publish printer in ADS.
7925 * @param c A net_context structure.
7926 * @param argc Standard main() style argc.
7927 * @param argv Standard main() style argv. Initial components are already
7930 * @return A shell status integer (0 for success).
7932 static int rpc_printer_publish(struct net_context
*c
, int argc
,
7936 struct functable func
[] = {
7939 rpc_printer_publish_publish
,
7941 N_("Publish printer in AD"),
7942 N_("net rpc printer publish publish\n"
7943 " Publish printer in AD")
7947 rpc_printer_publish_update
,
7949 N_("Update printer in AD"),
7950 N_("net rpc printer publish update\n"
7951 " Update printer in AD")
7955 rpc_printer_publish_unpublish
,
7957 N_("Unpublish printer"),
7958 N_("net rpc printer publish unpublish\n"
7959 " Unpublish printer")
7963 rpc_printer_publish_list
,
7965 N_("List published printers"),
7966 N_("net rpc printer publish list\n"
7967 " List published printers")
7969 {NULL
, NULL
, 0, NULL
, NULL
}
7973 if (c
->display_usage
) {
7974 d_printf(_("Usage:\n"));
7975 d_printf(_("net rpc printer publish\n"
7976 " List published printers\n"
7977 " Alias of net rpc printer publish "
7979 net_display_usage_from_functable(func
);
7982 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7983 rpc_printer_publish_list_internals
,
7987 return net_run_function(c
, argc
, argv
, "net rpc printer publish",func
);
7993 * Display rpc printer help page.
7995 * @param c A net_context structure.
7996 * @param argc Standard main() style argc.
7997 * @param argv Standard main() style argv. Initial components are already
8000 int rpc_printer_usage(struct net_context
*c
, int argc
, const char **argv
)
8002 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
8003 "\tlists all printers on print-server\n\n"));
8004 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
8005 "\tlists all printer-drivers on print-server\n\n"));
8006 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
8007 "\tpublishes printer settings in Active Directory\n"
8008 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
8009 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
8010 "\n\tmigrates printers from remote to local server\n\n"));
8011 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
8012 "\n\tmigrates printer-settings from remote to local server\n\n"));
8013 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
8014 "\n\tmigrates printer-drivers from remote to local server\n\n"));
8015 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
8016 "\n\tmigrates printer-forms from remote to local server\n\n"));
8017 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
8018 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
8019 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
8020 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
8021 "\tremote to local print-server\n\n"));
8022 net_common_methods_usage(c
, argc
, argv
);
8023 net_common_flags_usage(c
, argc
, argv
);
8025 "\t-v or --verbose\t\t\tgive verbose output\n"
8026 "\t --destination\t\tmigration target server (default: localhost)\n"));
8032 * 'net rpc printer' entrypoint.
8034 * @param c A net_context structure.
8035 * @param argc Standard main() style argc.
8036 * @param argv Standard main() style argv. Initial components are already
8039 int net_rpc_printer(struct net_context
*c
, int argc
, const char **argv
)
8041 struct functable func
[] = {
8046 N_("List all printers on print server"),
8047 N_("net rpc printer list\n"
8048 " List all printers on print server")
8052 rpc_printer_migrate
,
8054 N_("Migrate printer to local server"),
8055 N_("net rpc printer migrate\n"
8056 " Migrate printer to local server")
8060 rpc_printer_driver_list
,
8062 N_("List printer drivers"),
8063 N_("net rpc printer driver\n"
8064 " List printer drivers")
8068 rpc_printer_publish
,
8070 N_("Publish printer in AD"),
8071 N_("net rpc printer publish\n"
8072 " Publish printer in AD")
8074 {NULL
, NULL
, 0, NULL
, NULL
}
8078 if (c
->display_usage
) {
8079 d_printf(_("Usage:\n"));
8080 d_printf(_("net rpc printer\n"
8081 " List printers\n"));
8082 net_display_usage_from_functable(func
);
8085 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
8086 rpc_printer_list_internals
,
8090 return net_run_function(c
, argc
, argv
, "net rpc printer", func
);
8094 * 'net rpc' entrypoint.
8096 * @param c A net_context structure.
8097 * @param argc Standard main() style argc.
8098 * @param argv Standard main() style argv. Initial components are already
8102 int net_rpc(struct net_context
*c
, int argc
, const char **argv
)
8104 NET_API_STATUS status
;
8106 struct functable func
[] = {
8111 N_("Modify global audit settings"),
8112 N_("net rpc audit\n"
8113 " Modify global audit settings")
8119 N_("Show basic info about a domain"),
8121 " Show basic info about a domain")
8127 N_("Join a domain"),
8135 N_("Join a domain created in server manager"),
8136 N_("net rpc oldjoin\n"
8137 " Join a domain created in server manager")
8143 N_("Test that a join is valid"),
8144 N_("net rpc testjoin\n"
8145 " Test that a join is valid")
8151 N_("List/modify users"),
8153 " List/modify users")
8159 N_("Change a user password"),
8160 N_("net rpc password\n"
8161 " Change a user password\n"
8162 " Alias for net rpc user password")
8168 N_("List/modify groups"),
8169 N_("net rpc group\n"
8170 " List/modify groups")
8176 N_("List/modify shares"),
8177 N_("net rpc share\n"
8178 " List/modify shares")
8184 N_("List open files"),
8192 N_("List/modify printers"),
8193 N_("net rpc printer\n"
8194 " List/modify printers")
8198 net_rpc_changetrustpw
,
8200 N_("Change trust account password"),
8201 N_("net rpc changetrustpw\n"
8202 " Change trust account password")
8208 N_("Modify domain trusts"),
8209 N_("net rpc trustdom\n"
8210 " Modify domain trusts")
8216 N_("Abort a remote shutdown"),
8217 N_("net rpc abortshutdown\n"
8218 " Abort a remote shutdown")
8224 N_("Shutdown a remote server"),
8225 N_("net rpc shutdown\n"
8226 " Shutdown a remote server")
8232 N_("Dump SAM data of remote NT PDC"),
8233 N_("net rpc samdump\n"
8234 " Dump SAM data of remote NT PDC")
8240 N_("Sync a remote NT PDC's data into local passdb"),
8241 N_("net rpc vampire\n"
8242 " Sync a remote NT PDC's data into local passdb")
8248 N_("Fetch the domain sid into local secrets.tdb"),
8249 N_("net rpc getsid\n"
8250 " Fetch the domain sid into local secrets.tdb")
8256 N_("Manage privileges assigned to SID"),
8257 N_("net rpc rights\n"
8258 " Manage privileges assigned to SID")
8264 N_("Start/stop/query remote services"),
8265 N_("net rpc service\n"
8266 " Start/stop/query remote services")
8272 N_("Manage registry hives"),
8273 N_("net rpc registry\n"
8274 " Manage registry hives")
8280 N_("Open interactive shell on remote server"),
8281 N_("net rpc shell\n"
8282 " Open interactive shell on remote server")
8288 N_("Manage trusts"),
8289 N_("net rpc trust\n"
8296 N_("Configure a remote samba server"),
8298 " Configure a remote samba server")
8300 {NULL
, NULL
, 0, NULL
, NULL
}
8303 status
= libnetapi_net_init(&c
->netapi_ctx
);
8307 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
8308 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
8309 if (c
->opt_kerberos
) {
8310 libnetapi_set_use_kerberos(c
->netapi_ctx
);
8312 if (c
->opt_ccache
) {
8313 libnetapi_set_use_ccache(c
->netapi_ctx
);
8316 return net_run_function(c
, argc
, argv
, "net rpc", func
);