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
,
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 CRED_DONT_USE_KERBEROS
,
212 DCERPC_AUTH_TYPE_NTLMSSP
,
213 DCERPC_AUTH_LEVEL_PRIVACY
,
214 smbXcli_conn_remote_name(cli
->conn
),
215 lp_workgroup(), c
->opt_user_name
,
216 c
->opt_password
, &pipe_hnd
);
218 nt_status
= cli_rpc_pipe_open_noauth(
222 if (!NT_STATUS_IS_OK(nt_status
)) {
223 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
225 nt_errstr(nt_status
) ));
231 nt_status
= fn(c
, domain_sid
, domain_name
, cli
, pipe_hnd
, mem_ctx
, argc
, argv
);
233 if (!NT_STATUS_IS_OK(nt_status
)) {
234 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status
)));
237 DEBUG(5, ("rpc command function succedded\n"));
240 if (!(conn_flags
& NET_FLAGS_NO_PIPE
)) {
242 TALLOC_FREE(pipe_hnd
);
247 /* close the connection only if it was opened here */
252 talloc_destroy(mem_ctx
);
257 * Force a change of the trust acccount password.
259 * All parameters are provided by the run_rpc_command function, except for
260 * argc, argv which are passed through.
262 * @param domain_sid The domain sid acquired from the remote server.
263 * @param cli A cli_state connected to the server.
264 * @param mem_ctx Talloc context, destroyed on completion of the function.
265 * @param argc Standard main() style argc.
266 * @param argv Standard main() style argv. Initial components are already
269 * @return Normal NTSTATUS return.
272 static NTSTATUS
rpc_changetrustpw_internals(struct net_context
*c
,
273 const struct dom_sid
*domain_sid
,
274 const char *domain_name
,
275 struct cli_state
*cli
,
276 struct rpc_pipe_client
*pipe_hnd
,
282 const char *dcname
= NULL
;
285 return NT_STATUS_INTERNAL_ERROR
;
288 dcname
= smbXcli_conn_remote_name(cli
->conn
);
290 status
= trust_pw_change(c
->netlogon_creds
,
292 pipe_hnd
->binding_handle
,
293 c
->opt_target_workgroup
,
296 if (!NT_STATUS_IS_OK(status
)) {
297 d_fprintf(stderr
, _("Failed to change machine account password: %s\n"),
306 * Force a change of the trust acccount password.
308 * @param argc Standard main() style argc.
309 * @param argv Standard main() style argv. Initial components are already
312 * @return A shell status integer (0 for success).
315 int net_rpc_changetrustpw(struct net_context
*c
, int argc
, const char **argv
)
317 if (c
->display_usage
) {
319 "net rpc changetrustpw\n"
322 _("Change the machine trust password"));
326 return run_rpc_command(c
, NULL
, &ndr_table_netlogon
,
327 NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
,
328 rpc_changetrustpw_internals
,
333 * Join a domain, the old way. This function exists to allow
334 * the message to be displayed when oldjoin was explicitly
335 * requested, but not when it was implied by "net rpc join".
337 * This uses 'machinename' as the inital password, and changes it.
339 * The password should be created with 'server manager' or equiv first.
341 * @param argc Standard main() style argc.
342 * @param argv Standard main() style argv. Initial components are already
345 * @return A shell status integer (0 for success).
348 static int net_rpc_oldjoin(struct net_context
*c
, int argc
, const char **argv
)
350 struct libnet_JoinCtx
*r
= NULL
;
353 const char *domain
= lp_workgroup(); /* FIXME */
354 bool modify_config
= lp_config_backend_is_registry();
355 enum netr_SchannelType sec_chan_type
;
358 if (c
->display_usage
) {
361 " Join a domain the old way\n");
365 mem_ctx
= talloc_init("net_rpc_oldjoin");
370 werr
= libnet_init_JoinCtx(mem_ctx
, &r
);
371 if (!W_ERROR_IS_OK(werr
)) {
376 check what type of join - if the user want's to join as
377 a BDC, the server must agree that we are a BDC.
380 sec_chan_type
= get_sec_channel_type(argv
[0]);
382 sec_chan_type
= get_sec_channel_type(NULL
);
386 d_fprintf(stderr
, _("Could not initialise message context. "
387 "Try running as root\n"));
388 werr
= WERR_ACCESS_DENIED
;
392 pw
= talloc_strndup(r
, lp_netbios_name(), 14);
394 werr
= WERR_NOT_ENOUGH_MEMORY
;
398 r
->in
.msg_ctx
= c
->msg_ctx
;
399 r
->in
.domain_name
= domain
;
400 r
->in
.secure_channel_type
= sec_chan_type
;
401 r
->in
.dc_name
= c
->opt_host
;
402 r
->in
.admin_account
= "";
403 r
->in
.admin_password
= strlower_talloc(r
, pw
);
404 if (r
->in
.admin_password
== NULL
) {
405 werr
= WERR_NOT_ENOUGH_MEMORY
;
409 r
->in
.modify_config
= modify_config
;
410 r
->in
.join_flags
= WKSSVC_JOIN_FLAGS_JOIN_TYPE
|
411 WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
|
412 WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
;
414 werr
= libnet_Join(mem_ctx
, r
);
415 if (!W_ERROR_IS_OK(werr
)) {
419 /* Check the short name of the domain */
421 if (!modify_config
&& !strequal(lp_workgroup(), r
->out
.netbios_domain_name
)) {
422 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
423 d_printf("domain name obtained from the server.\n");
424 d_printf("Using the name [%s] from the server.\n", r
->out
.netbios_domain_name
);
425 d_printf("You should set \"workgroup = %s\" in %s.\n",
426 r
->out
.netbios_domain_name
, get_dyn_CONFIGFILE());
429 d_printf("Using short domain name -- %s\n", r
->out
.netbios_domain_name
);
431 if (r
->out
.dns_domain_name
) {
432 d_printf("Joined '%s' to realm '%s'\n", r
->in
.machine_name
,
433 r
->out
.dns_domain_name
);
435 d_printf("Joined '%s' to domain '%s'\n", r
->in
.machine_name
,
436 r
->out
.netbios_domain_name
);
439 /* print out informative error string in case there is one */
440 if (r
->out
.error_string
!= NULL
) {
441 d_printf("%s\n", r
->out
.error_string
);
444 TALLOC_FREE(mem_ctx
);
449 if (c
->opt_flags
& NET_FLAGS_EXPECT_FALLBACK
) {
453 /* issue an overall failure message at the end. */
454 d_fprintf(stderr
, _("Failed to join domain: %s\n"),
455 r
&& r
->out
.error_string
? r
->out
.error_string
:
456 get_friendly_werror_msg(werr
));
459 TALLOC_FREE(mem_ctx
);
465 * check that a join is OK
467 * @return A shell status integer (0 for success)
470 int net_rpc_testjoin(struct net_context
*c
, int argc
, const char **argv
)
474 const char *domain
= c
->opt_target_workgroup
;
475 const char *dc
= c
->opt_host
;
477 if (c
->display_usage
) {
480 " Test if a join is OK\n");
484 mem_ctx
= talloc_init("net_rpc_testjoin");
490 struct netr_DsRGetDCNameInfo
*info
;
493 d_fprintf(stderr
, _("Could not initialise message context. "
494 "Try running as root\n"));
495 talloc_destroy(mem_ctx
);
499 status
= dsgetdcname(mem_ctx
,
506 if (!NT_STATUS_IS_OK(status
)) {
507 talloc_destroy(mem_ctx
);
511 dc
= strip_hostname(info
->dc_unc
);
514 /* Display success or failure */
515 status
= libnet_join_ok(c
->msg_ctx
,
519 if (!NT_STATUS_IS_OK(status
)) {
520 fprintf(stderr
,"Join to domain '%s' is not valid: %s\n",
521 domain
, nt_errstr(status
));
522 talloc_destroy(mem_ctx
);
526 printf("Join to '%s' is OK\n",domain
);
527 talloc_destroy(mem_ctx
);
533 * Join a domain using the administrator username and password
535 * @param argc Standard main() style argc
536 * @param argc Standard main() style argv. Initial components are already
537 * stripped. Currently not used.
538 * @return A shell status integer (0 for success)
542 static int net_rpc_join_newstyle(struct net_context
*c
, int argc
, const char **argv
)
544 struct libnet_JoinCtx
*r
= NULL
;
547 const char *domain
= lp_workgroup(); /* FIXME */
548 bool modify_config
= lp_config_backend_is_registry();
549 enum netr_SchannelType sec_chan_type
;
551 if (c
->display_usage
) {
554 " Join a domain the new way\n");
558 mem_ctx
= talloc_init("net_rpc_join_newstyle");
563 werr
= libnet_init_JoinCtx(mem_ctx
, &r
);
564 if (!W_ERROR_IS_OK(werr
)) {
569 check what type of join - if the user want's to join as
570 a BDC, the server must agree that we are a BDC.
573 sec_chan_type
= get_sec_channel_type(argv
[0]);
575 sec_chan_type
= get_sec_channel_type(NULL
);
579 d_fprintf(stderr
, _("Could not initialise message context. "
580 "Try running as root\n"));
581 werr
= WERR_ACCESS_DENIED
;
585 r
->in
.msg_ctx
= c
->msg_ctx
;
586 r
->in
.domain_name
= domain
;
587 r
->in
.secure_channel_type
= sec_chan_type
;
588 r
->in
.dc_name
= c
->opt_host
;
589 r
->in
.admin_account
= c
->opt_user_name
;
590 r
->in
.admin_password
= net_prompt_pass(c
, c
->opt_user_name
);
592 r
->in
.use_kerberos
= c
->opt_kerberos
;
593 r
->in
.modify_config
= modify_config
;
594 r
->in
.join_flags
= WKSSVC_JOIN_FLAGS_JOIN_TYPE
|
595 WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE
|
596 WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED
;
598 werr
= libnet_Join(mem_ctx
, r
);
599 if (!W_ERROR_IS_OK(werr
)) {
603 /* Check the short name of the domain */
605 if (!modify_config
&& !strequal(lp_workgroup(), r
->out
.netbios_domain_name
)) {
606 d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
607 d_printf("domain name obtained from the server.\n");
608 d_printf("Using the name [%s] from the server.\n", r
->out
.netbios_domain_name
);
609 d_printf("You should set \"workgroup = %s\" in %s.\n",
610 r
->out
.netbios_domain_name
, get_dyn_CONFIGFILE());
613 d_printf("Using short domain name -- %s\n", r
->out
.netbios_domain_name
);
615 if (r
->out
.dns_domain_name
) {
616 d_printf("Joined '%s' to realm '%s'\n", r
->in
.machine_name
,
617 r
->out
.dns_domain_name
);
619 d_printf("Joined '%s' to domain '%s'\n", r
->in
.machine_name
,
620 r
->out
.netbios_domain_name
);
623 /* print out informative error string in case there is one */
624 if (r
->out
.error_string
!= NULL
) {
625 d_printf("%s\n", r
->out
.error_string
);
628 TALLOC_FREE(mem_ctx
);
633 /* issue an overall failure message at the end. */
634 d_printf("Failed to join domain: %s\n",
635 r
&& r
->out
.error_string
? r
->out
.error_string
:
636 get_friendly_werror_msg(werr
));
638 TALLOC_FREE(mem_ctx
);
644 * 'net rpc join' entrypoint.
645 * @param argc Standard main() style argc.
646 * @param argv Standard main() style argv. Initial components are already
649 * Main 'net_rpc_join()' (where the admin username/password is used) is
651 * Try to just change the password, but if that doesn't work, use/prompt
652 * for a username/password.
655 int net_rpc_join(struct net_context
*c
, int argc
, const char **argv
)
659 if (c
->display_usage
) {
662 _("net rpc join -U <username>[%%password] <type>\n"
664 " username\tName of the admin user"
665 " password\tPassword of the admin user, will "
666 "prompt if not specified\n"
667 " type\tCan be one of the following:\n"
668 "\t\tMEMBER\tJoin as member server (default)\n"
669 "\t\tBDC\tJoin as BDC\n"
670 "\t\tPDC\tJoin as PDC\n"));
674 if (lp_server_role() == ROLE_STANDALONE
) {
675 d_printf(_("cannot join as standalone machine\n"));
679 if (strlen(lp_netbios_name()) > 15) {
680 d_printf(_("Our netbios name can be at most 15 chars long, "
681 "\"%s\" is %u chars long\n"),
682 lp_netbios_name(), (unsigned int)strlen(lp_netbios_name()));
686 c
->opt_flags
|= NET_FLAGS_EXPECT_FALLBACK
;
687 ret
= net_rpc_oldjoin(c
, argc
, argv
);
688 c
->opt_flags
&= ~NET_FLAGS_EXPECT_FALLBACK
;
693 return net_rpc_join_newstyle(c
, argc
, argv
);
697 * display info about a rpc domain
699 * All parameters are provided by the run_rpc_command function, except for
700 * argc, argv which are passed through.
702 * @param domain_sid The domain sid acquired from the remote server
703 * @param cli A cli_state connected to the server.
704 * @param mem_ctx Talloc context, destroyed on completion of the function.
705 * @param argc Standard main() style argc.
706 * @param argv Standard main() style argv. Initial components are already
709 * @return Normal NTSTATUS return.
712 NTSTATUS
rpc_info_internals(struct net_context
*c
,
713 const struct dom_sid
*domain_sid
,
714 const char *domain_name
,
715 struct cli_state
*cli
,
716 struct rpc_pipe_client
*pipe_hnd
,
721 struct policy_handle connect_pol
, domain_pol
;
722 NTSTATUS status
, result
;
723 union samr_DomainInfo
*info
= NULL
;
725 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
727 sid_to_fstring(sid_str
, domain_sid
);
729 /* Get sam policy handle */
730 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
732 MAXIMUM_ALLOWED_ACCESS
,
735 if (!NT_STATUS_IS_OK(status
)) {
736 d_fprintf(stderr
, _("Could not connect to SAM: %s\n"),
741 if (!NT_STATUS_IS_OK(result
)) {
743 d_fprintf(stderr
, _("Could not connect to SAM: %s\n"),
748 /* Get domain policy handle */
749 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
751 MAXIMUM_ALLOWED_ACCESS
,
752 discard_const_p(struct dom_sid2
, domain_sid
),
755 if (!NT_STATUS_IS_OK(status
)) {
756 d_fprintf(stderr
, _("Could not open domain: %s\n"),
760 if (!NT_STATUS_IS_OK(result
)) {
762 d_fprintf(stderr
, _("Could not open domain: %s\n"),
767 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
772 if (!NT_STATUS_IS_OK(status
)) {
776 if (NT_STATUS_IS_OK(result
)) {
777 d_printf(_("Domain Name: %s\n"),
778 info
->general
.domain_name
.string
);
779 d_printf(_("Domain SID: %s\n"), sid_str
);
780 d_printf(_("Sequence number: %llu\n"),
781 (unsigned long long)info
->general
.sequence_num
);
782 d_printf(_("Num users: %u\n"), info
->general
.num_users
);
783 d_printf(_("Num domain groups: %u\n"),info
->general
.num_groups
);
784 d_printf(_("Num local groups: %u\n"),info
->general
.num_aliases
);
792 * 'net rpc info' entrypoint.
793 * @param argc Standard main() style argc.
794 * @param argv Standard main() style argv. Initial components are already
798 int net_rpc_info(struct net_context
*c
, int argc
, const char **argv
)
800 if (c
->display_usage
) {
805 _("Display information about the domain"));
809 return run_rpc_command(c
, NULL
, &ndr_table_samr
,
810 NET_FLAGS_PDC
, rpc_info_internals
,
815 * Fetch domain SID into the local secrets.tdb.
817 * All parameters are provided by the run_rpc_command function, except for
818 * argc, argv which are passed through.
820 * @param domain_sid The domain sid acquired from the remote server.
821 * @param cli A cli_state connected to the server.
822 * @param mem_ctx Talloc context, destroyed on completion of the function.
823 * @param argc Standard main() style argc.
824 * @param argv Standard main() style argv. Initial components are already
827 * @return Normal NTSTATUS return.
830 static NTSTATUS
rpc_getsid_internals(struct net_context
*c
,
831 const struct dom_sid
*domain_sid
,
832 const char *domain_name
,
833 struct cli_state
*cli
,
834 struct rpc_pipe_client
*pipe_hnd
,
841 sid_to_fstring(sid_str
, domain_sid
);
842 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
843 sid_str
, domain_name
);
845 if (!secrets_store_domain_sid(domain_name
, domain_sid
)) {
846 DEBUG(0,("Can't store domain SID\n"));
847 return NT_STATUS_UNSUCCESSFUL
;
854 * 'net rpc getsid' entrypoint.
855 * @param argc Standard main() style argc.
856 * @param argv Standard main() style argv. Initial components are already
860 int net_rpc_getsid(struct net_context
*c
, int argc
, const char **argv
)
862 int conn_flags
= NET_FLAGS_PDC
;
864 if (!c
->opt_user_specified
) {
865 conn_flags
|= NET_FLAGS_ANONYMOUS
;
868 if (c
->display_usage
) {
873 _("Fetch domain SID into local secrets.tdb"));
877 return run_rpc_command(c
, NULL
, &ndr_table_samr
,
879 rpc_getsid_internals
,
883 /****************************************************************************/
886 * Basic usage function for 'net rpc user'.
887 * @param argc Standard main() style argc.
888 * @param argv Standard main() style argv. Initial components are already
892 static int rpc_user_usage(struct net_context
*c
, int argc
, const char **argv
)
894 return net_user_usage(c
, argc
, argv
);
898 * Add a new user to a remote RPC server.
900 * @param argc Standard main() style argc.
901 * @param argv Standard main() style argv. Initial components are already
904 * @return A shell status integer (0 for success).
907 static int rpc_user_add(struct net_context
*c
, int argc
, const char **argv
)
909 NET_API_STATUS status
;
910 struct USER_INFO_1 info1
;
911 uint32_t parm_error
= 0;
913 if (argc
< 1 || c
->display_usage
) {
914 rpc_user_usage(c
, argc
, argv
);
920 info1
.usri1_name
= argv
[0];
922 info1
.usri1_password
= argv
[1];
925 status
= NetUserAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
928 d_fprintf(stderr
,_("Failed to add user '%s' with error: %s.\n"),
929 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
933 d_printf(_("Added user '%s'.\n"), argv
[0]);
940 * Rename a user on a remote RPC server.
942 * @param argc Standard main() style argc.
943 * @param argv Standard main() style argv. Initial components are already
946 * @return A shell status integer (0 for success).
949 static int rpc_user_rename(struct net_context
*c
, int argc
, const char **argv
)
951 NET_API_STATUS status
;
952 struct USER_INFO_0 u0
;
953 uint32_t parm_err
= 0;
955 if (argc
!= 2 || c
->display_usage
) {
956 rpc_user_usage(c
, argc
, argv
);
960 u0
.usri0_name
= argv
[1];
962 status
= NetUserSetInfo(c
->opt_host
, argv
[0],
963 0, (uint8_t *)&u0
, &parm_err
);
966 _("Failed to rename user from %s to %s - %s\n"),
968 libnetapi_get_error_string(c
->netapi_ctx
, status
));
970 d_printf(_("Renamed user from %s to %s\n"), argv
[0], argv
[1]);
977 * Set a user's primary group
979 * @param argc Standard main() style argc.
980 * @param argv Standard main() style argv. Initial components are already
983 * @return A shell status integer (0 for success).
986 static int rpc_user_setprimarygroup(struct net_context
*c
, int argc
,
989 NET_API_STATUS status
;
991 struct GROUP_INFO_2
*g2
;
992 struct USER_INFO_1051 u1051
;
993 uint32_t parm_err
= 0;
995 if (argc
!= 2 || c
->display_usage
) {
996 rpc_user_usage(c
, argc
, argv
);
1000 status
= NetGroupGetInfo(c
->opt_host
, argv
[1], 2, &buffer
);
1002 d_fprintf(stderr
, _("Failed to find group name %s -- %s\n"),
1004 libnetapi_get_error_string(c
->netapi_ctx
, status
));
1007 g2
= (struct GROUP_INFO_2
*)buffer
;
1009 u1051
.usri1051_primary_group_id
= g2
->grpi2_group_id
;
1011 NetApiBufferFree(buffer
);
1013 status
= NetUserSetInfo(c
->opt_host
, argv
[0], 1051,
1014 (uint8_t *)&u1051
, &parm_err
);
1017 _("Failed to set user's primary group %s to %s - "
1018 "%s\n"), argv
[0], argv
[1],
1019 libnetapi_get_error_string(c
->netapi_ctx
, status
));
1021 d_printf(_("Set primary group of user %s to %s\n"), argv
[0],
1028 * Delete a user from a remote RPC server.
1030 * @param argc Standard main() style argc.
1031 * @param argv Standard main() style argv. Initial components are already
1034 * @return A shell status integer (0 for success).
1037 static int rpc_user_delete(struct net_context
*c
, int argc
, const char **argv
)
1039 NET_API_STATUS status
;
1041 if (argc
< 1 || c
->display_usage
) {
1042 rpc_user_usage(c
, argc
, argv
);
1046 status
= NetUserDel(c
->opt_host
, argv
[0]);
1049 d_fprintf(stderr
, _("Failed to delete user '%s' with: %s.\n"),
1051 libnetapi_get_error_string(c
->netapi_ctx
, status
));
1054 d_printf(_("Deleted user '%s'.\n"), argv
[0]);
1061 * Set a user's password on a remote RPC server.
1063 * @param argc Standard main() style argc.
1064 * @param argv Standard main() style argv. Initial components are already
1067 * @return A shell status integer (0 for success).
1070 static int rpc_user_password(struct net_context
*c
, int argc
, const char **argv
)
1072 NET_API_STATUS status
;
1073 char *prompt
= NULL
;
1074 struct USER_INFO_1003 u1003
;
1075 uint32_t parm_err
= 0;
1078 if (argc
< 1 || c
->display_usage
) {
1079 rpc_user_usage(c
, argc
, argv
);
1084 u1003
.usri1003_password
= argv
[1];
1086 char pwd
[256] = {0};
1087 ret
= asprintf(&prompt
, _("Enter new password for %s:"),
1093 ret
= samba_getpass(prompt
, pwd
, sizeof(pwd
), false, false);
1099 u1003
.usri1003_password
= talloc_strdup(c
, pwd
);
1100 if (u1003
.usri1003_password
== NULL
) {
1105 status
= NetUserSetInfo(c
->opt_host
, argv
[0], 1003, (uint8_t *)&u1003
, &parm_err
);
1107 /* Display results */
1110 _("Failed to set password for '%s' with error: %s.\n"),
1111 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
1120 * List a user's groups from a remote RPC server.
1122 * @param argc Standard main() style argc.
1123 * @param argv Standard main() style argv. Initial components are already
1126 * @return A shell status integer (0 for success)
1129 static int rpc_user_info(struct net_context
*c
, int argc
, const char **argv
)
1132 NET_API_STATUS status
;
1133 struct GROUP_USERS_INFO_0
*u0
= NULL
;
1134 uint32_t entries_read
= 0;
1135 uint32_t total_entries
= 0;
1139 if (argc
< 1 || c
->display_usage
) {
1140 rpc_user_usage(c
, argc
, argv
);
1144 status
= NetUserGetGroups(c
->opt_host
,
1147 (uint8_t **)(void *)&u0
,
1153 _("Failed to get groups for '%s' with error: %s.\n"),
1154 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
1159 for (i
=0; i
< entries_read
; i
++) {
1160 printf("%s\n", u0
->grui0_name
);
1168 * List users on a remote RPC server.
1170 * All parameters are provided by the run_rpc_command function, except for
1171 * argc, argv which are passed through.
1173 * @param domain_sid The domain sid acquired from the remote server.
1174 * @param cli A cli_state connected to the server.
1175 * @param mem_ctx Talloc context, destroyed on completion of the function.
1176 * @param argc Standard main() style argc.
1177 * @param argv Standard main() style argv. Initial components are already
1180 * @return Normal NTSTATUS return.
1183 static int rpc_user_list(struct net_context
*c
, int argc
, const char **argv
)
1185 NET_API_STATUS status
;
1186 uint32_t start_idx
=0, num_entries
, i
, loop_count
= 0;
1187 struct NET_DISPLAY_USER
*info
= NULL
;
1188 void *buffer
= NULL
;
1190 /* Query domain users */
1191 if (c
->opt_long_list_entries
)
1192 d_printf(_("\nUser name Comment"
1193 "\n-----------------------------\n"));
1195 uint32_t max_entries
, max_size
;
1197 dcerpc_get_query_dispinfo_params(
1198 loop_count
, &max_entries
, &max_size
);
1200 status
= NetQueryDisplayInformation(c
->opt_host
,
1207 if (status
!= 0 && status
!= ERROR_MORE_DATA
) {
1211 info
= (struct NET_DISPLAY_USER
*)buffer
;
1213 for (i
= 0; i
< num_entries
; i
++) {
1215 if (c
->opt_long_list_entries
)
1216 printf("%-21.21s %s\n", info
->usri1_name
,
1217 info
->usri1_comment
);
1219 printf("%s\n", info
->usri1_name
);
1223 NetApiBufferFree(buffer
);
1226 start_idx
+= num_entries
;
1228 } while (status
== ERROR_MORE_DATA
);
1234 * 'net rpc user' entrypoint.
1235 * @param argc Standard main() style argc.
1236 * @param argv Standard main() style argv. Initial components are already
1240 int net_rpc_user(struct net_context
*c
, int argc
, const char **argv
)
1242 NET_API_STATUS status
;
1244 struct functable func
[] = {
1249 N_("Add specified user"),
1250 N_("net rpc user add\n"
1251 " Add specified user")
1257 N_("List domain groups of user"),
1258 N_("net rpc user info\n"
1259 " List domain groups of user")
1265 N_("Remove specified user"),
1266 N_("net rpc user delete\n"
1267 " Remove specified user")
1273 N_("Change user password"),
1274 N_("net rpc user password\n"
1275 " Change user password")
1281 N_("Rename specified user"),
1282 N_("net rpc user rename\n"
1283 " Rename specified user")
1287 rpc_user_setprimarygroup
,
1289 "Set a user's primary group",
1290 "net rpc user setprimarygroup\n"
1291 " Set a user's primary group"
1293 {NULL
, NULL
, 0, NULL
, NULL
}
1296 status
= libnetapi_net_init(&c
->netapi_ctx
);
1300 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
1301 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
1302 if (c
->opt_kerberos
) {
1303 libnetapi_set_use_kerberos(c
->netapi_ctx
);
1307 if (c
->display_usage
) {
1312 _("List all users"));
1313 net_display_usage_from_functable(func
);
1317 return rpc_user_list(c
, argc
, argv
);
1320 return net_run_function(c
, argc
, argv
, "net rpc user", func
);
1323 static NTSTATUS
rpc_sh_user_list(struct net_context
*c
,
1324 TALLOC_CTX
*mem_ctx
,
1325 struct rpc_sh_ctx
*ctx
,
1326 struct rpc_pipe_client
*pipe_hnd
,
1327 int argc
, const char **argv
)
1329 return werror_to_ntstatus(W_ERROR(rpc_user_list(c
, argc
, argv
)));
1332 static NTSTATUS
rpc_sh_user_info(struct net_context
*c
,
1333 TALLOC_CTX
*mem_ctx
,
1334 struct rpc_sh_ctx
*ctx
,
1335 struct rpc_pipe_client
*pipe_hnd
,
1336 int argc
, const char **argv
)
1338 return werror_to_ntstatus(W_ERROR(rpc_user_info(c
, argc
, argv
)));
1341 static NTSTATUS
rpc_sh_handle_user(struct net_context
*c
,
1342 TALLOC_CTX
*mem_ctx
,
1343 struct rpc_sh_ctx
*ctx
,
1344 struct rpc_pipe_client
*pipe_hnd
,
1345 int argc
, const char **argv
,
1347 struct net_context
*c
,
1348 TALLOC_CTX
*mem_ctx
,
1349 struct rpc_sh_ctx
*ctx
,
1350 struct rpc_pipe_client
*pipe_hnd
,
1351 struct policy_handle
*user_hnd
,
1352 int argc
, const char **argv
))
1354 struct policy_handle connect_pol
, domain_pol
, user_pol
;
1355 NTSTATUS status
, result
;
1358 enum lsa_SidType type
;
1359 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1362 d_fprintf(stderr
, "%s %s <username>\n", _("Usage:"),
1364 return NT_STATUS_INVALID_PARAMETER
;
1367 ZERO_STRUCT(connect_pol
);
1368 ZERO_STRUCT(domain_pol
);
1369 ZERO_STRUCT(user_pol
);
1371 status
= net_rpc_lookup_name(c
, mem_ctx
, ctx
->cli
,
1372 argv
[0], NULL
, NULL
, &sid
, &type
);
1373 if (!NT_STATUS_IS_OK(status
)) {
1374 d_fprintf(stderr
, _("Could not lookup %s: %s\n"), argv
[0],
1379 if (type
!= SID_NAME_USER
) {
1380 d_fprintf(stderr
, _("%s is a %s, not a user\n"), argv
[0],
1381 sid_type_lookup(type
));
1382 status
= NT_STATUS_NO_SUCH_USER
;
1386 if (!sid_peek_check_rid(ctx
->domain_sid
, &sid
, &rid
)) {
1387 d_fprintf(stderr
, _("%s is not in our domain\n"), argv
[0]);
1388 status
= NT_STATUS_NO_SUCH_USER
;
1392 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
1394 MAXIMUM_ALLOWED_ACCESS
,
1397 if (!NT_STATUS_IS_OK(status
)) {
1400 if (!NT_STATUS_IS_OK(result
)) {
1405 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
1407 MAXIMUM_ALLOWED_ACCESS
,
1411 if (!NT_STATUS_IS_OK(status
)) {
1414 if (!NT_STATUS_IS_OK(result
)) {
1419 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
1421 MAXIMUM_ALLOWED_ACCESS
,
1425 if (!NT_STATUS_IS_OK(status
)) {
1428 if (!NT_STATUS_IS_OK(result
)) {
1433 status
= fn(c
, mem_ctx
, ctx
, pipe_hnd
, &user_pol
, argc
-1, argv
+1);
1436 if (is_valid_policy_hnd(&user_pol
)) {
1437 dcerpc_samr_Close(b
, mem_ctx
, &user_pol
, &result
);
1439 if (is_valid_policy_hnd(&domain_pol
)) {
1440 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
1442 if (is_valid_policy_hnd(&connect_pol
)) {
1443 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
1448 static NTSTATUS
rpc_sh_user_show_internals(struct net_context
*c
,
1449 TALLOC_CTX
*mem_ctx
,
1450 struct rpc_sh_ctx
*ctx
,
1451 struct rpc_pipe_client
*pipe_hnd
,
1452 struct policy_handle
*user_hnd
,
1453 int argc
, const char **argv
)
1455 NTSTATUS status
, result
;
1456 union samr_UserInfo
*info
= NULL
;
1457 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1460 d_fprintf(stderr
, "%s %s show <username>\n", _("Usage:"),
1462 return NT_STATUS_INVALID_PARAMETER
;
1465 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1470 if (!NT_STATUS_IS_OK(status
)) {
1473 if (!NT_STATUS_IS_OK(result
)) {
1477 d_printf(_("user rid: %d, group rid: %d\n"),
1479 info
->info21
.primary_gid
);
1484 static NTSTATUS
rpc_sh_user_show(struct net_context
*c
,
1485 TALLOC_CTX
*mem_ctx
,
1486 struct rpc_sh_ctx
*ctx
,
1487 struct rpc_pipe_client
*pipe_hnd
,
1488 int argc
, const char **argv
)
1490 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1491 rpc_sh_user_show_internals
);
1494 #define FETCHSTR(name, rec) \
1495 do { if (strequal(ctx->thiscmd, name)) { \
1496 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1499 #define SETSTR(name, rec, flag) \
1500 do { if (strequal(ctx->thiscmd, name)) { \
1501 init_lsa_String(&(info->info21.rec), argv[0]); \
1502 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1505 static NTSTATUS
rpc_sh_user_str_edit_internals(struct net_context
*c
,
1506 TALLOC_CTX
*mem_ctx
,
1507 struct rpc_sh_ctx
*ctx
,
1508 struct rpc_pipe_client
*pipe_hnd
,
1509 struct policy_handle
*user_hnd
,
1510 int argc
, const char **argv
)
1512 NTSTATUS status
, result
;
1513 const char *username
;
1514 const char *oldval
= "";
1515 union samr_UserInfo
*info
= NULL
;
1516 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1519 d_fprintf(stderr
, "%s %s <username> [new value|NULL]\n",
1520 _("Usage:"), ctx
->whoami
);
1521 return NT_STATUS_INVALID_PARAMETER
;
1524 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1529 if (!NT_STATUS_IS_OK(status
)) {
1532 if (!NT_STATUS_IS_OK(result
)) {
1536 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1538 FETCHSTR("fullname", full_name
);
1539 FETCHSTR("homedir", home_directory
);
1540 FETCHSTR("homedrive", home_drive
);
1541 FETCHSTR("logonscript", logon_script
);
1542 FETCHSTR("profilepath", profile_path
);
1543 FETCHSTR("description", description
);
1546 d_printf(_("%s's %s: [%s]\n"), username
, ctx
->thiscmd
, oldval
);
1550 if (strcmp(argv
[0], "NULL") == 0) {
1554 ZERO_STRUCT(info
->info21
);
1556 SETSTR("fullname", full_name
, FULL_NAME
);
1557 SETSTR("homedir", home_directory
, HOME_DIRECTORY
);
1558 SETSTR("homedrive", home_drive
, HOME_DRIVE
);
1559 SETSTR("logonscript", logon_script
, LOGON_SCRIPT
);
1560 SETSTR("profilepath", profile_path
, PROFILE_PATH
);
1561 SETSTR("description", description
, DESCRIPTION
);
1563 status
= dcerpc_samr_SetUserInfo(b
, mem_ctx
,
1568 if (!NT_STATUS_IS_OK(status
)) {
1574 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username
,
1575 ctx
->thiscmd
, oldval
, argv
[0]);
1582 #define HANDLEFLG(name, rec) \
1583 do { if (strequal(ctx->thiscmd, name)) { \
1584 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1586 newflags = oldflags | ACB_##rec; \
1588 newflags = oldflags & ~ACB_##rec; \
1591 static NTSTATUS
rpc_sh_user_str_edit(struct net_context
*c
,
1592 TALLOC_CTX
*mem_ctx
,
1593 struct rpc_sh_ctx
*ctx
,
1594 struct rpc_pipe_client
*pipe_hnd
,
1595 int argc
, const char **argv
)
1597 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1598 rpc_sh_user_str_edit_internals
);
1601 static NTSTATUS
rpc_sh_user_flag_edit_internals(struct net_context
*c
,
1602 TALLOC_CTX
*mem_ctx
,
1603 struct rpc_sh_ctx
*ctx
,
1604 struct rpc_pipe_client
*pipe_hnd
,
1605 struct policy_handle
*user_hnd
,
1606 int argc
, const char **argv
)
1608 NTSTATUS status
, result
;
1609 const char *username
;
1610 const char *oldval
= "unknown";
1611 uint32_t oldflags
, newflags
;
1613 union samr_UserInfo
*info
= NULL
;
1614 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1617 ((argc
== 1) && !strequal(argv
[0], "yes") &&
1618 !strequal(argv
[0], "no"))) {
1619 /* TRANSATORS: The yes|no here are program keywords. Please do
1621 d_fprintf(stderr
, _("Usage: %s <username> [yes|no]\n"),
1623 return NT_STATUS_INVALID_PARAMETER
;
1626 newval
= strequal(argv
[0], "yes");
1628 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1633 if (!NT_STATUS_IS_OK(status
)) {
1636 if (!NT_STATUS_IS_OK(result
)) {
1640 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1641 oldflags
= info
->info21
.acct_flags
;
1642 newflags
= info
->info21
.acct_flags
;
1644 HANDLEFLG("disabled", DISABLED
);
1645 HANDLEFLG("pwnotreq", PWNOTREQ
);
1646 HANDLEFLG("autolock", AUTOLOCK
);
1647 HANDLEFLG("pwnoexp", PWNOEXP
);
1650 d_printf(_("%s's %s flag: %s\n"), username
, ctx
->thiscmd
,
1655 ZERO_STRUCT(info
->info21
);
1657 info
->info21
.acct_flags
= newflags
;
1658 info
->info21
.fields_present
= SAMR_FIELD_ACCT_FLAGS
;
1660 status
= dcerpc_samr_SetUserInfo(b
, mem_ctx
,
1665 if (!NT_STATUS_IS_OK(status
)) {
1669 if (NT_STATUS_IS_OK(result
)) {
1670 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username
,
1671 ctx
->thiscmd
, oldval
, argv
[0]);
1679 static NTSTATUS
rpc_sh_user_flag_edit(struct net_context
*c
,
1680 TALLOC_CTX
*mem_ctx
,
1681 struct rpc_sh_ctx
*ctx
,
1682 struct rpc_pipe_client
*pipe_hnd
,
1683 int argc
, const char **argv
)
1685 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1686 rpc_sh_user_flag_edit_internals
);
1689 struct rpc_sh_cmd
*net_rpc_user_edit_cmds(struct net_context
*c
,
1690 TALLOC_CTX
*mem_ctx
,
1691 struct rpc_sh_ctx
*ctx
)
1693 static struct rpc_sh_cmd cmds
[] = {
1695 { "fullname", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1696 N_("Show/Set a user's full name") },
1698 { "homedir", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1699 N_("Show/Set a user's home directory") },
1701 { "homedrive", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1702 N_("Show/Set a user's home drive") },
1704 { "logonscript", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1705 N_("Show/Set a user's logon script") },
1707 { "profilepath", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1708 N_("Show/Set a user's profile path") },
1710 { "description", NULL
, &ndr_table_samr
, rpc_sh_user_str_edit
,
1711 N_("Show/Set a user's description") },
1713 { "disabled", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1714 N_("Show/Set whether a user is disabled") },
1716 { "autolock", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1717 N_("Show/Set whether a user locked out") },
1719 { "pwnotreq", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1720 N_("Show/Set whether a user does not need a password") },
1722 { "pwnoexp", NULL
, &ndr_table_samr
, rpc_sh_user_flag_edit
,
1723 N_("Show/Set whether a user's password does not expire") },
1725 { NULL
, NULL
, 0, NULL
, NULL
}
1731 struct rpc_sh_cmd
*net_rpc_user_cmds(struct net_context
*c
,
1732 TALLOC_CTX
*mem_ctx
,
1733 struct rpc_sh_ctx
*ctx
)
1735 static struct rpc_sh_cmd cmds
[] = {
1737 { "list", NULL
, &ndr_table_samr
, rpc_sh_user_list
,
1738 N_("List available users") },
1740 { "info", NULL
, &ndr_table_samr
, rpc_sh_user_info
,
1741 N_("List the domain groups a user is member of") },
1743 { "show", NULL
, &ndr_table_samr
, rpc_sh_user_show
,
1744 N_("Show info about a user") },
1746 { "edit", net_rpc_user_edit_cmds
, 0, NULL
,
1747 N_("Show/Modify a user's fields") },
1749 { NULL
, NULL
, 0, NULL
, NULL
}
1755 /****************************************************************************/
1758 * Basic usage function for 'net rpc group'.
1759 * @param argc Standard main() style argc.
1760 * @param argv Standard main() style argv. Initial components are already
1764 static int rpc_group_usage(struct net_context
*c
, int argc
, const char **argv
)
1766 return net_group_usage(c
, argc
, argv
);
1770 * Delete group on a remote RPC server.
1772 * All parameters are provided by the run_rpc_command function, except for
1773 * argc, argv which are passed through.
1775 * @param domain_sid The domain sid acquired from the remote server.
1776 * @param cli A cli_state connected to the server.
1777 * @param mem_ctx Talloc context, destroyed on completion of the function.
1778 * @param argc Standard main() style argc.
1779 * @param argv Standard main() style argv. Initial components are already
1782 * @return Normal NTSTATUS return.
1785 static NTSTATUS
rpc_group_delete_internals(struct net_context
*c
,
1786 const struct dom_sid
*domain_sid
,
1787 const char *domain_name
,
1788 struct cli_state
*cli
,
1789 struct rpc_pipe_client
*pipe_hnd
,
1790 TALLOC_CTX
*mem_ctx
,
1794 struct policy_handle connect_pol
, domain_pol
, group_pol
, user_pol
;
1795 bool group_is_primary
= false;
1796 NTSTATUS status
, result
;
1798 struct samr_RidAttrArray
*rids
= NULL
;
1801 /* struct samr_RidWithAttribute *user_gids; */
1802 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
1804 struct samr_Ids group_rids
, name_types
;
1805 struct lsa_String lsa_acct_name
;
1806 union samr_UserInfo
*info
= NULL
;
1808 if (argc
< 1 || c
->display_usage
) {
1809 rpc_group_usage(c
, argc
,argv
);
1810 return NT_STATUS_OK
; /* ok? */
1813 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
1815 MAXIMUM_ALLOWED_ACCESS
,
1818 if (!NT_STATUS_IS_OK(status
)) {
1819 d_fprintf(stderr
, _("Request samr_Connect2 failed\n"));
1823 if (!NT_STATUS_IS_OK(result
)) {
1825 d_fprintf(stderr
, _("Request samr_Connect2 failed\n"));
1829 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
1831 MAXIMUM_ALLOWED_ACCESS
,
1832 discard_const_p(struct dom_sid2
, domain_sid
),
1835 if (!NT_STATUS_IS_OK(status
)) {
1836 d_fprintf(stderr
, _("Request open_domain failed\n"));
1840 if (!NT_STATUS_IS_OK(result
)) {
1842 d_fprintf(stderr
, _("Request open_domain failed\n"));
1846 init_lsa_String(&lsa_acct_name
, argv
[0]);
1848 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
1855 if (!NT_STATUS_IS_OK(status
)) {
1856 d_fprintf(stderr
, _("Lookup of '%s' failed\n"),argv
[0]);
1860 if (!NT_STATUS_IS_OK(result
)) {
1862 d_fprintf(stderr
, _("Lookup of '%s' failed\n"),argv
[0]);
1865 if (group_rids
.count
!= 1) {
1866 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
1869 if (name_types
.count
!= 1) {
1870 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
1874 switch (name_types
.ids
[0])
1876 case SID_NAME_DOM_GRP
:
1877 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
1879 MAXIMUM_ALLOWED_ACCESS
,
1883 if (!NT_STATUS_IS_OK(status
)) {
1884 d_fprintf(stderr
, _("Request open_group failed"));
1888 if (!NT_STATUS_IS_OK(result
)) {
1890 d_fprintf(stderr
, _("Request open_group failed"));
1894 group_rid
= group_rids
.ids
[0];
1896 status
= dcerpc_samr_QueryGroupMember(b
, mem_ctx
,
1900 if (!NT_STATUS_IS_OK(status
)) {
1902 _("Unable to query group members of %s"),
1907 if (!NT_STATUS_IS_OK(result
)) {
1910 _("Unable to query group members of %s"),
1915 if (c
->opt_verbose
) {
1917 _("Domain Group %s (rid: %d) has %d members\n"),
1918 argv
[0],group_rid
, rids
->count
);
1921 /* Check if group is anyone's primary group */
1922 for (i
= 0; i
< rids
->count
; i
++)
1924 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
1926 MAXIMUM_ALLOWED_ACCESS
,
1930 if (!NT_STATUS_IS_OK(status
)) {
1932 _("Unable to open group member %d\n"),
1937 if (!NT_STATUS_IS_OK(result
)) {
1940 _("Unable to open group member %d\n"),
1945 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
1950 if (!NT_STATUS_IS_OK(status
)) {
1952 _("Unable to lookup userinfo for group "
1958 if (!NT_STATUS_IS_OK(result
)) {
1961 _("Unable to lookup userinfo for group "
1967 if (info
->info21
.primary_gid
== group_rid
) {
1968 if (c
->opt_verbose
) {
1969 d_printf(_("Group is primary group "
1971 info
->info21
.account_name
.string
);
1973 group_is_primary
= true;
1976 dcerpc_samr_Close(b
, mem_ctx
, &user_pol
, &result
);
1979 if (group_is_primary
) {
1980 d_fprintf(stderr
, _("Unable to delete group because "
1981 "some of it's members have it as primary "
1983 status
= NT_STATUS_MEMBERS_PRIMARY_GROUP
;
1987 /* remove all group members */
1988 for (i
= 0; i
< rids
->count
; i
++)
1991 d_printf(_("Remove group member %d..."),
1993 status
= dcerpc_samr_DeleteGroupMember(b
, mem_ctx
,
1997 if (!NT_STATUS_IS_OK(status
)) {
2001 if (NT_STATUS_IS_OK(result
)) {
2003 d_printf(_("ok\n"));
2006 d_printf("%s\n", _("failed"));
2011 status
= dcerpc_samr_DeleteDomainGroup(b
, mem_ctx
,
2014 if (!NT_STATUS_IS_OK(status
)) {
2021 /* removing a local group is easier... */
2022 case SID_NAME_ALIAS
:
2023 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2025 MAXIMUM_ALLOWED_ACCESS
,
2029 if (!NT_STATUS_IS_OK(status
)) {
2030 d_fprintf(stderr
, _("Request open_alias failed\n"));
2033 if (!NT_STATUS_IS_OK(result
)) {
2035 d_fprintf(stderr
, _("Request open_alias failed\n"));
2039 status
= dcerpc_samr_DeleteDomAlias(b
, mem_ctx
,
2042 if (!NT_STATUS_IS_OK(status
)) {
2050 d_fprintf(stderr
, _("%s is of type %s. This command is only "
2051 "for deleting local or global groups\n"),
2052 argv
[0],sid_type_lookup(name_types
.ids
[0]));
2053 status
= NT_STATUS_UNSUCCESSFUL
;
2057 if (NT_STATUS_IS_OK(status
)) {
2059 d_printf(_("Deleted %s '%s'\n"),
2060 sid_type_lookup(name_types
.ids
[0]), argv
[0]);
2062 d_fprintf(stderr
, _("Deleting of %s failed: %s\n"), argv
[0],
2063 get_friendly_nt_error_msg(status
));
2071 static int rpc_group_delete(struct net_context
*c
, int argc
, const char **argv
)
2073 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2074 rpc_group_delete_internals
, argc
,argv
);
2077 static int rpc_group_add_internals(struct net_context
*c
, int argc
, const char **argv
)
2079 NET_API_STATUS status
;
2080 struct GROUP_INFO_1 info1
;
2081 uint32_t parm_error
= 0;
2083 if (argc
!= 1 || c
->display_usage
) {
2084 rpc_group_usage(c
, argc
, argv
);
2090 info1
.grpi1_name
= argv
[0];
2091 if (c
->opt_comment
&& strlen(c
->opt_comment
) > 0) {
2092 info1
.grpi1_comment
= c
->opt_comment
;
2095 status
= NetGroupAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
2099 _("Failed to add group '%s' with error: %s.\n"),
2100 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
2104 d_printf(_("Added group '%s'.\n"), argv
[0]);
2110 static int rpc_alias_add_internals(struct net_context
*c
, int argc
, const char **argv
)
2112 NET_API_STATUS status
;
2113 struct LOCALGROUP_INFO_1 info1
;
2114 uint32_t parm_error
= 0;
2116 if (argc
!= 1 || c
->display_usage
) {
2117 rpc_group_usage(c
, argc
, argv
);
2123 info1
.lgrpi1_name
= argv
[0];
2124 if (c
->opt_comment
&& strlen(c
->opt_comment
) > 0) {
2125 info1
.lgrpi1_comment
= c
->opt_comment
;
2128 status
= NetLocalGroupAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
2132 _("Failed to add alias '%s' with error: %s.\n"),
2133 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
2137 d_printf(_("Added alias '%s'.\n"), argv
[0]);
2143 static int rpc_group_add(struct net_context
*c
, int argc
, const char **argv
)
2145 if (c
->opt_localgroup
)
2146 return rpc_alias_add_internals(c
, argc
, argv
);
2148 return rpc_group_add_internals(c
, argc
, argv
);
2151 static NTSTATUS
get_sid_from_name(struct cli_state
*cli
,
2152 TALLOC_CTX
*mem_ctx
,
2154 struct dom_sid
*sid
,
2155 enum lsa_SidType
*type
)
2157 struct dom_sid
*sids
= NULL
;
2158 enum lsa_SidType
*types
= NULL
;
2159 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2160 struct policy_handle lsa_pol
;
2161 NTSTATUS status
, result
;
2162 struct dcerpc_binding_handle
*b
;
2164 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
2166 if (!NT_STATUS_IS_OK(status
)) {
2170 b
= pipe_hnd
->binding_handle
;
2172 status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, false,
2173 SEC_FLAG_MAXIMUM_ALLOWED
, &lsa_pol
);
2175 if (!NT_STATUS_IS_OK(status
)) {
2179 status
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
2180 &name
, NULL
, 1, &sids
, &types
);
2182 if (NT_STATUS_IS_OK(status
)) {
2183 sid_copy(sid
, &sids
[0]);
2187 dcerpc_lsa_Close(b
, mem_ctx
, &lsa_pol
, &result
);
2191 TALLOC_FREE(pipe_hnd
);
2194 if (!NT_STATUS_IS_OK(status
) && (strncasecmp_m(name
, "S-", 2) == 0)) {
2196 /* Try as S-1-5-whatever */
2198 struct dom_sid tmp_sid
;
2200 if (string_to_sid(&tmp_sid
, name
)) {
2201 sid_copy(sid
, &tmp_sid
);
2202 *type
= SID_NAME_UNKNOWN
;
2203 status
= NT_STATUS_OK
;
2210 static NTSTATUS
rpc_add_groupmem(struct rpc_pipe_client
*pipe_hnd
,
2211 TALLOC_CTX
*mem_ctx
,
2212 const struct dom_sid
*group_sid
,
2215 struct policy_handle connect_pol
, domain_pol
;
2216 NTSTATUS status
, result
;
2218 struct policy_handle group_pol
;
2219 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2221 struct samr_Ids rids
, rid_types
;
2222 struct lsa_String lsa_acct_name
;
2226 sid_copy(&sid
, group_sid
);
2228 if (!sid_split_rid(&sid
, &group_rid
)) {
2229 return NT_STATUS_UNSUCCESSFUL
;
2232 /* Get sam policy handle */
2233 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2235 MAXIMUM_ALLOWED_ACCESS
,
2238 if (!NT_STATUS_IS_OK(status
)) {
2241 if (!NT_STATUS_IS_OK(result
)) {
2245 /* Get domain policy handle */
2246 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2248 MAXIMUM_ALLOWED_ACCESS
,
2252 if (!NT_STATUS_IS_OK(status
)) {
2255 if (!NT_STATUS_IS_OK(result
)) {
2259 init_lsa_String(&lsa_acct_name
, member
);
2261 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
2268 if (!NT_STATUS_IS_OK(status
)) {
2269 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2274 if (!NT_STATUS_IS_OK(result
)) {
2276 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2280 if (rids
.count
!= 1) {
2281 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2284 if (rid_types
.count
!= 1) {
2285 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2289 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
2291 MAXIMUM_ALLOWED_ACCESS
,
2295 if (!NT_STATUS_IS_OK(status
)) {
2299 if (!NT_STATUS_IS_OK(result
)) {
2304 status
= dcerpc_samr_AddGroupMember(b
, mem_ctx
,
2307 0x0005, /* unknown flags */
2309 if (!NT_STATUS_IS_OK(status
)) {
2316 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2320 static NTSTATUS
rpc_add_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2321 struct cli_state
*cli
,
2322 TALLOC_CTX
*mem_ctx
,
2323 const struct dom_sid
*alias_sid
,
2326 struct policy_handle connect_pol
, domain_pol
;
2327 NTSTATUS status
, result
;
2329 struct policy_handle alias_pol
;
2330 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2332 struct dom_sid member_sid
;
2333 enum lsa_SidType member_type
;
2337 sid_copy(&sid
, alias_sid
);
2339 if (!sid_split_rid(&sid
, &alias_rid
)) {
2340 return NT_STATUS_UNSUCCESSFUL
;
2343 result
= get_sid_from_name(cli
, mem_ctx
,
2344 member
, &member_sid
, &member_type
);
2346 if (!NT_STATUS_IS_OK(result
)) {
2347 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2352 /* Get sam policy handle */
2353 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2355 MAXIMUM_ALLOWED_ACCESS
,
2358 if (!NT_STATUS_IS_OK(status
)) {
2361 if (!NT_STATUS_IS_OK(result
)) {
2366 /* Get domain policy handle */
2367 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2369 MAXIMUM_ALLOWED_ACCESS
,
2373 if (!NT_STATUS_IS_OK(status
)) {
2376 if (!NT_STATUS_IS_OK(result
)) {
2381 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2383 MAXIMUM_ALLOWED_ACCESS
,
2387 if (!NT_STATUS_IS_OK(status
)) {
2390 if (!NT_STATUS_IS_OK(result
)) {
2394 status
= dcerpc_samr_AddAliasMember(b
, mem_ctx
,
2398 if (!NT_STATUS_IS_OK(status
)) {
2405 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2409 static NTSTATUS
rpc_group_addmem_internals(struct net_context
*c
,
2410 const struct dom_sid
*domain_sid
,
2411 const char *domain_name
,
2412 struct cli_state
*cli
,
2413 struct rpc_pipe_client
*pipe_hnd
,
2414 TALLOC_CTX
*mem_ctx
,
2418 struct dom_sid group_sid
;
2419 enum lsa_SidType group_type
;
2421 if (argc
!= 2 || c
->display_usage
) {
2424 _("net rpc group addmem <group> <member>\n"
2425 " Add a member to a group\n"
2426 " group\tGroup to add member to\n"
2427 " member\tMember to add to group\n"));
2428 return NT_STATUS_UNSUCCESSFUL
;
2431 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2432 &group_sid
, &group_type
))) {
2433 d_fprintf(stderr
, _("Could not lookup group name %s\n"),
2435 return NT_STATUS_UNSUCCESSFUL
;
2438 if (group_type
== SID_NAME_DOM_GRP
) {
2439 NTSTATUS result
= rpc_add_groupmem(pipe_hnd
, mem_ctx
,
2440 &group_sid
, argv
[1]);
2442 if (!NT_STATUS_IS_OK(result
)) {
2443 d_fprintf(stderr
, _("Could not add %s to %s: %s\n"),
2444 argv
[1], argv
[0], nt_errstr(result
));
2449 if (group_type
== SID_NAME_ALIAS
) {
2450 NTSTATUS result
= rpc_add_aliasmem(pipe_hnd
, cli
, mem_ctx
,
2451 &group_sid
, argv
[1]);
2453 if (!NT_STATUS_IS_OK(result
)) {
2454 d_fprintf(stderr
, _("Could not add %s to %s: %s\n"),
2455 argv
[1], argv
[0], nt_errstr(result
));
2460 d_fprintf(stderr
, _("Can only add members to global or local groups "
2461 "which %s is not\n"), argv
[0]);
2463 return NT_STATUS_UNSUCCESSFUL
;
2466 static int rpc_group_addmem(struct net_context
*c
, int argc
, const char **argv
)
2468 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2469 rpc_group_addmem_internals
,
2473 static NTSTATUS
rpc_del_groupmem(struct net_context
*c
,
2474 struct rpc_pipe_client
*pipe_hnd
,
2475 TALLOC_CTX
*mem_ctx
,
2476 const struct dom_sid
*group_sid
,
2479 struct policy_handle connect_pol
, domain_pol
;
2480 NTSTATUS status
, result
;
2482 struct policy_handle group_pol
;
2483 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2485 struct samr_Ids rids
, rid_types
;
2486 struct lsa_String lsa_acct_name
;
2490 sid_copy(&sid
, group_sid
);
2492 if (!sid_split_rid(&sid
, &group_rid
))
2493 return NT_STATUS_UNSUCCESSFUL
;
2495 /* Get sam policy handle */
2496 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2498 MAXIMUM_ALLOWED_ACCESS
,
2501 if (!NT_STATUS_IS_OK(status
)) {
2504 if (!NT_STATUS_IS_OK(result
)) {
2509 /* Get domain policy handle */
2510 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2512 MAXIMUM_ALLOWED_ACCESS
,
2516 if (!NT_STATUS_IS_OK(status
)) {
2519 if (!NT_STATUS_IS_OK(result
)) {
2523 init_lsa_String(&lsa_acct_name
, member
);
2525 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
2532 if (!NT_STATUS_IS_OK(status
)) {
2533 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2538 if (!NT_STATUS_IS_OK(result
)) {
2540 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2544 if (rids
.count
!= 1) {
2545 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2548 if (rid_types
.count
!= 1) {
2549 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
2553 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
2555 MAXIMUM_ALLOWED_ACCESS
,
2559 if (!NT_STATUS_IS_OK(status
)) {
2562 if (!NT_STATUS_IS_OK(result
)) {
2567 status
= dcerpc_samr_DeleteGroupMember(b
, mem_ctx
,
2571 if (!NT_STATUS_IS_OK(status
)) {
2577 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2581 static NTSTATUS
rpc_del_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2582 struct cli_state
*cli
,
2583 TALLOC_CTX
*mem_ctx
,
2584 const struct dom_sid
*alias_sid
,
2587 struct policy_handle connect_pol
, domain_pol
;
2588 NTSTATUS status
, result
;
2590 struct policy_handle alias_pol
;
2591 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2593 struct dom_sid member_sid
;
2594 enum lsa_SidType member_type
;
2598 sid_copy(&sid
, alias_sid
);
2600 if (!sid_split_rid(&sid
, &alias_rid
))
2601 return NT_STATUS_UNSUCCESSFUL
;
2603 result
= get_sid_from_name(cli
, mem_ctx
,
2604 member
, &member_sid
, &member_type
);
2606 if (!NT_STATUS_IS_OK(result
)) {
2607 d_fprintf(stderr
, _("Could not lookup up group member %s\n"),
2612 /* Get sam policy handle */
2613 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2615 MAXIMUM_ALLOWED_ACCESS
,
2618 if (!NT_STATUS_IS_OK(status
)) {
2621 if (!NT_STATUS_IS_OK(result
)) {
2626 /* Get domain policy handle */
2627 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2629 MAXIMUM_ALLOWED_ACCESS
,
2633 if (!NT_STATUS_IS_OK(status
)) {
2636 if (!NT_STATUS_IS_OK(result
)) {
2641 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2643 MAXIMUM_ALLOWED_ACCESS
,
2647 if (!NT_STATUS_IS_OK(status
)) {
2651 if (!NT_STATUS_IS_OK(result
)) {
2655 status
= dcerpc_samr_DeleteAliasMember(b
, mem_ctx
,
2660 if (!NT_STATUS_IS_OK(status
)) {
2667 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
2671 static NTSTATUS
rpc_group_delmem_internals(struct net_context
*c
,
2672 const struct dom_sid
*domain_sid
,
2673 const char *domain_name
,
2674 struct cli_state
*cli
,
2675 struct rpc_pipe_client
*pipe_hnd
,
2676 TALLOC_CTX
*mem_ctx
,
2680 struct dom_sid group_sid
;
2681 enum lsa_SidType group_type
;
2683 if (argc
!= 2 || c
->display_usage
) {
2686 _("net rpc group delmem <group> <member>\n"
2687 " Delete a member from a group\n"
2688 " group\tGroup to delete member from\n"
2689 " member\tMember to delete from group\n"));
2690 return NT_STATUS_UNSUCCESSFUL
;
2693 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2694 &group_sid
, &group_type
))) {
2695 d_fprintf(stderr
, _("Could not lookup group name %s\n"),
2697 return NT_STATUS_UNSUCCESSFUL
;
2700 if (group_type
== SID_NAME_DOM_GRP
) {
2701 NTSTATUS result
= rpc_del_groupmem(c
, pipe_hnd
, mem_ctx
,
2702 &group_sid
, argv
[1]);
2704 if (!NT_STATUS_IS_OK(result
)) {
2705 d_fprintf(stderr
, _("Could not del %s from %s: %s\n"),
2706 argv
[1], argv
[0], nt_errstr(result
));
2711 if (group_type
== SID_NAME_ALIAS
) {
2712 NTSTATUS result
= rpc_del_aliasmem(pipe_hnd
, cli
, mem_ctx
,
2713 &group_sid
, argv
[1]);
2715 if (!NT_STATUS_IS_OK(result
)) {
2716 d_fprintf(stderr
, _("Could not del %s from %s: %s\n"),
2717 argv
[1], argv
[0], nt_errstr(result
));
2722 d_fprintf(stderr
, _("Can only delete members from global or local "
2723 "groups which %s is not\n"), argv
[0]);
2725 return NT_STATUS_UNSUCCESSFUL
;
2728 static int rpc_group_delmem(struct net_context
*c
, int argc
, const char **argv
)
2730 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
2731 rpc_group_delmem_internals
,
2736 * List groups on a remote RPC server.
2738 * All parameters are provided by the run_rpc_command function, except for
2739 * argc, argv which are passes through.
2741 * @param domain_sid The domain sid acquired from the remote server.
2742 * @param cli A cli_state connected to the server.
2743 * @param mem_ctx Talloc context, destroyed on completion of the function.
2744 * @param argc Standard main() style argc.
2745 * @param argv Standard main() style argv. Initial components are already
2748 * @return Normal NTSTATUS return.
2751 static NTSTATUS
rpc_group_list_internals(struct net_context
*c
,
2752 const struct dom_sid
*domain_sid
,
2753 const char *domain_name
,
2754 struct cli_state
*cli
,
2755 struct rpc_pipe_client
*pipe_hnd
,
2756 TALLOC_CTX
*mem_ctx
,
2760 struct policy_handle connect_pol
, domain_pol
;
2761 NTSTATUS status
, result
;
2762 uint32_t start_idx
=0, max_entries
=250, num_entries
, i
, loop_count
= 0;
2763 struct samr_SamArray
*groups
= NULL
;
2764 bool global
= false;
2766 bool builtin
= false;
2767 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
2769 if (c
->display_usage
) {
2772 _("net rpc group list [global] [local] [builtin]\n"
2773 " List groups on RPC server\n"
2774 " global\tList global groups\n"
2775 " local\tList local groups\n"
2776 " builtin\tList builtin groups\n"
2777 " If none of global, local or builtin is "
2778 "specified, all three options are considered "
2780 return NT_STATUS_OK
;
2789 for (i
=0; i
<argc
; i
++) {
2790 if (strequal(argv
[i
], "global"))
2793 if (strequal(argv
[i
], "local"))
2796 if (strequal(argv
[i
], "builtin"))
2800 /* Get sam policy handle */
2802 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
2804 MAXIMUM_ALLOWED_ACCESS
,
2807 if (!NT_STATUS_IS_OK(status
)) {
2810 if (!NT_STATUS_IS_OK(result
)) {
2815 /* Get domain policy handle */
2817 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2819 MAXIMUM_ALLOWED_ACCESS
,
2820 discard_const_p(struct dom_sid2
, domain_sid
),
2823 if (!NT_STATUS_IS_OK(status
)) {
2826 if (!NT_STATUS_IS_OK(result
)) {
2831 /* Query domain groups */
2832 if (c
->opt_long_list_entries
)
2833 d_printf(_("\nGroup name Comment"
2834 "\n-----------------------------\n"));
2836 uint32_t max_size
, total_size
, returned_size
;
2837 union samr_DispInfo info
;
2841 dcerpc_get_query_dispinfo_params(
2842 loop_count
, &max_entries
, &max_size
);
2844 status
= dcerpc_samr_QueryDisplayInfo(b
, mem_ctx
,
2854 if (!NT_STATUS_IS_OK(status
)) {
2857 num_entries
= info
.info3
.count
;
2858 start_idx
+= info
.info3
.count
;
2860 if (!NT_STATUS_IS_OK(result
) &&
2861 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2864 for (i
= 0; i
< num_entries
; i
++) {
2866 const char *group
= NULL
;
2867 const char *desc
= NULL
;
2869 group
= info
.info3
.entries
[i
].account_name
.string
;
2870 desc
= info
.info3
.entries
[i
].description
.string
;
2872 if (c
->opt_long_list_entries
)
2873 printf("%-21.21s %-50.50s\n",
2876 printf("%s\n", group
);
2878 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2879 /* query domain aliases */
2884 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
2891 if (!NT_STATUS_IS_OK(status
)) {
2894 if (!NT_STATUS_IS_OK(result
) &&
2895 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2898 for (i
= 0; i
< num_entries
; i
++) {
2900 const char *description
= NULL
;
2902 if (c
->opt_long_list_entries
) {
2904 struct policy_handle alias_pol
;
2905 union samr_AliasInfo
*info
= NULL
;
2908 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2911 groups
->entries
[i
].idx
,
2914 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2915 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
2920 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2921 status
= dcerpc_samr_Close(b
, mem_ctx
,
2924 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2925 description
= info
->description
.string
;
2931 if (description
!= NULL
) {
2932 printf("%-21.21s %-50.50s\n",
2933 groups
->entries
[i
].name
.string
,
2936 printf("%s\n", groups
->entries
[i
].name
.string
);
2939 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2940 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
2941 /* Get builtin policy handle */
2943 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
2945 MAXIMUM_ALLOWED_ACCESS
,
2946 discard_const_p(struct dom_sid2
, &global_sid_Builtin
),
2949 if (!NT_STATUS_IS_OK(status
)) {
2952 if (!NT_STATUS_IS_OK(result
)) {
2957 /* query builtin aliases */
2960 if (!builtin
) break;
2962 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
2969 if (!NT_STATUS_IS_OK(status
)) {
2972 if (!NT_STATUS_IS_OK(result
) &&
2973 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
2978 for (i
= 0; i
< num_entries
; i
++) {
2980 const char *description
= NULL
;
2982 if (c
->opt_long_list_entries
) {
2984 struct policy_handle alias_pol
;
2985 union samr_AliasInfo
*info
= NULL
;
2988 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
2991 groups
->entries
[i
].idx
,
2994 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
2995 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
3000 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
3001 status
= dcerpc_samr_Close(b
, mem_ctx
,
3004 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(_result
)) {
3005 description
= info
->description
.string
;
3011 if (description
!= NULL
) {
3012 printf("%-21.21s %-50.50s\n",
3013 groups
->entries
[i
].name
.string
,
3016 printf("%s\n", groups
->entries
[i
].name
.string
);
3019 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
3027 static int rpc_group_list(struct net_context
*c
, int argc
, const char **argv
)
3029 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3030 rpc_group_list_internals
,
3034 static NTSTATUS
rpc_list_group_members(struct net_context
*c
,
3035 struct rpc_pipe_client
*pipe_hnd
,
3036 TALLOC_CTX
*mem_ctx
,
3037 const char *domain_name
,
3038 const struct dom_sid
*domain_sid
,
3039 struct policy_handle
*domain_pol
,
3042 NTSTATUS result
, status
;
3043 struct policy_handle group_pol
;
3044 uint32_t num_members
, *group_rids
;
3046 struct samr_RidAttrArray
*rids
= NULL
;
3047 struct lsa_Strings names
;
3048 struct samr_Ids types
;
3049 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3052 sid_to_fstring(sid_str
, domain_sid
);
3054 status
= dcerpc_samr_OpenGroup(b
, mem_ctx
,
3056 MAXIMUM_ALLOWED_ACCESS
,
3060 if (!NT_STATUS_IS_OK(status
)) {
3063 if (!NT_STATUS_IS_OK(result
)) {
3067 status
= dcerpc_samr_QueryGroupMember(b
, mem_ctx
,
3071 if (!NT_STATUS_IS_OK(status
)) {
3074 if (!NT_STATUS_IS_OK(result
)) {
3078 num_members
= rids
->count
;
3079 group_rids
= rids
->rids
;
3081 while (num_members
> 0) {
3082 int this_time
= 512;
3084 if (num_members
< this_time
)
3085 this_time
= num_members
;
3087 status
= dcerpc_samr_LookupRids(b
, mem_ctx
,
3094 if (!NT_STATUS_IS_OK(status
)) {
3097 if (!NT_STATUS_IS_OK(result
)) {
3100 if (names
.count
!= this_time
) {
3101 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3103 if (types
.count
!= this_time
) {
3104 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3106 /* We only have users as members, but make the output
3107 the same as the output of alias members */
3109 for (i
= 0; i
< this_time
; i
++) {
3111 if (c
->opt_long_list_entries
) {
3112 printf("%s-%d %s\\%s %d\n", sid_str
,
3113 group_rids
[i
], domain_name
,
3114 names
.names
[i
].string
,
3117 printf("%s\\%s\n", domain_name
,
3118 names
.names
[i
].string
);
3122 num_members
-= this_time
;
3126 return NT_STATUS_OK
;
3129 static NTSTATUS
rpc_list_alias_members(struct net_context
*c
,
3130 struct rpc_pipe_client
*pipe_hnd
,
3131 struct cli_state
*cli
,
3132 TALLOC_CTX
*mem_ctx
,
3133 struct policy_handle
*domain_pol
,
3136 NTSTATUS result
, status
;
3137 struct rpc_pipe_client
*lsa_pipe
;
3138 struct policy_handle alias_pol
, lsa_pol
;
3139 uint32_t num_members
;
3140 struct dom_sid
*alias_sids
;
3143 enum lsa_SidType
*types
;
3145 struct lsa_SidArray sid_array
;
3146 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3148 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
3150 MAXIMUM_ALLOWED_ACCESS
,
3154 if (!NT_STATUS_IS_OK(status
)) {
3157 if (!NT_STATUS_IS_OK(result
)) {
3161 status
= dcerpc_samr_GetMembersInAlias(b
, mem_ctx
,
3165 if (!NT_STATUS_IS_OK(status
)) {
3166 d_fprintf(stderr
, _("Couldn't list alias members\n"));
3169 if (!NT_STATUS_IS_OK(result
)) {
3170 d_fprintf(stderr
, _("Couldn't list alias members\n"));
3174 num_members
= sid_array
.num_sids
;
3176 if (num_members
== 0) {
3177 return NT_STATUS_OK
;
3180 result
= cli_rpc_pipe_open_noauth(cli
,
3183 if (!NT_STATUS_IS_OK(result
)) {
3184 d_fprintf(stderr
, _("Couldn't open LSA pipe. Error was %s\n"),
3185 nt_errstr(result
) );
3189 result
= rpccli_lsa_open_policy(lsa_pipe
, mem_ctx
, true,
3190 SEC_FLAG_MAXIMUM_ALLOWED
, &lsa_pol
);
3192 if (!NT_STATUS_IS_OK(result
)) {
3193 d_fprintf(stderr
, _("Couldn't open LSA policy handle\n"));
3194 TALLOC_FREE(lsa_pipe
);
3198 alias_sids
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_members
);
3200 d_fprintf(stderr
, _("Out of memory\n"));
3201 TALLOC_FREE(lsa_pipe
);
3202 return NT_STATUS_NO_MEMORY
;
3205 for (i
=0; i
<num_members
; i
++) {
3206 sid_copy(&alias_sids
[i
], sid_array
.sids
[i
].sid
);
3209 result
= rpccli_lsa_lookup_sids(lsa_pipe
, mem_ctx
, &lsa_pol
,
3210 num_members
, alias_sids
,
3211 &domains
, &names
, &types
);
3213 if (!NT_STATUS_IS_OK(result
) &&
3214 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3215 d_fprintf(stderr
, _("Couldn't lookup SIDs\n"));
3216 TALLOC_FREE(lsa_pipe
);
3220 for (i
= 0; i
< num_members
; i
++) {
3222 sid_to_fstring(sid_str
, &alias_sids
[i
]);
3224 if (c
->opt_long_list_entries
) {
3225 printf("%s %s\\%s %d\n", sid_str
,
3226 domains
[i
] ? domains
[i
] : _("*unknown*"),
3227 names
[i
] ? names
[i
] : _("*unknown*"), types
[i
]);
3230 printf("%s\\%s\n", domains
[i
], names
[i
]);
3232 printf("%s\n", sid_str
);
3236 TALLOC_FREE(lsa_pipe
);
3237 return NT_STATUS_OK
;
3240 static NTSTATUS
rpc_group_members_internals(struct net_context
*c
,
3241 const struct dom_sid
*domain_sid
,
3242 const char *domain_name
,
3243 struct cli_state
*cli
,
3244 struct rpc_pipe_client
*pipe_hnd
,
3245 TALLOC_CTX
*mem_ctx
,
3249 NTSTATUS result
, status
;
3250 struct policy_handle connect_pol
, domain_pol
;
3251 struct samr_Ids rids
, rid_types
;
3252 struct lsa_String lsa_acct_name
;
3253 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3255 /* Get sam policy handle */
3257 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
3259 MAXIMUM_ALLOWED_ACCESS
,
3262 if (!NT_STATUS_IS_OK(status
)) {
3265 if (!NT_STATUS_IS_OK(result
)) {
3269 /* Get domain policy handle */
3271 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
3273 MAXIMUM_ALLOWED_ACCESS
,
3274 discard_const_p(struct dom_sid2
, domain_sid
),
3277 if (!NT_STATUS_IS_OK(status
)) {
3280 if (!NT_STATUS_IS_OK(result
)) {
3284 init_lsa_String(&lsa_acct_name
, argv
[0]); /* sure? */
3286 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
3293 if (!NT_STATUS_IS_OK(status
)) {
3297 if (!NT_STATUS_IS_OK(result
)) {
3299 /* Ok, did not find it in the global sam, try with builtin */
3301 struct dom_sid sid_Builtin
;
3303 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
3305 sid_copy(&sid_Builtin
, &global_sid_Builtin
);
3307 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
3309 MAXIMUM_ALLOWED_ACCESS
,
3313 if (!NT_STATUS_IS_OK(status
)) {
3316 if (!NT_STATUS_IS_OK(result
)) {
3317 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3322 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
3329 if (!NT_STATUS_IS_OK(status
)) {
3332 if (!NT_STATUS_IS_OK(result
)) {
3333 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3339 if (rids
.count
!= 1) {
3340 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3342 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3344 if (rid_types
.count
!= 1) {
3345 d_fprintf(stderr
, _("Couldn't find group %s\n"),
3347 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
3351 if (rid_types
.ids
[0] == SID_NAME_DOM_GRP
) {
3352 return rpc_list_group_members(c
, pipe_hnd
, mem_ctx
, domain_name
,
3353 domain_sid
, &domain_pol
,
3357 if (rid_types
.ids
[0] == SID_NAME_ALIAS
) {
3358 return rpc_list_alias_members(c
, pipe_hnd
, cli
, mem_ctx
, &domain_pol
,
3362 return NT_STATUS_NO_SUCH_GROUP
;
3365 static int rpc_group_members(struct net_context
*c
, int argc
, const char **argv
)
3367 if (argc
!= 1 || c
->display_usage
) {
3368 return rpc_group_usage(c
, argc
, argv
);
3371 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3372 rpc_group_members_internals
,
3376 static int rpc_group_rename_internals(struct net_context
*c
, int argc
, const char **argv
)
3378 NET_API_STATUS status
;
3379 struct GROUP_INFO_0 g0
;
3383 d_printf(_("Usage:\n"));
3384 d_printf("net rpc group rename group newname\n");
3388 g0
.grpi0_name
= argv
[1];
3390 status
= NetGroupSetInfo(c
->opt_host
,
3397 d_fprintf(stderr
, _("Renaming group %s failed with: %s\n"),
3398 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
3406 static int rpc_group_rename(struct net_context
*c
, int argc
, const char **argv
)
3408 if (argc
!= 2 || c
->display_usage
) {
3409 return rpc_group_usage(c
, argc
, argv
);
3412 return rpc_group_rename_internals(c
, argc
, argv
);
3416 * 'net rpc group' entrypoint.
3417 * @param argc Standard main() style argc.
3418 * @param argv Standard main() style argv. Initial components are already
3422 int net_rpc_group(struct net_context
*c
, int argc
, const char **argv
)
3424 NET_API_STATUS status
;
3426 struct functable func
[] = {
3431 N_("Create specified group"),
3432 N_("net rpc group add\n"
3433 " Create specified group")
3439 N_("Delete specified group"),
3440 N_("net rpc group delete\n"
3441 " Delete specified group")
3447 N_("Add member to group"),
3448 N_("net rpc group addmem\n"
3449 " Add member to group")
3455 N_("Remove member from group"),
3456 N_("net rpc group delmem\n"
3457 " Remove member from group")
3464 N_("net rpc group list\n"
3471 N_("List group members"),
3472 N_("net rpc group members\n"
3473 " List group members")
3480 N_("net rpc group rename\n"
3483 {NULL
, NULL
, 0, NULL
, NULL
}
3486 status
= libnetapi_net_init(&c
->netapi_ctx
);
3490 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
3491 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
3492 if (c
->opt_kerberos
) {
3493 libnetapi_set_use_kerberos(c
->netapi_ctx
);
3497 if (c
->display_usage
) {
3498 d_printf(_("Usage:\n"));
3499 d_printf(_("net rpc group\n"
3500 " Alias for net rpc group list global "
3501 "local builtin\n"));
3502 net_display_usage_from_functable(func
);
3506 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
3507 rpc_group_list_internals
,
3511 return net_run_function(c
, argc
, argv
, "net rpc group", func
);
3514 /****************************************************************************/
3516 static int rpc_share_usage(struct net_context
*c
, int argc
, const char **argv
)
3518 return net_share_usage(c
, argc
, argv
);
3522 * Add a share on a remote RPC server.
3524 * @param argc Standard main() style argc.
3525 * @param argv Standard main() style argv. Initial components are already
3528 * @return A shell status integer (0 for success).
3531 static int rpc_share_add(struct net_context
*c
, int argc
, const char **argv
)
3533 NET_API_STATUS status
;
3536 uint32_t type
= STYPE_DISKTREE
; /* only allow disk shares to be added */
3537 uint32_t num_users
=0, perms
=0;
3538 char *password
=NULL
; /* don't allow a share password */
3539 struct SHARE_INFO_2 i2
;
3540 uint32_t parm_error
= 0;
3542 if ((argc
< 1) || !strchr(argv
[0], '=') || c
->display_usage
) {
3543 return rpc_share_usage(c
, argc
, argv
);
3546 if ((sharename
= talloc_strdup(c
, argv
[0])) == NULL
) {
3550 path
= strchr(sharename
, '=');
3557 i2
.shi2_netname
= sharename
;
3558 i2
.shi2_type
= type
;
3559 i2
.shi2_remark
= c
->opt_comment
;
3560 i2
.shi2_permissions
= perms
;
3561 i2
.shi2_max_uses
= c
->opt_maxusers
;
3562 i2
.shi2_current_uses
= num_users
;
3563 i2
.shi2_path
= path
;
3564 i2
.shi2_passwd
= password
;
3566 status
= NetShareAdd(c
->opt_host
,
3571 printf(_("NetShareAdd failed with: %s\n"),
3572 libnetapi_get_error_string(c
->netapi_ctx
, status
));
3579 * Delete a share on a remote RPC server.
3581 * @param domain_sid The domain sid acquired from the remote server.
3582 * @param argc Standard main() style argc.
3583 * @param argv Standard main() style argv. Initial components are already
3586 * @return A shell status integer (0 for success).
3588 static int rpc_share_delete(struct net_context
*c
, int argc
, const char **argv
)
3590 if (argc
< 1 || c
->display_usage
) {
3591 return rpc_share_usage(c
, argc
, argv
);
3594 return NetShareDel(c
->opt_host
, argv
[0], 0);
3598 * Formatted print of share info
3600 * @param r pointer to SHARE_INFO_1 to format
3603 static void display_share_info_1(struct net_context
*c
,
3604 struct SHARE_INFO_1
*r
)
3606 if (c
->opt_long_list_entries
) {
3607 d_printf("%-12s %-8.8s %-50s\n",
3609 net_share_type_str(r
->shi1_type
& ~(STYPE_TEMPORARY
|STYPE_HIDDEN
)),
3612 d_printf("%s\n", r
->shi1_netname
);
3616 static WERROR
get_share_info(struct net_context
*c
,
3617 struct rpc_pipe_client
*pipe_hnd
,
3618 TALLOC_CTX
*mem_ctx
,
3622 struct srvsvc_NetShareInfoCtr
*info_ctr
)
3626 union srvsvc_NetShareInfo info
;
3627 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
3629 /* no specific share requested, enumerate all */
3632 uint32_t preferred_len
= 0xffffffff;
3633 uint32_t total_entries
= 0;
3634 uint32_t resume_handle
= 0;
3636 info_ctr
->level
= level
;
3638 status
= dcerpc_srvsvc_NetShareEnumAll(b
, mem_ctx
,
3645 if (!NT_STATUS_IS_OK(status
)) {
3646 return ntstatus_to_werror(status
);
3651 /* request just one share */
3652 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
3659 if (!NT_STATUS_IS_OK(status
)) {
3660 result
= ntstatus_to_werror(status
);
3664 if (!W_ERROR_IS_OK(result
)) {
3669 ZERO_STRUCTP(info_ctr
);
3671 info_ctr
->level
= level
;
3676 struct srvsvc_NetShareCtr1
*ctr1
;
3678 ctr1
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr1
);
3679 W_ERROR_HAVE_NO_MEMORY(ctr1
);
3682 ctr1
->array
= info
.info1
;
3684 info_ctr
->ctr
.ctr1
= ctr1
;
3690 struct srvsvc_NetShareCtr2
*ctr2
;
3692 ctr2
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr2
);
3693 W_ERROR_HAVE_NO_MEMORY(ctr2
);
3696 ctr2
->array
= info
.info2
;
3698 info_ctr
->ctr
.ctr2
= ctr2
;
3704 struct srvsvc_NetShareCtr502
*ctr502
;
3706 ctr502
= talloc_zero(mem_ctx
, struct srvsvc_NetShareCtr502
);
3707 W_ERROR_HAVE_NO_MEMORY(ctr502
);
3710 ctr502
->array
= info
.info502
;
3712 info_ctr
->ctr
.ctr502
= ctr502
;
3722 * 'net rpc share list' entrypoint.
3723 * @param argc Standard main() style argc.
3724 * @param argv Standard main() style argv. Initial components are already
3727 static int rpc_share_list(struct net_context
*c
, int argc
, const char **argv
)
3729 NET_API_STATUS status
;
3730 struct SHARE_INFO_1
*i1
= NULL
;
3731 uint32_t entries_read
= 0;
3732 uint32_t total_entries
= 0;
3733 uint32_t resume_handle
= 0;
3734 uint32_t i
, level
= 1;
3736 if (c
->display_usage
) {
3738 "net rpc share list\n"
3741 _("List shares on remote server"));
3745 status
= NetShareEnum(c
->opt_host
,
3747 (uint8_t **)(void *)&i1
,
3756 /* Display results */
3758 if (c
->opt_long_list_entries
) {
3760 "\nEnumerating shared resources (exports) on remote server:\n\n"
3761 "\nShare name Type Description\n"
3762 "---------- ---- -----------\n"));
3764 for (i
= 0; i
< entries_read
; i
++)
3765 display_share_info_1(c
, &i1
[i
]);
3770 static bool check_share_availability(struct cli_state
*cli
, const char *netname
)
3774 status
= cli_tree_connect(cli
, netname
, "A:", NULL
);
3775 if (!NT_STATUS_IS_OK(status
)) {
3776 d_printf(_("skipping [%s]: not a file share.\n"), netname
);
3780 status
= cli_tdis(cli
);
3781 if (!NT_STATUS_IS_OK(status
)) {
3782 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status
));
3789 static bool check_share_sanity(struct net_context
*c
, struct cli_state
*cli
,
3790 const char *netname
, uint32_t type
)
3792 /* only support disk shares */
3793 if (! ( type
== STYPE_DISKTREE
|| type
== (STYPE_DISKTREE
| STYPE_HIDDEN
)) ) {
3794 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname
,
3799 /* skip builtin shares */
3800 /* FIXME: should print$ be added too ? */
3801 if (strequal(netname
,"IPC$") || strequal(netname
,"ADMIN$") ||
3802 strequal(netname
,"global"))
3805 if (c
->opt_exclude
&& in_list(netname
, c
->opt_exclude
, false)) {
3806 printf(_("excluding [%s]\n"), netname
);
3810 return check_share_availability(cli
, netname
);
3814 * Migrate shares from a remote RPC server to the local RPC server.
3816 * All parameters are provided by the run_rpc_command function, except for
3817 * argc, argv which are passed through.
3819 * @param domain_sid The domain sid acquired from the remote server.
3820 * @param cli A cli_state connected to the server.
3821 * @param mem_ctx Talloc context, destroyed on completion of the function.
3822 * @param argc Standard main() style argc.
3823 * @param argv Standard main() style argv. Initial components are already
3826 * @return Normal NTSTATUS return.
3829 static NTSTATUS
rpc_share_migrate_shares_internals(struct net_context
*c
,
3830 const struct dom_sid
*domain_sid
,
3831 const char *domain_name
,
3832 struct cli_state
*cli
,
3833 struct rpc_pipe_client
*pipe_hnd
,
3834 TALLOC_CTX
*mem_ctx
,
3839 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3840 struct srvsvc_NetShareInfoCtr ctr_src
;
3842 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
3843 struct cli_state
*cli_dst
= NULL
;
3844 uint32_t level
= 502; /* includes secdesc */
3845 uint32_t parm_error
= 0;
3846 struct dcerpc_binding_handle
*b
;
3848 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3850 if (!W_ERROR_IS_OK(result
))
3853 /* connect destination PI_SRVSVC */
3854 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
,
3856 if (!NT_STATUS_IS_OK(nt_status
))
3859 b
= srvsvc_pipe
->binding_handle
;
3861 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
3863 union srvsvc_NetShareInfo info
;
3864 struct srvsvc_NetShareInfo502 info502
=
3865 ctr_src
.ctr
.ctr502
->array
[i
];
3867 /* reset error-code */
3868 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3870 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
3873 /* finally add the share on the dst server */
3875 printf(_("migrating: [%s], path: %s, comment: %s, without "
3877 info502
.name
, info502
.path
, info502
.comment
);
3879 info
.info502
= &info502
;
3881 nt_status
= dcerpc_srvsvc_NetShareAdd(b
, mem_ctx
,
3882 srvsvc_pipe
->desthost
,
3887 if (!NT_STATUS_IS_OK(nt_status
)) {
3888 printf(_("cannot add share: %s\n"),
3889 nt_errstr(nt_status
));
3892 if (W_ERROR_V(result
) == W_ERROR_V(WERR_FILE_EXISTS
)) {
3893 printf(_(" [%s] does already exist\n"),
3898 if (!W_ERROR_IS_OK(result
)) {
3899 nt_status
= werror_to_ntstatus(result
);
3900 printf(_("cannot add share: %s\n"),
3901 win_errstr(result
));
3907 nt_status
= NT_STATUS_OK
;
3911 cli_shutdown(cli_dst
);
3919 * Migrate shares from a RPC server to another.
3921 * @param argc Standard main() style argc.
3922 * @param argv Standard main() style argv. Initial components are already
3925 * @return A shell status integer (0 for success).
3927 static int rpc_share_migrate_shares(struct net_context
*c
, int argc
,
3930 if (c
->display_usage
) {
3932 "net rpc share migrate shares\n"
3935 _("Migrate shares to local server"));
3940 printf(_("no server to migrate\n"));
3944 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
3945 rpc_share_migrate_shares_internals
,
3952 * @param f file_info
3953 * @param mask current search mask
3954 * @param state arg-pointer
3957 static NTSTATUS
copy_fn(const char *mnt
, struct file_info
*f
,
3958 const char *mask
, void *state
)
3960 static NTSTATUS nt_status
;
3961 static struct copy_clistate
*local_state
;
3962 static fstring filename
, new_mask
;
3965 struct net_context
*c
;
3967 local_state
= (struct copy_clistate
*)state
;
3968 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3972 if (strequal(f
->name
, ".") || strequal(f
->name
, ".."))
3973 return NT_STATUS_OK
;
3975 DEBUG(3,("got mask: %s, name: %s\n", mask
, f
->name
));
3978 if (f
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
3980 DEBUG(3,("got dir: %s\n", f
->name
));
3982 fstrcpy(dir
, local_state
->cwd
);
3984 fstrcat(dir
, f
->name
);
3986 switch (net_mode_share
)
3988 case NET_MODE_SHARE_MIGRATE
:
3989 /* create that directory */
3990 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
3991 local_state
->cli_share_src
,
3992 local_state
->cli_share_dst
,
3994 c
->opt_acls
? true : false,
3995 c
->opt_attrs
? true : false,
3996 c
->opt_timestamps
? true:false,
4000 d_fprintf(stderr
, _("Unsupported mode %d\n"), net_mode_share
);
4001 return NT_STATUS_INTERNAL_ERROR
;
4004 if (!NT_STATUS_IS_OK(nt_status
)) {
4005 printf(_("could not handle dir %s: %s\n"),
4006 dir
, nt_errstr(nt_status
));
4010 /* search below that directory */
4011 if (strlcpy(new_mask
, dir
, sizeof(new_mask
)) >= sizeof(new_mask
)) {
4012 return NT_STATUS_NO_MEMORY
;
4014 if (strlcat(new_mask
, "\\*", sizeof(new_mask
)) >= sizeof(new_mask
)) {
4015 return NT_STATUS_NO_MEMORY
;
4018 old_dir
= local_state
->cwd
;
4019 local_state
->cwd
= dir
;
4020 nt_status
= sync_files(local_state
, new_mask
);
4021 if (!NT_STATUS_IS_OK(nt_status
)) {
4022 printf(_("could not handle files\n"));
4024 local_state
->cwd
= old_dir
;
4031 fstrcpy(filename
, local_state
->cwd
);
4032 fstrcat(filename
, "\\");
4033 fstrcat(filename
, f
->name
);
4035 DEBUG(3,("got file: %s\n", filename
));
4037 switch (net_mode_share
)
4039 case NET_MODE_SHARE_MIGRATE
:
4040 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
4041 local_state
->cli_share_src
,
4042 local_state
->cli_share_dst
,
4044 c
->opt_acls
? true : false,
4045 c
->opt_attrs
? true : false,
4046 c
->opt_timestamps
? true: false,
4050 d_fprintf(stderr
, _("Unsupported file mode %d\n"),
4052 return NT_STATUS_INTERNAL_ERROR
;
4055 if (!NT_STATUS_IS_OK(nt_status
))
4056 printf(_("could not handle file %s: %s\n"),
4057 filename
, nt_errstr(nt_status
));
4062 * sync files, can be called recursivly to list files
4063 * and then call copy_fn for each file
4065 * @param cp_clistate pointer to the copy_clistate we work with
4066 * @param mask the current search mask
4068 * @return Boolean result
4070 static NTSTATUS
sync_files(struct copy_clistate
*cp_clistate
, const char *mask
)
4072 struct cli_state
*targetcli
;
4073 char *targetpath
= NULL
;
4076 DEBUG(3,("calling cli_list with mask: %s\n", mask
));
4078 status
= cli_resolve_path(talloc_tos(), "", NULL
,
4079 cp_clistate
->cli_share_src
,
4080 mask
, &targetcli
, &targetpath
);
4081 if (!NT_STATUS_IS_OK(status
)) {
4082 d_fprintf(stderr
, _("cli_resolve_path %s failed with error: "
4084 mask
, nt_errstr(status
));
4088 status
= cli_list(targetcli
, targetpath
, cp_clistate
->attribute
,
4089 copy_fn
, cp_clistate
);
4090 if (!NT_STATUS_IS_OK(status
)) {
4091 d_fprintf(stderr
, _("listing %s failed with error: %s\n"),
4092 mask
, nt_errstr(status
));
4100 * Set the top level directory permissions before we do any further copies.
4101 * Should set up ACL inheritance.
4104 bool copy_top_level_perms(struct net_context
*c
,
4105 struct copy_clistate
*cp_clistate
,
4106 const char *sharename
)
4108 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4110 switch (net_mode_share
) {
4111 case NET_MODE_SHARE_MIGRATE
:
4112 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename
));
4113 nt_status
= net_copy_fileattr(c
,
4114 cp_clistate
->mem_ctx
,
4115 cp_clistate
->cli_share_src
,
4116 cp_clistate
->cli_share_dst
,
4118 c
->opt_acls
? true : false,
4119 c
->opt_attrs
? true : false,
4120 c
->opt_timestamps
? true: false,
4124 d_fprintf(stderr
, _("Unsupported mode %d\n"), net_mode_share
);
4128 if (!NT_STATUS_IS_OK(nt_status
)) {
4129 printf(_("Could handle directory attributes for top level "
4130 "directory of share %s. Error %s\n"),
4131 sharename
, nt_errstr(nt_status
));
4139 * Sync all files inside a remote share to another share (over smb).
4141 * All parameters are provided by the run_rpc_command function, except for
4142 * argc, argv which are passed through.
4144 * @param domain_sid The domain sid acquired from the remote server.
4145 * @param cli A cli_state connected to the server.
4146 * @param mem_ctx Talloc context, destroyed on completion of the function.
4147 * @param argc Standard main() style argc.
4148 * @param argv Standard main() style argv. Initial components are already
4151 * @return Normal NTSTATUS return.
4154 static NTSTATUS
rpc_share_migrate_files_internals(struct net_context
*c
,
4155 const struct dom_sid
*domain_sid
,
4156 const char *domain_name
,
4157 struct cli_state
*cli
,
4158 struct rpc_pipe_client
*pipe_hnd
,
4159 TALLOC_CTX
*mem_ctx
,
4164 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4165 struct srvsvc_NetShareInfoCtr ctr_src
;
4167 uint32_t level
= 502;
4168 struct copy_clistate cp_clistate
;
4169 bool got_src_share
= false;
4170 bool got_dst_share
= false;
4171 const char *mask
= "\\*";
4174 dst
= SMB_STRDUP(c
->opt_destination
?c
->opt_destination
:"127.0.0.1");
4176 nt_status
= NT_STATUS_NO_MEMORY
;
4180 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
4183 if (!W_ERROR_IS_OK(result
))
4186 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
4188 struct srvsvc_NetShareInfo502 info502
=
4189 ctr_src
.ctr
.ctr502
->array
[i
];
4191 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
4194 /* one might not want to mirror whole discs :) */
4195 if (strequal(info502
.name
, "print$") || info502
.name
[1] == '$') {
4196 d_printf(_("skipping [%s]: builtin/hidden share\n"),
4201 switch (net_mode_share
)
4203 case NET_MODE_SHARE_MIGRATE
:
4207 d_fprintf(stderr
, _("Unsupported mode %d\n"),
4211 printf(_(" [%s] files and directories %s ACLs, %s DOS "
4214 c
->opt_acls
? _("including") : _("without"),
4215 c
->opt_attrs
? _("including") : _("without"),
4216 c
->opt_timestamps
? _("(preserving timestamps)") : "");
4218 cp_clistate
.mem_ctx
= mem_ctx
;
4219 cp_clistate
.cli_share_src
= NULL
;
4220 cp_clistate
.cli_share_dst
= NULL
;
4221 cp_clistate
.cwd
= NULL
;
4222 cp_clistate
.attribute
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_DIRECTORY
;
4225 /* open share source */
4226 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_src
,
4227 smbXcli_conn_remote_sockaddr(cli
->conn
),
4228 smbXcli_conn_remote_name(cli
->conn
),
4229 info502
.name
, "A:");
4230 if (!NT_STATUS_IS_OK(nt_status
))
4233 got_src_share
= true;
4235 if (net_mode_share
== NET_MODE_SHARE_MIGRATE
) {
4236 /* open share destination */
4237 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_dst
,
4238 NULL
, dst
, info502
.name
, "A:");
4239 if (!NT_STATUS_IS_OK(nt_status
))
4242 got_dst_share
= true;
4245 if (!copy_top_level_perms(c
, &cp_clistate
, info502
.name
)) {
4246 d_fprintf(stderr
, _("Could not handle the top level "
4247 "directory permissions for the "
4248 "share: %s\n"), info502
.name
);
4249 nt_status
= NT_STATUS_UNSUCCESSFUL
;
4253 nt_status
= sync_files(&cp_clistate
, mask
);
4254 if (!NT_STATUS_IS_OK(nt_status
)) {
4255 d_fprintf(stderr
, _("could not handle files for share: "
4256 "%s\n"), info502
.name
);
4261 nt_status
= NT_STATUS_OK
;
4266 cli_shutdown(cp_clistate
.cli_share_src
);
4269 cli_shutdown(cp_clistate
.cli_share_dst
);
4276 static int rpc_share_migrate_files(struct net_context
*c
, int argc
, const char **argv
)
4278 if (c
->display_usage
) {
4280 "net share migrate files\n"
4283 _("Migrate files to local server"));
4288 d_printf(_("no server to migrate\n"));
4292 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4293 rpc_share_migrate_files_internals
,
4298 * Migrate share-ACLs from a remote RPC server to the local RPC server.
4300 * All parameters are provided by the run_rpc_command function, except for
4301 * argc, argv which are passed through.
4303 * @param domain_sid The domain sid acquired from the remote server.
4304 * @param cli A cli_state connected to the server.
4305 * @param mem_ctx Talloc context, destroyed on completion of the function.
4306 * @param argc Standard main() style argc.
4307 * @param argv Standard main() style argv. Initial components are already
4310 * @return Normal NTSTATUS return.
4313 static NTSTATUS
rpc_share_migrate_security_internals(struct net_context
*c
,
4314 const struct dom_sid
*domain_sid
,
4315 const char *domain_name
,
4316 struct cli_state
*cli
,
4317 struct rpc_pipe_client
*pipe_hnd
,
4318 TALLOC_CTX
*mem_ctx
,
4323 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
4324 struct srvsvc_NetShareInfoCtr ctr_src
;
4325 union srvsvc_NetShareInfo info
;
4327 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
4328 struct cli_state
*cli_dst
= NULL
;
4329 uint32_t level
= 502; /* includes secdesc */
4330 uint32_t parm_error
= 0;
4331 struct dcerpc_binding_handle
*b
;
4333 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
4336 if (!W_ERROR_IS_OK(result
))
4339 /* connect destination PI_SRVSVC */
4340 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
,
4342 if (!NT_STATUS_IS_OK(nt_status
))
4345 b
= srvsvc_pipe
->binding_handle
;
4347 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
4349 struct srvsvc_NetShareInfo502 info502
=
4350 ctr_src
.ctr
.ctr502
->array
[i
];
4352 /* reset error-code */
4353 nt_status
= NT_STATUS_UNSUCCESSFUL
;
4355 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
4358 printf(_("migrating: [%s], path: %s, comment: %s, including "
4360 info502
.name
, info502
.path
, info502
.comment
);
4363 display_sec_desc(info502
.sd_buf
.sd
);
4365 /* FIXME: shouldn't we be able to just set the security descriptor ? */
4366 info
.info502
= &info502
;
4368 /* finally modify the share on the dst server */
4369 nt_status
= dcerpc_srvsvc_NetShareSetInfo(b
, mem_ctx
,
4370 srvsvc_pipe
->desthost
,
4376 if (!NT_STATUS_IS_OK(nt_status
)) {
4377 printf(_("cannot set share-acl: %s\n"),
4378 nt_errstr(nt_status
));
4381 if (!W_ERROR_IS_OK(result
)) {
4382 nt_status
= werror_to_ntstatus(result
);
4383 printf(_("cannot set share-acl: %s\n"),
4384 win_errstr(result
));
4390 nt_status
= NT_STATUS_OK
;
4394 cli_shutdown(cli_dst
);
4402 * Migrate share-acls from a RPC server to another.
4404 * @param argc Standard main() style argc.
4405 * @param argv Standard main() style argv. Initial components are already
4408 * @return A shell status integer (0 for success).
4410 static int rpc_share_migrate_security(struct net_context
*c
, int argc
,
4413 if (c
->display_usage
) {
4415 "net rpc share migrate security\n"
4418 _("Migrate share-acls to local server"));
4423 d_printf(_("no server to migrate\n"));
4427 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4428 rpc_share_migrate_security_internals
,
4433 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4434 * from one server to another.
4436 * @param argc Standard main() style argc.
4437 * @param argv Standard main() style argv. Initial components are already
4440 * @return A shell status integer (0 for success).
4443 static int rpc_share_migrate_all(struct net_context
*c
, int argc
,
4448 if (c
->display_usage
) {
4450 "net rpc share migrate all\n"
4453 _("Migrates shares including all share settings"));
4458 d_printf(_("no server to migrate\n"));
4462 /* order is important. we don't want to be locked out by the share-acl
4463 * before copying files - gd */
4465 ret
= run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4466 rpc_share_migrate_shares_internals
, argc
, argv
);
4470 ret
= run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4471 rpc_share_migrate_files_internals
, argc
, argv
);
4475 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
4476 rpc_share_migrate_security_internals
, argc
,
4482 * 'net rpc share migrate' entrypoint.
4483 * @param argc Standard main() style argc.
4484 * @param argv Standard main() style argv. Initial components are already
4487 static int rpc_share_migrate(struct net_context
*c
, int argc
, const char **argv
)
4490 struct functable func
[] = {
4493 rpc_share_migrate_all
,
4495 N_("Migrate shares from remote to local server"),
4496 N_("net rpc share migrate all\n"
4497 " Migrate shares from remote to local server")
4501 rpc_share_migrate_files
,
4503 N_("Migrate files from remote to local server"),
4504 N_("net rpc share migrate files\n"
4505 " Migrate files from remote to local server")
4509 rpc_share_migrate_security
,
4511 N_("Migrate share-ACLs from remote to local server"),
4512 N_("net rpc share migrate security\n"
4513 " Migrate share-ACLs from remote to local server")
4517 rpc_share_migrate_shares
,
4519 N_("Migrate shares from remote to local server"),
4520 N_("net rpc share migrate shares\n"
4521 " Migrate shares from remote to local server")
4523 {NULL
, NULL
, 0, NULL
, NULL
}
4526 net_mode_share
= NET_MODE_SHARE_MIGRATE
;
4528 return net_run_function(c
, argc
, argv
, "net rpc share migrate", func
);
4533 uint32_t num_members
;
4534 struct dom_sid
*members
;
4537 static int num_server_aliases
;
4538 static struct full_alias
*server_aliases
;
4541 * Add an alias to the static list.
4543 static void push_alias(struct full_alias
*alias
)
4547 if (server_aliases
== NULL
) {
4548 server_aliases
= talloc_array(NULL
, struct full_alias
, 100);
4549 if (server_aliases
== NULL
) {
4550 smb_panic("talloc_array failed");
4554 array_size
= talloc_array_length(server_aliases
);
4555 if (array_size
== num_server_aliases
) {
4556 server_aliases
= talloc_realloc(NULL
, server_aliases
,
4557 struct full_alias
, array_size
+ 100);
4558 if (server_aliases
== NULL
) {
4559 smb_panic("talloc_realloc failed");
4563 server_aliases
[num_server_aliases
] = *alias
;
4564 num_server_aliases
+= 1;
4568 * For a specific domain on the server, fetch all the aliases
4569 * and their members. Add all of them to the server_aliases.
4572 static NTSTATUS
rpc_fetch_domain_aliases(struct rpc_pipe_client
*pipe_hnd
,
4573 TALLOC_CTX
*mem_ctx
,
4574 struct policy_handle
*connect_pol
,
4575 const struct dom_sid
*domain_sid
)
4577 uint32_t start_idx
, max_entries
, num_entries
, i
;
4578 struct samr_SamArray
*groups
= NULL
;
4579 NTSTATUS result
, status
;
4580 struct policy_handle domain_pol
;
4581 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4583 /* Get domain policy handle */
4585 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
4587 MAXIMUM_ALLOWED_ACCESS
,
4588 discard_const_p(struct dom_sid2
, domain_sid
),
4591 if (!NT_STATUS_IS_OK(status
)) {
4594 if (!NT_STATUS_IS_OK(result
)) {
4602 status
= dcerpc_samr_EnumDomainAliases(b
, mem_ctx
,
4609 if (!NT_STATUS_IS_OK(status
)) {
4612 for (i
= 0; i
< num_entries
; i
++) {
4614 struct policy_handle alias_pol
;
4615 struct full_alias alias
;
4616 struct lsa_SidArray sid_array
;
4620 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
4622 MAXIMUM_ALLOWED_ACCESS
,
4623 groups
->entries
[i
].idx
,
4626 if (!NT_STATUS_IS_OK(status
)) {
4629 if (!NT_STATUS_IS_OK(_result
)) {
4634 status
= dcerpc_samr_GetMembersInAlias(b
, mem_ctx
,
4638 if (!NT_STATUS_IS_OK(status
)) {
4641 if (!NT_STATUS_IS_OK(_result
)) {
4646 alias
.num_members
= sid_array
.num_sids
;
4648 status
= dcerpc_samr_Close(b
, mem_ctx
, &alias_pol
, &_result
);
4649 if (!NT_STATUS_IS_OK(status
)) {
4652 if (!NT_STATUS_IS_OK(_result
)) {
4657 alias
.members
= NULL
;
4659 if (alias
.num_members
> 0) {
4660 alias
.members
= SMB_MALLOC_ARRAY(struct dom_sid
, alias
.num_members
);
4662 for (j
= 0; j
< alias
.num_members
; j
++)
4663 sid_copy(&alias
.members
[j
],
4664 sid_array
.sids
[j
].sid
);
4667 sid_compose(&alias
.sid
, domain_sid
,
4668 groups
->entries
[i
].idx
);
4672 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
4674 status
= NT_STATUS_OK
;
4677 dcerpc_samr_Close(b
, mem_ctx
, &domain_pol
, &result
);
4683 * Dump server_aliases as names for debugging purposes.
4686 static NTSTATUS
rpc_aliaslist_dump(struct net_context
*c
,
4687 const struct dom_sid
*domain_sid
,
4688 const char *domain_name
,
4689 struct cli_state
*cli
,
4690 struct rpc_pipe_client
*pipe_hnd
,
4691 TALLOC_CTX
*mem_ctx
,
4697 struct policy_handle lsa_pol
;
4698 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4700 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
4701 SEC_FLAG_MAXIMUM_ALLOWED
,
4703 if (!NT_STATUS_IS_OK(result
))
4706 for (i
=0; i
<num_server_aliases
; i
++) {
4709 enum lsa_SidType
*types
;
4712 struct full_alias
*alias
= &server_aliases
[i
];
4714 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
4716 &domains
, &names
, &types
);
4717 if (!NT_STATUS_IS_OK(result
))
4720 DEBUG(1, ("%s\\%s %d: ", domains
[0], names
[0], types
[0]));
4722 if (alias
->num_members
== 0) {
4727 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
,
4730 &domains
, &names
, &types
);
4732 if (!NT_STATUS_IS_OK(result
) &&
4733 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
4736 for (j
=0; j
<alias
->num_members
; j
++)
4737 DEBUG(1, ("%s\\%s (%d); ",
4738 domains
[j
] ? domains
[j
] : "*unknown*",
4739 names
[j
] ? names
[j
] : "*unknown*",types
[j
]));
4743 dcerpc_lsa_Close(b
, mem_ctx
, &lsa_pol
, &result
);
4745 return NT_STATUS_OK
;
4749 * Fetch a list of all server aliases and their members into
4753 static NTSTATUS
rpc_aliaslist_internals(struct net_context
*c
,
4754 const struct dom_sid
*domain_sid
,
4755 const char *domain_name
,
4756 struct cli_state
*cli
,
4757 struct rpc_pipe_client
*pipe_hnd
,
4758 TALLOC_CTX
*mem_ctx
,
4762 NTSTATUS result
, status
;
4763 struct policy_handle connect_pol
;
4764 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
4766 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
4768 MAXIMUM_ALLOWED_ACCESS
,
4771 if (!NT_STATUS_IS_OK(status
)) {
4774 if (!NT_STATUS_IS_OK(result
)) {
4779 status
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4780 &global_sid_Builtin
);
4781 if (!NT_STATUS_IS_OK(status
)) {
4785 status
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4788 dcerpc_samr_Close(b
, mem_ctx
, &connect_pol
, &result
);
4793 static void init_user_token(struct security_token
*token
, struct dom_sid
*user_sid
)
4795 token
->num_sids
= 4;
4797 if (!(token
->sids
= SMB_MALLOC_ARRAY(struct dom_sid
, 4))) {
4798 d_fprintf(stderr
, "malloc %s\n",_("failed"));
4799 token
->num_sids
= 0;
4803 token
->sids
[0] = *user_sid
;
4804 sid_copy(&token
->sids
[1], &global_sid_World
);
4805 sid_copy(&token
->sids
[2], &global_sid_Network
);
4806 sid_copy(&token
->sids
[3], &global_sid_Authenticated_Users
);
4809 static void free_user_token(struct security_token
*token
)
4811 SAFE_FREE(token
->sids
);
4814 static void add_sid_to_token(struct security_token
*token
, struct dom_sid
*sid
)
4816 if (security_token_has_sid(token
, sid
))
4819 token
->sids
= SMB_REALLOC_ARRAY(token
->sids
, struct dom_sid
, token
->num_sids
+1);
4824 sid_copy(&token
->sids
[token
->num_sids
], sid
);
4826 token
->num_sids
+= 1;
4831 struct security_token token
;
4834 static void dump_user_token(struct user_token
*token
)
4838 d_printf("%s\n", token
->name
);
4840 for (i
=0; i
<token
->token
.num_sids
; i
++) {
4841 d_printf(" %s\n", sid_string_tos(&token
->token
.sids
[i
]));
4845 static bool is_alias_member(struct dom_sid
*sid
, struct full_alias
*alias
)
4849 for (i
=0; i
<alias
->num_members
; i
++) {
4850 if (dom_sid_compare(sid
, &alias
->members
[i
]) == 0)
4857 static void collect_sid_memberships(struct security_token
*token
, struct dom_sid sid
)
4861 for (i
=0; i
<num_server_aliases
; i
++) {
4862 if (is_alias_member(&sid
, &server_aliases
[i
]))
4863 add_sid_to_token(token
, &server_aliases
[i
].sid
);
4868 * We got a user token with all the SIDs we can know about without asking the
4869 * server directly. These are the user and domain group sids. All of these can
4870 * be members of aliases. So scan the list of aliases for each of the SIDs and
4871 * add them to the token.
4874 static void collect_alias_memberships(struct security_token
*token
)
4876 int num_global_sids
= token
->num_sids
;
4879 for (i
=0; i
<num_global_sids
; i
++) {
4880 collect_sid_memberships(token
, token
->sids
[i
]);
4884 static bool get_user_sids(const char *domain
, const char *user
, struct security_token
*token
)
4886 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4887 enum wbcSidType type
;
4889 struct wbcDomainSid wsid
;
4890 char sid_str
[WBC_SID_STRING_BUFLEN
];
4891 struct dom_sid user_sid
;
4892 uint32_t num_groups
;
4893 gid_t
*groups
= NULL
;
4896 fstr_sprintf(full_name
, "%s%c%s",
4897 domain
, *lp_winbind_separator(), user
);
4899 /* First let's find out the user sid */
4901 wbc_status
= wbcLookupName(domain
, user
, &wsid
, &type
);
4903 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4904 DEBUG(1, ("winbind could not find %s: %s\n",
4905 full_name
, wbcErrorString(wbc_status
)));
4909 wbcSidToStringBuf(&wsid
, sid_str
, sizeof(sid_str
));
4911 if (type
!= WBC_SID_NAME_USER
) {
4912 DEBUG(1, ("%s is not a user\n", full_name
));
4916 if (!string_to_sid(&user_sid
, sid_str
)) {
4917 DEBUG(1,("Could not convert sid %s from string\n", sid_str
));
4921 init_user_token(token
, &user_sid
);
4923 /* And now the groups winbind knows about */
4925 wbc_status
= wbcGetGroups(full_name
, &num_groups
, &groups
);
4926 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4927 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4928 full_name
, wbcErrorString(wbc_status
)));
4932 for (i
= 0; i
< num_groups
; i
++) {
4933 gid_t gid
= groups
[i
];
4937 wbc_status
= wbcGidToSid(gid
, &wsid
);
4938 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4939 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4940 (unsigned int)gid
, wbcErrorString(wbc_status
)));
4941 wbcFreeMemory(groups
);
4945 wbcSidToStringBuf(&wsid
, sid_str
, sizeof(sid_str
));
4947 DEBUG(3, (" %s\n", sid_str
));
4949 ok
= string_to_sid(&sid
, sid_str
);
4951 DEBUG(1, ("Failed to convert string to SID\n"));
4952 wbcFreeMemory(groups
);
4955 add_sid_to_token(token
, &sid
);
4957 wbcFreeMemory(groups
);
4963 * Get a list of all user tokens we want to look at
4966 static bool get_user_tokens(struct net_context
*c
, int *num_tokens
,
4967 struct user_token
**user_tokens
)
4969 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4970 uint32_t i
, num_users
;
4972 struct user_token
*result
;
4973 TALLOC_CTX
*frame
= NULL
;
4975 if (lp_winbind_use_default_domain() &&
4976 (c
->opt_target_workgroup
== NULL
)) {
4977 d_fprintf(stderr
, _("winbind use default domain = yes set, "
4978 "please specify a workgroup\n"));
4982 /* Send request to winbind daemon */
4984 wbc_status
= wbcListUsers(NULL
, &num_users
, &users
);
4985 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4986 DEBUG(1, (_("winbind could not list users: %s\n"),
4987 wbcErrorString(wbc_status
)));
4991 result
= SMB_MALLOC_ARRAY(struct user_token
, num_users
);
4993 if (result
== NULL
) {
4994 DEBUG(1, ("Could not malloc sid array\n"));
4995 wbcFreeMemory(users
);
4999 frame
= talloc_stackframe();
5000 for (i
=0; i
< num_users
; i
++) {
5001 fstring domain
, user
;
5004 fstrcpy(result
[i
].name
, users
[i
]);
5006 p
= strchr(users
[i
], *lp_winbind_separator());
5008 DEBUG(3, ("%s\n", users
[i
]));
5011 fstrcpy(domain
, c
->opt_target_workgroup
);
5012 fstrcpy(user
, users
[i
]);
5015 fstrcpy(domain
, users
[i
]);
5016 if (!strupper_m(domain
)) {
5017 DEBUG(1, ("strupper_m %s failed\n", domain
));
5018 wbcFreeMemory(users
);
5024 get_user_sids(domain
, user
, &(result
[i
].token
));
5027 wbcFreeMemory(users
);
5029 *num_tokens
= num_users
;
5030 *user_tokens
= result
;
5035 static bool get_user_tokens_from_file(FILE *f
,
5037 struct user_token
**tokens
)
5039 struct user_token
*token
= NULL
;
5044 if (fgets(line
, sizeof(line
)-1, f
) == NULL
) {
5048 if ((strlen(line
) > 0) && (line
[strlen(line
)-1] == '\n')) {
5049 line
[strlen(line
)-1] = '\0';
5052 if (line
[0] == ' ') {
5056 if(!string_to_sid(&sid
, &line
[1])) {
5057 DEBUG(1,("get_user_tokens_from_file: Could "
5058 "not convert sid %s \n",&line
[1]));
5062 if (token
== NULL
) {
5063 DEBUG(0, ("File does not begin with username"));
5067 add_sid_to_token(&token
->token
, &sid
);
5071 /* And a new user... */
5074 *tokens
= SMB_REALLOC_ARRAY(*tokens
, struct user_token
, *num_tokens
);
5075 if (*tokens
== NULL
) {
5076 DEBUG(0, ("Could not realloc tokens\n"));
5080 token
= &((*tokens
)[*num_tokens
-1]);
5082 if (strlcpy(token
->name
, line
, sizeof(token
->name
)) >= sizeof(token
->name
)) {
5085 token
->token
.num_sids
= 0;
5086 token
->token
.sids
= NULL
;
5095 * Show the list of all users that have access to a share
5098 static void show_userlist(struct rpc_pipe_client
*pipe_hnd
,
5099 struct cli_state
*cli
,
5100 TALLOC_CTX
*mem_ctx
,
5101 const char *netname
,
5103 struct user_token
*tokens
)
5106 struct security_descriptor
*share_sd
= NULL
;
5107 struct security_descriptor
*root_sd
= NULL
;
5109 union srvsvc_NetShareInfo info
;
5112 struct smbXcli_tcon
*orig_tcon
= NULL
;
5113 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5115 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
5122 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
5123 DEBUG(1, ("Could not query secdesc for share %s\n",
5128 share_sd
= info
.info502
->sd_buf
.sd
;
5129 if (share_sd
== NULL
) {
5130 DEBUG(1, ("Got no secdesc for share %s\n",
5134 if (cli_state_has_tcon(cli
)) {
5135 orig_tcon
= cli_state_save_tcon(cli
);
5136 if (orig_tcon
== NULL
) {
5141 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, netname
, "A:", NULL
))) {
5142 cli_state_restore_tcon(cli
, orig_tcon
);
5146 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, "\\", 0, READ_CONTROL_ACCESS
, 0,
5147 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5148 FILE_OPEN
, 0x0, 0x0, &fnum
, NULL
))) {
5149 cli_query_secdesc(cli
, fnum
, mem_ctx
, &root_sd
);
5152 for (i
=0; i
<num_tokens
; i
++) {
5153 uint32_t acc_granted
;
5155 if (share_sd
!= NULL
) {
5156 status
= se_access_check(share_sd
, &tokens
[i
].token
,
5159 if (!NT_STATUS_IS_OK(status
)) {
5160 DEBUG(1, ("Could not check share_sd for "
5167 if (root_sd
== NULL
) {
5168 d_printf(" %s\n", tokens
[i
].name
);
5172 status
= se_access_check(root_sd
, &tokens
[i
].token
,
5174 if (!NT_STATUS_IS_OK(status
)) {
5175 DEBUG(1, ("Could not check root_sd for user %s\n",
5179 d_printf(" %s\n", tokens
[i
].name
);
5182 if (fnum
!= (uint16_t)-1)
5183 cli_close(cli
, fnum
);
5185 cli_state_restore_tcon(cli
, orig_tcon
);
5191 * List shares on a remote RPC server, including the security descriptors.
5193 * All parameters are provided by the run_rpc_command function, except for
5194 * argc, argv which are passed through.
5196 * @param domain_sid The domain sid acquired from the remote server.
5197 * @param cli A cli_state connected to the server.
5198 * @param mem_ctx Talloc context, destroyed on completion of the function.
5199 * @param argc Standard main() style argc.
5200 * @param argv Standard main() style argv. Initial components are already
5203 * @return Normal NTSTATUS return.
5206 static NTSTATUS
rpc_share_allowedusers_internals(struct net_context
*c
,
5207 const struct dom_sid
*domain_sid
,
5208 const char *domain_name
,
5209 struct cli_state
*cli
,
5210 struct rpc_pipe_client
*pipe_hnd
,
5211 TALLOC_CTX
*mem_ctx
,
5217 NTSTATUS nt_status
= NT_STATUS_OK
;
5218 uint32_t total_entries
= 0;
5219 uint32_t resume_handle
= 0;
5220 uint32_t preferred_len
= 0xffffffff;
5222 struct dcerpc_binding_handle
*b
= NULL
;
5223 struct srvsvc_NetShareInfoCtr info_ctr
;
5224 struct srvsvc_NetShareCtr1 ctr1
;
5227 struct user_token
*tokens
= NULL
;
5233 f
= fopen(argv
[0], "r");
5237 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno
)));
5238 return NT_STATUS_UNSUCCESSFUL
;
5241 r
= get_user_tokens_from_file(f
, &num_tokens
, &tokens
);
5247 DEBUG(0, ("Could not read users from file\n"));
5248 return NT_STATUS_UNSUCCESSFUL
;
5251 for (i
=0; i
<num_tokens
; i
++)
5252 collect_alias_memberships(&tokens
[i
].token
);
5254 ZERO_STRUCT(info_ctr
);
5258 info_ctr
.ctr
.ctr1
= &ctr1
;
5260 b
= pipe_hnd
->binding_handle
;
5262 /* Issue the NetShareEnum RPC call and retrieve the response */
5263 nt_status
= dcerpc_srvsvc_NetShareEnumAll(b
,
5272 /* Was it successful? */
5273 if (!NT_STATUS_IS_OK(nt_status
)) {
5274 /* Nope. Go clean up. */
5278 if (!W_ERROR_IS_OK(result
)) {
5279 /* Nope. Go clean up. */
5280 nt_status
= werror_to_ntstatus(result
);
5284 if (total_entries
== 0) {
5288 /* For each returned entry... */
5289 for (i
= 0; i
< info_ctr
.ctr
.ctr1
->count
; i
++) {
5290 const char *netname
= info_ctr
.ctr
.ctr1
->array
[i
].name
;
5292 if (info_ctr
.ctr
.ctr1
->array
[i
].type
!= STYPE_DISKTREE
) {
5296 d_printf("%s\n", netname
);
5298 show_userlist(pipe_hnd
, cli
, mem_ctx
, netname
,
5299 num_tokens
, tokens
);
5302 for (i
=0; i
<num_tokens
; i
++) {
5303 free_user_token(&tokens
[i
].token
);
5306 TALLOC_FREE(server_aliases
);
5311 static int rpc_share_allowedusers(struct net_context
*c
, int argc
,
5316 if (c
->display_usage
) {
5318 "net rpc share allowedusers\n"
5321 _("List allowed users"));
5325 result
= run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
5326 rpc_aliaslist_internals
,
5331 result
= run_rpc_command(c
, NULL
, &ndr_table_lsarpc
, 0,
5337 return run_rpc_command(c
, NULL
, &ndr_table_srvsvc
, 0,
5338 rpc_share_allowedusers_internals
,
5342 int net_usersidlist(struct net_context
*c
, int argc
, const char **argv
)
5345 struct user_token
*tokens
= NULL
;
5349 net_usersidlist_usage(c
, argc
, argv
);
5353 if (!get_user_tokens(c
, &num_tokens
, &tokens
)) {
5354 DEBUG(0, ("Could not get the user/sid list\n"));
5358 for (i
=0; i
<num_tokens
; i
++) {
5359 dump_user_token(&tokens
[i
]);
5360 free_user_token(&tokens
[i
].token
);
5367 int net_usersidlist_usage(struct net_context
*c
, int argc
, const char **argv
)
5369 d_printf(_("net usersidlist\n"
5370 "\tprints out a list of all users the running winbind knows\n"
5371 "\tabout, together with all their SIDs. This is used as\n"
5372 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5374 net_common_flags_usage(c
, argc
, argv
);
5379 * 'net rpc share' entrypoint.
5380 * @param argc Standard main() style argc.
5381 * @param argv Standard main() style argv. Initial components are already
5385 int net_rpc_share(struct net_context
*c
, int argc
, const char **argv
)
5387 NET_API_STATUS status
;
5389 struct functable func
[] = {
5395 N_("net rpc share add\n"
5403 N_("net rpc share delete\n"
5408 rpc_share_allowedusers
,
5410 N_("Modify allowed users"),
5411 N_("net rpc share allowedusers\n"
5412 " Modify allowed users")
5418 N_("Migrate share to local server"),
5419 N_("net rpc share migrate\n"
5420 " Migrate share to local server")
5427 N_("net rpc share list\n"
5430 {NULL
, NULL
, 0, NULL
, NULL
}
5433 status
= libnetapi_net_init(&c
->netapi_ctx
);
5437 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
5438 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
5439 if (c
->opt_kerberos
) {
5440 libnetapi_set_use_kerberos(c
->netapi_ctx
);
5444 if (c
->display_usage
) {
5449 " Alias for net rpc share list\n"));
5450 net_display_usage_from_functable(func
);
5454 return rpc_share_list(c
, argc
, argv
);
5457 return net_run_function(c
, argc
, argv
, "net rpc share", func
);
5460 static NTSTATUS
rpc_sh_share_list(struct net_context
*c
,
5461 TALLOC_CTX
*mem_ctx
,
5462 struct rpc_sh_ctx
*ctx
,
5463 struct rpc_pipe_client
*pipe_hnd
,
5464 int argc
, const char **argv
)
5467 return werror_to_ntstatus(W_ERROR(rpc_share_list(c
, argc
, argv
)));
5470 static NTSTATUS
rpc_sh_share_add(struct net_context
*c
,
5471 TALLOC_CTX
*mem_ctx
,
5472 struct rpc_sh_ctx
*ctx
,
5473 struct rpc_pipe_client
*pipe_hnd
,
5474 int argc
, const char **argv
)
5476 NET_API_STATUS status
;
5477 uint32_t parm_err
= 0;
5478 struct SHARE_INFO_2 i2
;
5480 if ((argc
< 2) || (argc
> 3)) {
5481 d_fprintf(stderr
, _("Usage: %s <share> <path> [comment]\n"),
5483 return NT_STATUS_INVALID_PARAMETER
;
5486 i2
.shi2_netname
= argv
[0];
5487 i2
.shi2_type
= STYPE_DISKTREE
;
5488 i2
.shi2_remark
= (argc
== 3) ? argv
[2] : "";
5489 i2
.shi2_permissions
= 0;
5490 i2
.shi2_max_uses
= 0;
5491 i2
.shi2_current_uses
= 0;
5492 i2
.shi2_path
= argv
[1];
5493 i2
.shi2_passwd
= NULL
;
5495 status
= NetShareAdd(pipe_hnd
->desthost
,
5500 return werror_to_ntstatus(W_ERROR(status
));
5503 static NTSTATUS
rpc_sh_share_delete(struct net_context
*c
,
5504 TALLOC_CTX
*mem_ctx
,
5505 struct rpc_sh_ctx
*ctx
,
5506 struct rpc_pipe_client
*pipe_hnd
,
5507 int argc
, const char **argv
)
5510 d_fprintf(stderr
, "%s %s <share>\n", _("Usage:"), ctx
->whoami
);
5511 return NT_STATUS_INVALID_PARAMETER
;
5514 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd
->desthost
, argv
[0], 0)));
5517 static NTSTATUS
rpc_sh_share_info(struct net_context
*c
,
5518 TALLOC_CTX
*mem_ctx
,
5519 struct rpc_sh_ctx
*ctx
,
5520 struct rpc_pipe_client
*pipe_hnd
,
5521 int argc
, const char **argv
)
5523 union srvsvc_NetShareInfo info
;
5526 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5529 d_fprintf(stderr
, "%s %s <share>\n", _("Usage:"), ctx
->whoami
);
5530 return NT_STATUS_INVALID_PARAMETER
;
5533 status
= dcerpc_srvsvc_NetShareGetInfo(b
, mem_ctx
,
5539 if (!NT_STATUS_IS_OK(status
)) {
5540 result
= ntstatus_to_werror(status
);
5543 if (!W_ERROR_IS_OK(result
)) {
5547 d_printf(_("Name: %s\n"), info
.info2
->name
);
5548 d_printf(_("Comment: %s\n"), info
.info2
->comment
);
5549 d_printf(_("Path: %s\n"), info
.info2
->path
);
5550 d_printf(_("Password: %s\n"), info
.info2
->password
);
5553 return werror_to_ntstatus(result
);
5556 struct rpc_sh_cmd
*net_rpc_share_cmds(struct net_context
*c
, TALLOC_CTX
*mem_ctx
,
5557 struct rpc_sh_ctx
*ctx
)
5559 static struct rpc_sh_cmd cmds
[] = {
5561 { "list", NULL
, &ndr_table_srvsvc
, rpc_sh_share_list
,
5562 N_("List available shares") },
5564 { "add", NULL
, &ndr_table_srvsvc
, rpc_sh_share_add
,
5565 N_("Add a share") },
5567 { "delete", NULL
, &ndr_table_srvsvc
, rpc_sh_share_delete
,
5568 N_("Delete a share") },
5570 { "info", NULL
, &ndr_table_srvsvc
, rpc_sh_share_info
,
5571 N_("Get information about a share") },
5573 { NULL
, NULL
, 0, NULL
, NULL
}
5579 /****************************************************************************/
5581 static int rpc_file_usage(struct net_context
*c
, int argc
, const char **argv
)
5583 return net_file_usage(c
, argc
, argv
);
5587 * Close a file on a remote RPC server.
5589 * @param argc Standard main() style argc.
5590 * @param argv Standard main() style argv. Initial components are already
5593 * @return A shell status integer (0 for success).
5595 static int rpc_file_close(struct net_context
*c
, int argc
, const char **argv
)
5597 if (argc
< 1 || c
->display_usage
) {
5598 return rpc_file_usage(c
, argc
, argv
);
5601 return NetFileClose(c
->opt_host
, atoi(argv
[0]));
5605 * Formatted print of open file info
5607 * @param r struct FILE_INFO_3 contents
5610 static void display_file_info_3(struct FILE_INFO_3
*r
)
5612 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5613 r
->fi3_id
, r
->fi3_username
, r
->fi3_permissions
,
5614 r
->fi3_num_locks
, r
->fi3_pathname
);
5618 * List files for a user on a remote RPC server.
5620 * @param argc Standard main() style argc.
5621 * @param argv Standard main() style argv. Initial components are already
5624 * @return A shell status integer (0 for success)..
5627 static int rpc_file_user(struct net_context
*c
, int argc
, const char **argv
)
5629 NET_API_STATUS status
;
5630 uint32_t preferred_len
= 0xffffffff, i
;
5631 char *username
=NULL
;
5632 uint32_t total_entries
= 0;
5633 uint32_t entries_read
= 0;
5634 uint32_t resume_handle
= 0;
5635 struct FILE_INFO_3
*i3
= NULL
;
5637 if (c
->display_usage
) {
5638 return rpc_file_usage(c
, argc
, argv
);
5641 /* if argc > 0, must be user command */
5643 username
= smb_xstrdup(argv
[0]);
5646 status
= NetFileEnum(c
->opt_host
,
5650 (uint8_t **)(void *)&i3
,
5660 /* Display results */
5663 "\nEnumerating open files on remote server:\n\n"
5664 "\nFileId Opened by Perms Locks Path"
5665 "\n------ --------- ----- ----- ---- \n"));
5666 for (i
= 0; i
< entries_read
; i
++) {
5667 display_file_info_3(&i3
[i
]);
5670 SAFE_FREE(username
);
5675 * 'net rpc file' entrypoint.
5676 * @param argc Standard main() style argc.
5677 * @param argv Standard main() style argv. Initial components are already
5681 int net_rpc_file(struct net_context
*c
, int argc
, const char **argv
)
5683 NET_API_STATUS status
;
5685 struct functable func
[] = {
5690 N_("Close opened file"),
5691 N_("net rpc file close\n"
5692 " Close opened file")
5698 N_("List files opened by user"),
5699 N_("net rpc file user\n"
5700 " List files opened by user")
5707 N_("Display information about opened file"),
5708 N_("net rpc file info\n"
5709 " Display information about opened file")
5712 {NULL
, NULL
, 0, NULL
, NULL
}
5715 status
= libnetapi_net_init(&c
->netapi_ctx
);
5719 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
5720 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
5721 if (c
->opt_kerberos
) {
5722 libnetapi_set_use_kerberos(c
->netapi_ctx
);
5726 if (c
->display_usage
) {
5727 d_printf(_("Usage:\n"));
5728 d_printf(_("net rpc file\n"
5729 " List opened files\n"));
5730 net_display_usage_from_functable(func
);
5734 return rpc_file_user(c
, argc
, argv
);
5737 return net_run_function(c
, argc
, argv
, "net rpc file", func
);
5741 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5743 * All parameters are provided by the run_rpc_command function, except for
5744 * argc, argv which are passed through.
5746 * @param c A net_context structure.
5747 * @param domain_sid The domain sid acquired from the remote server.
5748 * @param cli A cli_state connected to the server.
5749 * @param mem_ctx Talloc context, destroyed on completion of the function.
5750 * @param argc Standard main() style argc.
5751 * @param argv Standard main() style argv. Initial components are already
5754 * @return Normal NTSTATUS return.
5757 static NTSTATUS
rpc_shutdown_abort_internals(struct net_context
*c
,
5758 const struct dom_sid
*domain_sid
,
5759 const char *domain_name
,
5760 struct cli_state
*cli
,
5761 struct rpc_pipe_client
*pipe_hnd
,
5762 TALLOC_CTX
*mem_ctx
,
5766 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5768 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5770 status
= dcerpc_initshutdown_Abort(b
, mem_ctx
, NULL
, &result
);
5771 if (!NT_STATUS_IS_OK(status
)) {
5774 if (W_ERROR_IS_OK(result
)) {
5775 d_printf(_("\nShutdown successfully aborted\n"));
5776 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5778 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5780 return werror_to_ntstatus(result
);
5784 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5786 * All parameters are provided by the run_rpc_command function, except for
5787 * argc, argv which are passed through.
5789 * @param c A net_context structure.
5790 * @param domain_sid The domain sid acquired from the remote server.
5791 * @param cli A cli_state connected to the server.
5792 * @param mem_ctx Talloc context, destroyed on completion of the function.
5793 * @param argc Standard main() style argc.
5794 * @param argv Standard main() style argv. Initial components are already
5797 * @return Normal NTSTATUS return.
5800 static NTSTATUS
rpc_reg_shutdown_abort_internals(struct net_context
*c
,
5801 const struct dom_sid
*domain_sid
,
5802 const char *domain_name
,
5803 struct cli_state
*cli
,
5804 struct rpc_pipe_client
*pipe_hnd
,
5805 TALLOC_CTX
*mem_ctx
,
5809 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5811 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5813 result
= dcerpc_winreg_AbortSystemShutdown(b
, mem_ctx
, NULL
, &werr
);
5815 if (!NT_STATUS_IS_OK(result
)) {
5816 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5819 if (W_ERROR_IS_OK(werr
)) {
5820 d_printf(_("\nShutdown successfully aborted\n"));
5821 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5823 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5825 return werror_to_ntstatus(werr
);
5829 * ABORT the shutdown of a remote RPC server.
5831 * @param argc Standard main() style argc.
5832 * @param argv Standard main() style argv. Initial components are already
5835 * @return A shell status integer (0 for success).
5838 static int rpc_shutdown_abort(struct net_context
*c
, int argc
,
5843 if (c
->display_usage
) {
5845 "net rpc abortshutdown\n"
5848 _("Abort a scheduled shutdown"));
5852 rc
= run_rpc_command(c
, NULL
, &ndr_table_initshutdown
, 0,
5853 rpc_shutdown_abort_internals
, argc
, argv
);
5858 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5860 return run_rpc_command(c
, NULL
, &ndr_table_winreg
, 0,
5861 rpc_reg_shutdown_abort_internals
,
5866 * Shut down a remote RPC Server via initshutdown pipe.
5868 * All parameters are provided by the run_rpc_command function, except for
5869 * argc, argv which are passed through.
5871 * @param c A net_context structure.
5872 * @param domain_sid The domain sid acquired from the remote server.
5873 * @param cli A cli_state connected to the server.
5874 * @param mem_ctx Talloc context, destroyed on completion of the function.
5875 * @param argc Standard main() style argc.
5876 * @param argv Standard main() style argv. Initial components are already
5879 * @return Normal NTSTATUS return.
5882 NTSTATUS
rpc_init_shutdown_internals(struct net_context
*c
,
5883 const struct dom_sid
*domain_sid
,
5884 const char *domain_name
,
5885 struct cli_state
*cli
,
5886 struct rpc_pipe_client
*pipe_hnd
,
5887 TALLOC_CTX
*mem_ctx
,
5891 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
5893 const char *msg
= N_("This machine will be shutdown shortly");
5894 uint32_t timeout
= 20;
5895 struct lsa_StringLarge msg_string
;
5896 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5898 if (c
->opt_comment
) {
5899 msg
= c
->opt_comment
;
5901 if (c
->opt_timeout
) {
5902 timeout
= c
->opt_timeout
;
5905 msg_string
.string
= msg
;
5907 /* create an entry */
5908 status
= dcerpc_initshutdown_Init(b
, mem_ctx
, NULL
,
5909 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5911 if (!NT_STATUS_IS_OK(status
)) {
5914 if (W_ERROR_IS_OK(result
)) {
5915 d_printf(_("\nShutdown of remote machine succeeded\n"));
5916 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5918 DEBUG(1,("Shutdown of remote machine failed!\n"));
5920 return werror_to_ntstatus(result
);
5924 * Shut down a remote RPC Server via winreg pipe.
5926 * All parameters are provided by the run_rpc_command function, except for
5927 * argc, argv which are passed through.
5929 * @param c A net_context structure.
5930 * @param domain_sid The domain sid acquired from the remote server.
5931 * @param cli A cli_state connected to the server.
5932 * @param mem_ctx Talloc context, destroyed on completion of the function.
5933 * @param argc Standard main() style argc.
5934 * @param argv Standard main() style argv. Initial components are already
5937 * @return Normal NTSTATUS return.
5940 NTSTATUS
rpc_reg_shutdown_internals(struct net_context
*c
,
5941 const struct dom_sid
*domain_sid
,
5942 const char *domain_name
,
5943 struct cli_state
*cli
,
5944 struct rpc_pipe_client
*pipe_hnd
,
5945 TALLOC_CTX
*mem_ctx
,
5949 const char *msg
= N_("This machine will be shutdown shortly");
5950 uint32_t timeout
= 20;
5951 struct lsa_StringLarge msg_string
;
5954 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
5956 if (c
->opt_comment
) {
5957 msg
= c
->opt_comment
;
5959 msg_string
.string
= msg
;
5961 if (c
->opt_timeout
) {
5962 timeout
= c
->opt_timeout
;
5965 /* create an entry */
5966 result
= dcerpc_winreg_InitiateSystemShutdown(b
, mem_ctx
, NULL
,
5967 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5969 if (!NT_STATUS_IS_OK(result
)) {
5970 d_fprintf(stderr
, "\nShutdown of remote machine failed\n");
5974 if (W_ERROR_IS_OK(werr
)) {
5975 d_printf(_("\nShutdown of remote machine succeeded\n"));
5977 d_fprintf(stderr
, "\nShutdown of remote machine failed\n");
5978 if ( W_ERROR_EQUAL(werr
, WERR_MACHINE_LOCKED
) )
5979 d_fprintf(stderr
, "\nMachine locked, use -f switch to force\n");
5981 d_fprintf(stderr
, "\nresult was: %s\n", win_errstr(werr
));
5984 return werror_to_ntstatus(werr
);
5988 * Shut down a remote RPC server.
5990 * @param argc Standard main() style argc.
5991 * @param argv Standard main() style argv. Initial components are already
5994 * @return A shell status integer (0 for success).
5997 static int rpc_shutdown(struct net_context
*c
, int argc
, const char **argv
)
6001 if (c
->display_usage
) {
6003 "net rpc shutdown\n"
6006 _("Shut down a remote RPC server"));
6010 rc
= run_rpc_command(c
, NULL
, &ndr_table_initshutdown
, 0,
6011 rpc_init_shutdown_internals
, argc
, argv
);
6014 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
6015 rc
= run_rpc_command(c
, NULL
, &ndr_table_winreg
, 0,
6016 rpc_reg_shutdown_internals
, argc
, argv
);
6022 /***************************************************************************
6023 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
6024 ***************************************************************************/
6027 * Add interdomain trust account to the RPC server.
6028 * All parameters (except for argc and argv) are passed by run_rpc_command
6031 * @param c A net_context structure.
6032 * @param domain_sid The domain sid acquired from the server.
6033 * @param cli A cli_state connected to the server.
6034 * @param mem_ctx Talloc context, destroyed on completion of the function.
6035 * @param argc Standard main() style argc.
6036 * @param argv Standard main() style argv. Initial components are already
6039 * @return normal NTSTATUS return code.
6042 static NTSTATUS
rpc_trustdom_add_internals(struct net_context
*c
,
6043 const struct dom_sid
*domain_sid
,
6044 const char *domain_name
,
6045 struct cli_state
*cli
,
6046 struct rpc_pipe_client
*pipe_hnd
,
6047 TALLOC_CTX
*mem_ctx
,
6051 struct policy_handle connect_pol
, domain_pol
, user_pol
;
6052 NTSTATUS status
, result
;
6054 struct lsa_String lsa_acct_name
;
6056 uint32_t acct_flags
=0;
6058 uint32_t access_granted
= 0;
6059 union samr_UserInfo info
;
6060 unsigned int orig_timeout
;
6061 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6062 DATA_BLOB session_key
= data_blob_null
;
6067 _(" net rpc trustdom add <domain_name> "
6068 "<trust password>\n"));
6069 return NT_STATUS_INVALID_PARAMETER
;
6073 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6076 if (asprintf(&acct_name
, "%s$", argv
[0]) < 0) {
6077 return NT_STATUS_NO_MEMORY
;
6080 if (!strupper_m(acct_name
)) {
6081 SAFE_FREE(acct_name
);
6082 return NT_STATUS_INVALID_PARAMETER
;
6085 init_lsa_String(&lsa_acct_name
, acct_name
);
6087 status
= cli_get_session_key(mem_ctx
, pipe_hnd
, &session_key
);
6088 if (!NT_STATUS_IS_OK(status
)) {
6089 DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
6090 nt_errstr(status
)));
6094 /* Get samr policy handle */
6095 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
6097 MAXIMUM_ALLOWED_ACCESS
,
6100 if (!NT_STATUS_IS_OK(status
)) {
6103 if (!NT_STATUS_IS_OK(result
)) {
6108 /* Get domain policy handle */
6109 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
6111 MAXIMUM_ALLOWED_ACCESS
,
6112 discard_const_p(struct dom_sid2
, domain_sid
),
6115 if (!NT_STATUS_IS_OK(status
)) {
6118 if (!NT_STATUS_IS_OK(result
)) {
6123 /* This call can take a long time - allow the server to time out.
6124 * 35 seconds should do it. */
6126 orig_timeout
= rpccli_set_timeout(pipe_hnd
, 35000);
6128 /* Create trusting domain's account */
6129 acb_info
= ACB_NORMAL
;
6130 acct_flags
= SEC_GENERIC_READ
| SEC_GENERIC_WRITE
| SEC_GENERIC_EXECUTE
|
6131 SEC_STD_WRITE_DAC
| SEC_STD_DELETE
|
6132 SAMR_USER_ACCESS_SET_PASSWORD
|
6133 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
6134 SAMR_USER_ACCESS_SET_ATTRIBUTES
;
6136 status
= dcerpc_samr_CreateUser2(b
, mem_ctx
,
6145 if (!NT_STATUS_IS_OK(status
)) {
6148 /* And restore our original timeout. */
6149 rpccli_set_timeout(pipe_hnd
, orig_timeout
);
6151 if (!NT_STATUS_IS_OK(result
)) {
6153 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
6154 acct_name
, nt_errstr(result
));
6159 struct samr_CryptPassword crypt_pwd
;
6161 ZERO_STRUCT(info
.info23
);
6163 init_samr_CryptPassword(argv
[1],
6167 info
.info23
.info
.fields_present
= SAMR_FIELD_ACCT_FLAGS
|
6168 SAMR_FIELD_NT_PASSWORD_PRESENT
;
6169 info
.info23
.info
.acct_flags
= ACB_DOMTRUST
;
6170 info
.info23
.password
= crypt_pwd
;
6172 status
= dcerpc_samr_SetUserInfo2(b
, mem_ctx
,
6177 if (!NT_STATUS_IS_OK(status
)) {
6181 if (!NT_STATUS_IS_OK(result
)) {
6183 DEBUG(0,("Could not set trust account password: %s\n",
6184 nt_errstr(result
)));
6190 SAFE_FREE(acct_name
);
6191 data_blob_clear_free(&session_key
);
6196 * Create interdomain trust account for a remote domain.
6198 * @param argc Standard argc.
6199 * @param argv Standard argv without initial components.
6201 * @return Integer status (0 means success).
6204 static int rpc_trustdom_add(struct net_context
*c
, int argc
, const char **argv
)
6206 if (argc
> 0 && !c
->display_usage
) {
6207 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
6208 rpc_trustdom_add_internals
, argc
, argv
);
6212 _("net rpc trustdom add <domain_name> <trust "
6220 * Remove interdomain trust account from the RPC server.
6221 * All parameters (except for argc and argv) are passed by run_rpc_command
6224 * @param c A net_context structure.
6225 * @param domain_sid The domain sid acquired from the server.
6226 * @param cli A cli_state connected to the server.
6227 * @param mem_ctx Talloc context, destroyed on completion of the function.
6228 * @param argc Standard main() style argc.
6229 * @param argv Standard main() style argv. Initial components are already
6232 * @return normal NTSTATUS return code.
6235 static NTSTATUS
rpc_trustdom_del_internals(struct net_context
*c
,
6236 const struct dom_sid
*domain_sid
,
6237 const char *domain_name
,
6238 struct cli_state
*cli
,
6239 struct rpc_pipe_client
*pipe_hnd
,
6240 TALLOC_CTX
*mem_ctx
,
6244 struct policy_handle connect_pol
, domain_pol
, user_pol
;
6245 NTSTATUS status
, result
;
6247 struct dom_sid trust_acct_sid
;
6248 struct samr_Ids user_rids
, name_types
;
6249 struct lsa_String lsa_acct_name
;
6250 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6255 _(" net rpc trustdom del <domain_name>\n"));
6256 return NT_STATUS_INVALID_PARAMETER
;
6260 * Make valid trusting domain account (ie. uppercased and with '$' appended)
6262 acct_name
= talloc_asprintf(mem_ctx
, "%s$", argv
[0]);
6264 if (acct_name
== NULL
)
6265 return NT_STATUS_NO_MEMORY
;
6267 if (!strupper_m(acct_name
)) {
6268 TALLOC_FREE(acct_name
);
6269 return NT_STATUS_INVALID_PARAMETER
;
6272 /* Get samr policy handle */
6273 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
6275 MAXIMUM_ALLOWED_ACCESS
,
6278 if (!NT_STATUS_IS_OK(status
)) {
6281 if (!NT_STATUS_IS_OK(result
)) {
6286 /* Get domain policy handle */
6287 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
6289 MAXIMUM_ALLOWED_ACCESS
,
6290 discard_const_p(struct dom_sid2
, domain_sid
),
6293 if (!NT_STATUS_IS_OK(status
)) {
6296 if (!NT_STATUS_IS_OK(result
)) {
6301 init_lsa_String(&lsa_acct_name
, acct_name
);
6303 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
6310 if (!NT_STATUS_IS_OK(status
)) {
6311 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6313 acct_name
, nt_errstr(status
));
6316 if (!NT_STATUS_IS_OK(result
)) {
6318 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6320 acct_name
, nt_errstr(result
) );
6323 if (user_rids
.count
!= 1) {
6324 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
6327 if (name_types
.count
!= 1) {
6328 status
= NT_STATUS_INVALID_NETWORK_RESPONSE
;
6332 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
6334 MAXIMUM_ALLOWED_ACCESS
,
6338 if (!NT_STATUS_IS_OK(status
)) {
6339 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6341 acct_name
, nt_errstr(status
) );
6345 if (!NT_STATUS_IS_OK(result
)) {
6347 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6349 acct_name
, nt_errstr(result
) );
6353 /* append the rid to the domain sid */
6354 if (!sid_compose(&trust_acct_sid
, domain_sid
, user_rids
.ids
[0])) {
6358 /* remove the sid */
6360 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, mem_ctx
,
6364 if (!NT_STATUS_IS_OK(status
)) {
6365 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6366 " on user %s failed %s\n"),
6367 acct_name
, nt_errstr(status
));
6370 if (!NT_STATUS_IS_OK(result
)) {
6372 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6373 " on user %s failed %s\n"),
6374 acct_name
, nt_errstr(result
) );
6381 status
= dcerpc_samr_DeleteUser(b
, mem_ctx
,
6384 if (!NT_STATUS_IS_OK(status
)) {
6385 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6387 acct_name
, nt_errstr(status
));
6391 if (!NT_STATUS_IS_OK(result
)) {
6393 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6395 acct_name
, nt_errstr(result
) );
6399 if (!NT_STATUS_IS_OK(result
)) {
6400 d_printf(_("Could not set trust account password: %s\n"),
6410 * Delete interdomain trust account for a remote domain.
6412 * @param argc Standard argc.
6413 * @param argv Standard argv without initial components.
6415 * @return Integer status (0 means success).
6418 static int rpc_trustdom_del(struct net_context
*c
, int argc
, const char **argv
)
6420 if (argc
> 0 && !c
->display_usage
) {
6421 return run_rpc_command(c
, NULL
, &ndr_table_samr
, 0,
6422 rpc_trustdom_del_internals
, argc
, argv
);
6426 _("net rpc trustdom del <domain>\n"));
6431 static NTSTATUS
rpc_trustdom_get_pdc(struct net_context
*c
,
6432 struct cli_state
*cli
,
6433 TALLOC_CTX
*mem_ctx
,
6434 const char *domain_name
)
6436 char *dc_name
= NULL
;
6437 const char *buffer
= NULL
;
6438 struct rpc_pipe_client
*netr
;
6441 struct dcerpc_binding_handle
*b
;
6443 /* Use NetServerEnum2 */
6445 if (cli_get_pdc_name(cli
, domain_name
, &dc_name
)) {
6447 return NT_STATUS_OK
;
6450 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6451 for domain %s\n", domain_name
));
6453 /* Try netr_GetDcName */
6455 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
,
6457 if (!NT_STATUS_IS_OK(status
)) {
6461 b
= netr
->binding_handle
;
6463 status
= dcerpc_netr_GetDcName(b
, mem_ctx
,
6470 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(result
)) {
6474 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6475 for domain %s\n", domain_name
));
6477 if (!NT_STATUS_IS_OK(status
)) {
6481 return werror_to_ntstatus(result
);
6485 * Establish trust relationship to a trusting domain.
6486 * Interdomain account must already be created on remote PDC.
6488 * @param c A net_context structure.
6489 * @param argc Standard argc.
6490 * @param argv Standard argv without initial components.
6492 * @return Integer status (0 means success).
6495 static int rpc_trustdom_establish(struct net_context
*c
, int argc
,
6498 struct cli_state
*cli
= NULL
;
6499 struct sockaddr_storage server_ss
;
6500 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6501 struct policy_handle connect_hnd
;
6502 TALLOC_CTX
*mem_ctx
;
6503 NTSTATUS nt_status
, result
;
6504 struct dom_sid
*domain_sid
;
6509 union lsa_PolicyInformation
*info
= NULL
;
6510 struct dcerpc_binding_handle
*b
;
6513 * Connect to \\server\ipc$ as 'our domain' account with password
6516 if (argc
!= 1 || c
->display_usage
) {
6519 _("net rpc trustdom establish <domain_name>\n"));
6523 domain_name
= smb_xstrdup(argv
[0]);
6524 if (!strupper_m(domain_name
)) {
6525 SAFE_FREE(domain_name
);
6529 /* account name used at first is our domain's name with '$' */
6530 if (asprintf(&acct_name
, "%s$", lp_workgroup()) == -1) {
6533 if (!strupper_m(acct_name
)) {
6534 SAFE_FREE(domain_name
);
6535 SAFE_FREE(acct_name
);
6540 * opt_workgroup will be used by connection functions further,
6541 * hence it should be set to remote domain name instead of ours
6543 if (c
->opt_workgroup
) {
6544 c
->opt_workgroup
= smb_xstrdup(domain_name
);
6547 c
->opt_user_name
= acct_name
;
6549 /* find the domain controller */
6550 if (!net_find_pdc(&server_ss
, pdc_name
, domain_name
)) {
6551 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name
));
6555 /* connect to ipc$ as username/password */
6556 nt_status
= connect_to_ipc(c
, &cli
, &server_ss
, pdc_name
);
6557 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
)) {
6559 /* Is it trusting domain account for sure ? */
6560 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6561 nt_errstr(nt_status
)));
6565 /* store who we connected to */
6567 saf_store( domain_name
, pdc_name
);
6570 * Connect to \\server\ipc$ again (this time anonymously)
6573 nt_status
= connect_to_ipc_anonymous(c
, &cli
, &server_ss
,
6576 if (NT_STATUS_IS_ERR(nt_status
)) {
6577 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6578 domain_name
, nt_errstr(nt_status
)));
6582 if (!(mem_ctx
= talloc_init("establishing trust relationship to "
6583 "domain %s", domain_name
))) {
6584 DEBUG(0, ("talloc_init() failed\n"));
6589 /* Make sure we're talking to a proper server */
6591 nt_status
= rpc_trustdom_get_pdc(c
, cli
, mem_ctx
, domain_name
);
6592 if (!NT_STATUS_IS_OK(nt_status
)) {
6594 talloc_destroy(mem_ctx
);
6599 * Call LsaOpenPolicy and LsaQueryInfo
6602 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
6604 if (!NT_STATUS_IS_OK(nt_status
)) {
6605 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status
) ));
6607 talloc_destroy(mem_ctx
);
6611 b
= pipe_hnd
->binding_handle
;
6613 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true, KEY_QUERY_VALUE
,
6615 if (NT_STATUS_IS_ERR(nt_status
)) {
6616 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6617 nt_errstr(nt_status
)));
6619 talloc_destroy(mem_ctx
);
6623 /* Querying info level 5 */
6625 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
6627 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6630 if (NT_STATUS_IS_ERR(nt_status
)) {
6631 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6632 nt_errstr(nt_status
)));
6634 talloc_destroy(mem_ctx
);
6637 if (NT_STATUS_IS_ERR(result
)) {
6638 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6639 nt_errstr(result
)));
6641 talloc_destroy(mem_ctx
);
6645 domain_sid
= info
->account_domain
.sid
;
6647 /* There should be actually query info level 3 (following nt serv behaviour),
6648 but I still don't know if it's _really_ necessary */
6651 * Store the password in secrets db
6654 if (!pdb_set_trusteddom_pw(domain_name
, c
->opt_password
, domain_sid
)) {
6655 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6657 talloc_destroy(mem_ctx
);
6662 * Close the pipes and clean up
6665 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
6666 if (NT_STATUS_IS_ERR(nt_status
)) {
6667 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6668 nt_errstr(nt_status
)));
6670 talloc_destroy(mem_ctx
);
6676 talloc_destroy(mem_ctx
);
6678 d_printf(_("Trust to domain %s established\n"), domain_name
);
6683 * Revoke trust relationship to the remote domain.
6685 * @param c A net_context structure.
6686 * @param argc Standard argc.
6687 * @param argv Standard argv without initial components.
6689 * @return Integer status (0 means success).
6692 static int rpc_trustdom_revoke(struct net_context
*c
, int argc
,
6698 if (argc
< 1 || c
->display_usage
) {
6701 _("net rpc trustdom revoke <domain_name>\n"
6702 " Revoke trust relationship\n"
6703 " domain_name\tName of domain to revoke trust\n"));
6707 /* generate upper cased domain name */
6708 domain_name
= smb_xstrdup(argv
[0]);
6709 if (!strupper_m(domain_name
)) {
6710 SAFE_FREE(domain_name
);
6714 /* delete password of the trust */
6715 if (!pdb_del_trusteddom_pw(domain_name
)) {
6716 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6723 SAFE_FREE(domain_name
);
6727 static NTSTATUS
rpc_query_domain_sid(struct net_context
*c
,
6728 const struct dom_sid
*domain_sid
,
6729 const char *domain_name
,
6730 struct cli_state
*cli
,
6731 struct rpc_pipe_client
*pipe_hnd
,
6732 TALLOC_CTX
*mem_ctx
,
6737 if (!sid_to_fstring(str_sid
, domain_sid
)) {
6738 return NT_STATUS_UNSUCCESSFUL
;
6740 d_printf("%s\n", str_sid
);
6741 return NT_STATUS_OK
;
6744 static void print_trusted_domain(struct dom_sid
*dom_sid
, const char *trusted_dom_name
)
6748 /* convert sid into ascii string */
6749 sid_to_fstring(ascii_sid
, dom_sid
);
6751 d_printf("%-20s%s\n", trusted_dom_name
, ascii_sid
);
6754 static NTSTATUS
vampire_trusted_domain(struct rpc_pipe_client
*pipe_hnd
,
6755 TALLOC_CTX
*mem_ctx
,
6756 struct policy_handle
*pol
,
6757 struct dom_sid dom_sid
,
6758 const char *trusted_dom_name
)
6760 NTSTATUS nt_status
, result
;
6761 union lsa_TrustedDomainInfo
*info
= NULL
;
6762 char *cleartextpwd
= NULL
;
6763 DATA_BLOB session_key
;
6764 DATA_BLOB data
= data_blob_null
;
6765 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
6767 nt_status
= dcerpc_lsa_QueryTrustedDomainInfoBySid(b
, mem_ctx
,
6770 LSA_TRUSTED_DOMAIN_INFO_PASSWORD
,
6773 if (NT_STATUS_IS_ERR(nt_status
)) {
6774 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6775 nt_errstr(nt_status
)));
6778 if (NT_STATUS_IS_ERR(result
)) {
6780 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6781 nt_errstr(result
)));
6785 data
= data_blob(info
->password
.password
->data
,
6786 info
->password
.password
->length
);
6788 nt_status
= cli_get_session_key(mem_ctx
, pipe_hnd
, &session_key
);
6789 if (!NT_STATUS_IS_OK(nt_status
)) {
6790 DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status
)));
6794 cleartextpwd
= sess_decrypt_string(mem_ctx
, &data
, &session_key
);
6795 data_blob_free(&session_key
);
6797 if (cleartextpwd
== NULL
) {
6798 DEBUG(0,("retrieved NULL password\n"));
6799 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6803 if (!pdb_set_trusteddom_pw(trusted_dom_name
, cleartextpwd
, &dom_sid
)) {
6804 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6805 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6809 #ifdef DEBUG_PASSWORD
6810 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6811 "password: [%s]\n", trusted_dom_name
,
6812 sid_string_dbg(&dom_sid
), cleartextpwd
));
6816 SAFE_FREE(cleartextpwd
);
6817 data_blob_free(&data
);
6822 static int rpc_trustdom_vampire(struct net_context
*c
, int argc
,
6825 /* common variables */
6826 TALLOC_CTX
* mem_ctx
;
6827 struct cli_state
*cli
= NULL
;
6828 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6829 NTSTATUS nt_status
, result
;
6830 const char *domain_name
= NULL
;
6831 struct policy_handle connect_hnd
;
6832 union lsa_PolicyInformation
*info
= NULL
;
6834 /* trusted domains listing variables */
6835 unsigned int enum_ctx
= 0;
6837 struct lsa_DomainList dom_list
;
6839 struct dcerpc_binding_handle
*b
;
6841 if (c
->display_usage
) {
6843 "net rpc trustdom vampire\n"
6846 _("Vampire trust relationship from remote server"));
6851 * Listing trusted domains (stored in secrets.tdb, if local)
6854 mem_ctx
= talloc_init("trust relationships vampire");
6857 * set domain and pdc name to local samba server (default)
6858 * or to remote one given in command line
6861 if (strcasecmp_m(c
->opt_workgroup
, lp_workgroup())) {
6862 domain_name
= c
->opt_workgroup
;
6863 c
->opt_target_workgroup
= c
->opt_workgroup
;
6865 fstrcpy(pdc_name
, lp_netbios_name());
6866 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
6867 c
->opt_target_workgroup
= domain_name
;
6870 /* open \PIPE\lsarpc and open policy handle */
6871 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
6872 if (!NT_STATUS_IS_OK(nt_status
)) {
6873 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6874 nt_errstr(nt_status
)));
6875 talloc_destroy(mem_ctx
);
6879 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
6881 if (!NT_STATUS_IS_OK(nt_status
)) {
6882 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6883 nt_errstr(nt_status
) ));
6885 talloc_destroy(mem_ctx
);
6889 b
= pipe_hnd
->binding_handle
;
6891 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, KEY_QUERY_VALUE
,
6893 if (NT_STATUS_IS_ERR(nt_status
)) {
6894 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6895 nt_errstr(nt_status
)));
6897 talloc_destroy(mem_ctx
);
6901 /* query info level 5 to obtain sid of a domain being queried */
6902 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
6904 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6908 if (NT_STATUS_IS_ERR(nt_status
)) {
6909 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6910 nt_errstr(nt_status
)));
6912 talloc_destroy(mem_ctx
);
6915 if (NT_STATUS_IS_ERR(result
)) {
6916 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6917 nt_errstr(result
)));
6919 talloc_destroy(mem_ctx
);
6924 * Keep calling LsaEnumTrustdom over opened pipe until
6925 * the end of enumeration is reached
6928 d_printf(_("Vampire trusted domains:\n\n"));
6931 nt_status
= dcerpc_lsa_EnumTrustDom(b
, mem_ctx
,
6937 if (NT_STATUS_IS_ERR(nt_status
)) {
6938 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6939 nt_errstr(nt_status
)));
6941 talloc_destroy(mem_ctx
);
6944 if (NT_STATUS_IS_ERR(result
)) {
6946 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6947 nt_errstr(result
)));
6949 talloc_destroy(mem_ctx
);
6954 for (i
= 0; i
< dom_list
.count
; i
++) {
6956 print_trusted_domain(dom_list
.domains
[i
].sid
,
6957 dom_list
.domains
[i
].name
.string
);
6959 nt_status
= vampire_trusted_domain(pipe_hnd
, mem_ctx
, &connect_hnd
,
6960 *dom_list
.domains
[i
].sid
,
6961 dom_list
.domains
[i
].name
.string
);
6962 if (!NT_STATUS_IS_OK(nt_status
)) {
6964 talloc_destroy(mem_ctx
);
6970 * in case of no trusted domains say something rather
6971 * than just display blank line
6973 if (!dom_list
.count
) d_printf(_("none\n"));
6975 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
6977 /* close this connection before doing next one */
6978 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
6979 if (NT_STATUS_IS_ERR(nt_status
)) {
6980 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6981 nt_errstr(nt_status
)));
6983 talloc_destroy(mem_ctx
);
6987 /* close lsarpc pipe and connection to IPC$ */
6990 talloc_destroy(mem_ctx
);
6994 static int rpc_trustdom_list(struct net_context
*c
, int argc
, const char **argv
)
6996 /* common variables */
6997 TALLOC_CTX
* mem_ctx
;
6998 struct cli_state
*cli
= NULL
, *remote_cli
= NULL
;
6999 struct rpc_pipe_client
*pipe_hnd
= NULL
;
7000 NTSTATUS nt_status
, result
;
7001 const char *domain_name
= NULL
;
7002 struct dom_sid
*queried_dom_sid
;
7003 int ascii_dom_name_len
;
7004 struct policy_handle connect_hnd
;
7005 union lsa_PolicyInformation
*info
= NULL
;
7006 struct dcerpc_binding_handle
*b
= NULL
;
7008 /* trusted domains listing variables */
7009 unsigned int num_domains
, enum_ctx
= 0;
7011 struct lsa_DomainList dom_list
;
7015 /* trusting domains listing variables */
7016 struct policy_handle domain_hnd
;
7017 struct samr_SamArray
*trusts
= NULL
;
7019 if (c
->display_usage
) {
7021 "net rpc trustdom list\n"
7024 _("List incoming and outgoing trust relationships"));
7029 * Listing trusted domains (stored in secrets.tdb, if local)
7032 mem_ctx
= talloc_init("trust relationships listing");
7035 * set domain and pdc name to local samba server (default)
7036 * or to remote one given in command line
7039 if (strcasecmp_m(c
->opt_workgroup
, lp_workgroup())) {
7040 domain_name
= c
->opt_workgroup
;
7041 c
->opt_target_workgroup
= c
->opt_workgroup
;
7043 fstrcpy(pdc_name
, lp_netbios_name());
7044 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
7045 c
->opt_target_workgroup
= domain_name
;
7048 /* open \PIPE\lsarpc and open policy handle */
7049 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
7050 if (!NT_STATUS_IS_OK(nt_status
)) {
7051 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
7052 nt_errstr(nt_status
)));
7053 talloc_destroy(mem_ctx
);
7057 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
,
7059 if (!NT_STATUS_IS_OK(nt_status
)) {
7060 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
7061 nt_errstr(nt_status
) ));
7063 talloc_destroy(mem_ctx
);
7067 b
= pipe_hnd
->binding_handle
;
7069 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, KEY_QUERY_VALUE
,
7071 if (NT_STATUS_IS_ERR(nt_status
)) {
7072 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
7073 nt_errstr(nt_status
)));
7075 talloc_destroy(mem_ctx
);
7079 /* query info level 5 to obtain sid of a domain being queried */
7080 nt_status
= dcerpc_lsa_QueryInfoPolicy(b
, mem_ctx
,
7082 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
7086 if (NT_STATUS_IS_ERR(nt_status
)) {
7087 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7088 nt_errstr(nt_status
)));
7090 talloc_destroy(mem_ctx
);
7093 if (NT_STATUS_IS_ERR(result
)) {
7094 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7095 nt_errstr(result
)));
7097 talloc_destroy(mem_ctx
);
7101 queried_dom_sid
= info
->account_domain
.sid
;
7104 * Keep calling LsaEnumTrustdom over opened pipe until
7105 * the end of enumeration is reached
7108 d_printf(_("Trusted domains list:\n\n"));
7110 found_domain
= false;
7113 nt_status
= dcerpc_lsa_EnumTrustDom(b
, mem_ctx
,
7119 if (NT_STATUS_IS_ERR(nt_status
)) {
7120 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7121 nt_errstr(nt_status
)));
7123 talloc_destroy(mem_ctx
);
7126 if (NT_STATUS_IS_ERR(result
)) {
7127 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7128 nt_errstr(result
)));
7130 talloc_destroy(mem_ctx
);
7135 for (i
= 0; i
< dom_list
.count
; i
++) {
7136 print_trusted_domain(dom_list
.domains
[i
].sid
,
7137 dom_list
.domains
[i
].name
.string
);
7138 found_domain
= true;
7142 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
7145 * in case of no trusted domains say something rather
7146 * than just display blank line
7148 if (!found_domain
) {
7149 d_printf(_("none\n"));
7152 /* close this connection before doing next one */
7153 nt_status
= dcerpc_lsa_Close(b
, mem_ctx
, &connect_hnd
, &result
);
7154 if (NT_STATUS_IS_ERR(nt_status
)) {
7155 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7156 nt_errstr(nt_status
)));
7158 talloc_destroy(mem_ctx
);
7162 TALLOC_FREE(pipe_hnd
);
7165 * Listing trusting domains (stored in passdb backend, if local)
7168 d_printf(_("\nTrusting domains list:\n\n"));
7171 * Open \PIPE\samr and get needed policy handles
7173 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_samr
,
7175 if (!NT_STATUS_IS_OK(nt_status
)) {
7176 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status
)));
7178 talloc_destroy(mem_ctx
);
7182 b
= pipe_hnd
->binding_handle
;
7185 nt_status
= dcerpc_samr_Connect2(b
, mem_ctx
,
7187 SAMR_ACCESS_LOOKUP_DOMAIN
,
7190 if (!NT_STATUS_IS_OK(nt_status
)) {
7191 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7192 nt_errstr(nt_status
)));
7194 talloc_destroy(mem_ctx
);
7197 if (!NT_STATUS_IS_OK(result
)) {
7199 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7200 nt_errstr(result
)));
7202 talloc_destroy(mem_ctx
);
7206 /* SamrOpenDomain - we have to open domain policy handle in order to be
7207 able to enumerate accounts*/
7208 nt_status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
7210 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
7214 if (!NT_STATUS_IS_OK(nt_status
)) {
7215 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7216 nt_errstr(nt_status
)));
7218 talloc_destroy(mem_ctx
);
7221 if (!NT_STATUS_IS_OK(result
)) {
7223 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7224 nt_errstr(result
)));
7226 talloc_destroy(mem_ctx
);
7231 * perform actual enumeration
7234 found_domain
= false;
7236 enum_ctx
= 0; /* reset enumeration context from last enumeration */
7239 nt_status
= dcerpc_samr_EnumDomainUsers(b
, mem_ctx
,
7247 if (NT_STATUS_IS_ERR(nt_status
)) {
7248 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7249 nt_errstr(nt_status
)));
7251 talloc_destroy(mem_ctx
);
7254 if (NT_STATUS_IS_ERR(result
)) {
7256 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7257 nt_errstr(result
)));
7259 talloc_destroy(mem_ctx
);
7263 for (i
= 0; i
< num_domains
; i
++) {
7265 char *str
= discard_const_p(char, trusts
->entries
[i
].name
.string
);
7267 found_domain
= true;
7270 * get each single domain's sid (do we _really_ need this ?):
7271 * 1) connect to domain's pdc
7272 * 2) query the pdc for domain's sid
7275 /* get rid of '$' tail */
7276 ascii_dom_name_len
= strlen(str
);
7277 if (ascii_dom_name_len
&& ascii_dom_name_len
< FSTRING_LEN
)
7278 str
[ascii_dom_name_len
- 1] = '\0';
7280 /* set opt_* variables to remote domain */
7281 if (!strupper_m(str
)) {
7283 talloc_destroy(mem_ctx
);
7286 c
->opt_workgroup
= talloc_strdup(mem_ctx
, str
);
7287 c
->opt_target_workgroup
= c
->opt_workgroup
;
7289 d_printf("%-20s", str
);
7291 /* connect to remote domain controller */
7292 nt_status
= net_make_ipc_connection(c
,
7293 NET_FLAGS_PDC
| NET_FLAGS_ANONYMOUS
,
7295 if (NT_STATUS_IS_OK(nt_status
)) {
7296 /* query for domain's sid */
7297 if (run_rpc_command(
7299 &ndr_table_lsarpc
, 0,
7300 rpc_query_domain_sid
, argc
,
7302 d_printf(_("strange - couldn't get domain's sid\n"));
7304 cli_shutdown(remote_cli
);
7307 d_fprintf(stderr
, _("domain controller is not "
7308 "responding: %s\n"),
7309 nt_errstr(nt_status
));
7310 d_printf(_("couldn't get domain's sid\n"));
7314 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
7316 if (!found_domain
) {
7320 /* close opened samr and domain policy handles */
7321 nt_status
= dcerpc_samr_Close(b
, mem_ctx
, &domain_hnd
, &result
);
7322 if (!NT_STATUS_IS_OK(nt_status
)) {
7323 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name
));
7326 nt_status
= dcerpc_samr_Close(b
, mem_ctx
, &connect_hnd
, &result
);
7327 if (!NT_STATUS_IS_OK(nt_status
)) {
7328 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name
));
7331 /* close samr pipe and connection to IPC$ */
7334 talloc_destroy(mem_ctx
);
7339 * Entrypoint for 'net rpc trustdom' code.
7341 * @param argc Standard argc.
7342 * @param argv Standard argv without initial components.
7344 * @return Integer status (0 means success).
7347 static int rpc_trustdom(struct net_context
*c
, int argc
, const char **argv
)
7349 struct functable func
[] = {
7354 N_("Add trusting domain's account"),
7355 N_("net rpc trustdom add\n"
7356 " Add trusting domain's account")
7362 N_("Remove trusting domain's account"),
7363 N_("net rpc trustdom del\n"
7364 " Remove trusting domain's account")
7368 rpc_trustdom_establish
,
7370 N_("Establish outgoing trust relationship"),
7371 N_("net rpc trustdom establish\n"
7372 " Establish outgoing trust relationship")
7376 rpc_trustdom_revoke
,
7378 N_("Revoke outgoing trust relationship"),
7379 N_("net rpc trustdom revoke\n"
7380 " Revoke outgoing trust relationship")
7386 N_("List in- and outgoing domain trusts"),
7387 N_("net rpc trustdom list\n"
7388 " List in- and outgoing domain trusts")
7392 rpc_trustdom_vampire
,
7394 N_("Vampire trusts from remote server"),
7395 N_("net rpc trustdom vampire\n"
7396 " Vampire trusts from remote server")
7398 {NULL
, NULL
, 0, NULL
, NULL
}
7401 return net_run_function(c
, argc
, argv
, "net rpc trustdom", func
);
7405 * Check if a server will take rpc commands
7406 * @param flags Type of server to connect to (PDC, DMB, localhost)
7407 * if the host is not explicitly specified
7408 * @return bool (true means rpc supported)
7410 bool net_rpc_check(struct net_context
*c
, unsigned flags
)
7412 struct cli_state
*cli
;
7414 struct sockaddr_storage server_ss
;
7415 char *server_name
= NULL
;
7418 /* flags (i.e. server type) may depend on command */
7419 if (!net_find_server(c
, NULL
, flags
, &server_ss
, &server_name
))
7422 status
= cli_connect_nb(server_name
, &server_ss
, 0, 0x20,
7423 lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT
,
7425 if (!NT_STATUS_IS_OK(status
)) {
7428 status
= smbXcli_negprot(cli
->conn
, cli
->timeout
, PROTOCOL_CORE
,
7430 if (!NT_STATUS_IS_OK(status
))
7432 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
)
7441 /* syncronise sam database via samsync rpc calls */
7442 static int rpc_vampire(struct net_context
*c
, int argc
, const char **argv
)
7444 struct functable func
[] = {
7449 N_("Dump remote SAM database to Kerberos Keytab"),
7450 N_("net rpc vampire keytab\n"
7451 " Dump remote SAM database to Kerberos keytab "
7458 N_("Dump remote SAM database to passdb"),
7459 N_("net rpc vampire passdb\n"
7460 " Dump remote SAM database to passdb")
7463 {NULL
, NULL
, 0, NULL
, NULL
}
7467 if (c
->display_usage
) {
7472 _("Vampire remote SAM database"));
7476 return rpc_vampire_passdb(c
, argc
, argv
);
7479 return net_run_function(c
, argc
, argv
, "net rpc vampire", func
);
7483 * Migrate everything from a print server.
7485 * @param c A net_context structure.
7486 * @param argc Standard main() style argc.
7487 * @param argv Standard main() style argv. Initial components are already
7490 * @return A shell status integer (0 for success).
7492 * The order is important !
7493 * To successfully add drivers the print queues have to exist !
7494 * Applying ACLs should be the last step, because you're easily locked out.
7497 static int rpc_printer_migrate_all(struct net_context
*c
, int argc
,
7502 if (c
->display_usage
) {
7504 "net rpc printer migrate all\n"
7507 _("Migrate everything from a print server"));
7512 d_printf(_("no server to migrate\n"));
7516 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7517 rpc_printer_migrate_printers_internals
, argc
,
7522 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7523 rpc_printer_migrate_drivers_internals
, argc
,
7528 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7529 rpc_printer_migrate_forms_internals
, argc
, argv
);
7533 ret
= run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7534 rpc_printer_migrate_settings_internals
, argc
,
7539 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7540 rpc_printer_migrate_security_internals
, argc
,
7546 * Migrate print drivers from a print server.
7548 * @param c A net_context structure.
7549 * @param argc Standard main() style argc.
7550 * @param argv Standard main() style argv. Initial components are already
7553 * @return A shell status integer (0 for success).
7555 static int rpc_printer_migrate_drivers(struct net_context
*c
, int argc
,
7558 if (c
->display_usage
) {
7560 "net rpc printer migrate drivers\n"
7563 _("Migrate print-drivers from a print-server"));
7568 d_printf(_("no server to migrate\n"));
7572 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7573 rpc_printer_migrate_drivers_internals
,
7578 * Migrate print-forms from a print-server.
7580 * @param c A net_context structure.
7581 * @param argc Standard main() style argc.
7582 * @param argv Standard main() style argv. Initial components are already
7585 * @return A shell status integer (0 for success).
7587 static int rpc_printer_migrate_forms(struct net_context
*c
, int argc
,
7590 if (c
->display_usage
) {
7592 "net rpc printer migrate forms\n"
7595 _("Migrate print-forms from a print-server"));
7600 d_printf(_("no server to migrate\n"));
7604 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7605 rpc_printer_migrate_forms_internals
,
7610 * Migrate printers from a print-server.
7612 * @param c A net_context structure.
7613 * @param argc Standard main() style argc.
7614 * @param argv Standard main() style argv. Initial components are already
7617 * @return A shell status integer (0 for success).
7619 static int rpc_printer_migrate_printers(struct net_context
*c
, int argc
,
7622 if (c
->display_usage
) {
7624 "net rpc printer migrate printers\n"
7627 _("Migrate printers from a print-server"));
7632 d_printf(_("no server to migrate\n"));
7636 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7637 rpc_printer_migrate_printers_internals
,
7642 * Migrate printer-ACLs from a print-server
7644 * @param c A net_context structure.
7645 * @param argc Standard main() style argc.
7646 * @param argv Standard main() style argv. Initial components are already
7649 * @return A shell status integer (0 for success).
7651 static int rpc_printer_migrate_security(struct net_context
*c
, int argc
,
7654 if (c
->display_usage
) {
7656 "net rpc printer migrate security\n"
7659 _("Migrate printer-ACLs from a print-server"));
7664 d_printf(_("no server to migrate\n"));
7668 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7669 rpc_printer_migrate_security_internals
,
7674 * Migrate printer-settings from a print-server.
7676 * @param c A net_context structure.
7677 * @param argc Standard main() style argc.
7678 * @param argv Standard main() style argv. Initial components are already
7681 * @return A shell status integer (0 for success).
7683 static int rpc_printer_migrate_settings(struct net_context
*c
, int argc
,
7686 if (c
->display_usage
) {
7688 "net rpc printer migrate settings\n"
7691 _("Migrate printer-settings from a "
7697 d_printf(_("no server to migrate\n"));
7701 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7702 rpc_printer_migrate_settings_internals
,
7707 * 'net rpc printer' entrypoint.
7709 * @param c A net_context structure.
7710 * @param argc Standard main() style argc.
7711 * @param argv Standard main() style argv. Initial components are already
7715 int rpc_printer_migrate(struct net_context
*c
, int argc
, const char **argv
)
7718 /* ouch: when addriver and setdriver are called from within
7719 rpc_printer_migrate_drivers_internals, the printer-queue already
7722 struct functable func
[] = {
7725 rpc_printer_migrate_all
,
7727 N_("Migrate all from remote to local print server"),
7728 N_("net rpc printer migrate all\n"
7729 " Migrate all from remote to local print server")
7733 rpc_printer_migrate_drivers
,
7735 N_("Migrate drivers to local server"),
7736 N_("net rpc printer migrate drivers\n"
7737 " Migrate drivers to local server")
7741 rpc_printer_migrate_forms
,
7743 N_("Migrate froms to local server"),
7744 N_("net rpc printer migrate forms\n"
7745 " Migrate froms to local server")
7749 rpc_printer_migrate_printers
,
7751 N_("Migrate printers to local server"),
7752 N_("net rpc printer migrate printers\n"
7753 " Migrate printers to local server")
7757 rpc_printer_migrate_security
,
7759 N_("Mirgate printer ACLs to local server"),
7760 N_("net rpc printer migrate security\n"
7761 " Mirgate printer ACLs to local server")
7765 rpc_printer_migrate_settings
,
7767 N_("Migrate printer settings to local server"),
7768 N_("net rpc printer migrate settings\n"
7769 " Migrate printer settings to local server")
7771 {NULL
, NULL
, 0, NULL
, NULL
}
7774 return net_run_function(c
, argc
, argv
, "net rpc printer migrate",func
);
7779 * List printers on a remote RPC server.
7781 * @param c A net_context structure.
7782 * @param argc Standard main() style argc.
7783 * @param argv Standard main() style argv. Initial components are already
7786 * @return A shell status integer (0 for success).
7788 static int rpc_printer_list(struct net_context
*c
, int argc
, const char **argv
)
7790 if (c
->display_usage
) {
7792 "net rpc printer list\n"
7795 _("List printers on a remote RPC server"));
7799 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7800 rpc_printer_list_internals
,
7805 * List printer-drivers on a remote RPC server.
7807 * @param c A net_context structure.
7808 * @param argc Standard main() style argc.
7809 * @param argv Standard main() style argv. Initial components are already
7812 * @return A shell status integer (0 for success).
7814 static int rpc_printer_driver_list(struct net_context
*c
, int argc
,
7817 if (c
->display_usage
) {
7819 "net rpc printer driver\n"
7822 _("List printer-drivers on a remote RPC server"));
7826 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7827 rpc_printer_driver_list_internals
,
7832 * Publish printer in ADS via MSRPC.
7834 * @param c A net_context structure.
7835 * @param argc Standard main() style argc.
7836 * @param argv Standard main() style argv. Initial components are already
7839 * @return A shell status integer (0 for success).
7841 static int rpc_printer_publish_publish(struct net_context
*c
, int argc
,
7844 if (c
->display_usage
) {
7846 "net rpc printer publish publish\n"
7849 _("Publish printer in ADS via MSRPC"));
7853 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7854 rpc_printer_publish_publish_internals
,
7859 * Update printer in ADS via MSRPC.
7861 * @param c A net_context structure.
7862 * @param argc Standard main() style argc.
7863 * @param argv Standard main() style argv. Initial components are already
7866 * @return A shell status integer (0 for success).
7868 static int rpc_printer_publish_update(struct net_context
*c
, int argc
, const char **argv
)
7870 if (c
->display_usage
) {
7872 "net rpc printer publish update\n"
7875 _("Update printer in ADS via MSRPC"));
7879 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7880 rpc_printer_publish_update_internals
,
7885 * UnPublish printer in ADS via MSRPC.
7887 * @param c A net_context structure.
7888 * @param argc Standard main() style argc.
7889 * @param argv Standard main() style argv. Initial components are already
7892 * @return A shell status integer (0 for success).
7894 static int rpc_printer_publish_unpublish(struct net_context
*c
, int argc
,
7897 if (c
->display_usage
) {
7899 "net rpc printer publish unpublish\n"
7902 _("UnPublish printer in ADS via MSRPC"));
7906 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7907 rpc_printer_publish_unpublish_internals
,
7912 * List published printers via MSRPC.
7914 * @param c A net_context structure.
7915 * @param argc Standard main() style argc.
7916 * @param argv Standard main() style argv. Initial components are already
7919 * @return A shell status integer (0 for success).
7921 static int rpc_printer_publish_list(struct net_context
*c
, int argc
,
7924 if (c
->display_usage
) {
7926 "net rpc printer publish list\n"
7929 _("List published printers via MSRPC"));
7933 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
7934 rpc_printer_publish_list_internals
,
7940 * Publish printer in ADS.
7942 * @param c A net_context structure.
7943 * @param argc Standard main() style argc.
7944 * @param argv Standard main() style argv. Initial components are already
7947 * @return A shell status integer (0 for success).
7949 static int rpc_printer_publish(struct net_context
*c
, int argc
,
7953 struct functable func
[] = {
7956 rpc_printer_publish_publish
,
7958 N_("Publish printer in AD"),
7959 N_("net rpc printer publish publish\n"
7960 " Publish printer in AD")
7964 rpc_printer_publish_update
,
7966 N_("Update printer in AD"),
7967 N_("net rpc printer publish update\n"
7968 " Update printer in AD")
7972 rpc_printer_publish_unpublish
,
7974 N_("Unpublish printer"),
7975 N_("net rpc printer publish unpublish\n"
7976 " Unpublish printer")
7980 rpc_printer_publish_list
,
7982 N_("List published printers"),
7983 N_("net rpc printer publish list\n"
7984 " List published printers")
7986 {NULL
, NULL
, 0, NULL
, NULL
}
7990 if (c
->display_usage
) {
7991 d_printf(_("Usage:\n"));
7992 d_printf(_("net rpc printer publish\n"
7993 " List published printers\n"
7994 " Alias of net rpc printer publish "
7996 net_display_usage_from_functable(func
);
7999 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
8000 rpc_printer_publish_list_internals
,
8004 return net_run_function(c
, argc
, argv
, "net rpc printer publish",func
);
8010 * Display rpc printer help page.
8012 * @param c A net_context structure.
8013 * @param argc Standard main() style argc.
8014 * @param argv Standard main() style argv. Initial components are already
8017 int rpc_printer_usage(struct net_context
*c
, int argc
, const char **argv
)
8019 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
8020 "\tlists all printers on print-server\n\n"));
8021 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
8022 "\tlists all printer-drivers on print-server\n\n"));
8023 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
8024 "\tpublishes printer settings in Active Directory\n"
8025 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
8026 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
8027 "\n\tmigrates printers from remote to local server\n\n"));
8028 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
8029 "\n\tmigrates printer-settings from remote to local server\n\n"));
8030 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
8031 "\n\tmigrates printer-drivers from remote to local server\n\n"));
8032 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
8033 "\n\tmigrates printer-forms from remote to local server\n\n"));
8034 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
8035 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
8036 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
8037 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
8038 "\tremote to local print-server\n\n"));
8039 net_common_methods_usage(c
, argc
, argv
);
8040 net_common_flags_usage(c
, argc
, argv
);
8042 "\t-v or --verbose\t\t\tgive verbose output\n"
8043 "\t --destination\t\tmigration target server (default: localhost)\n"));
8049 * 'net rpc printer' entrypoint.
8051 * @param c A net_context structure.
8052 * @param argc Standard main() style argc.
8053 * @param argv Standard main() style argv. Initial components are already
8056 int net_rpc_printer(struct net_context
*c
, int argc
, const char **argv
)
8058 struct functable func
[] = {
8063 N_("List all printers on print server"),
8064 N_("net rpc printer list\n"
8065 " List all printers on print server")
8069 rpc_printer_migrate
,
8071 N_("Migrate printer to local server"),
8072 N_("net rpc printer migrate\n"
8073 " Migrate printer to local server")
8077 rpc_printer_driver_list
,
8079 N_("List printer drivers"),
8080 N_("net rpc printer driver\n"
8081 " List printer drivers")
8085 rpc_printer_publish
,
8087 N_("Publish printer in AD"),
8088 N_("net rpc printer publish\n"
8089 " Publish printer in AD")
8091 {NULL
, NULL
, 0, NULL
, NULL
}
8095 if (c
->display_usage
) {
8096 d_printf(_("Usage:\n"));
8097 d_printf(_("net rpc printer\n"
8098 " List printers\n"));
8099 net_display_usage_from_functable(func
);
8102 return run_rpc_command(c
, NULL
, &ndr_table_spoolss
, 0,
8103 rpc_printer_list_internals
,
8107 return net_run_function(c
, argc
, argv
, "net rpc printer", func
);
8111 * 'net rpc' entrypoint.
8113 * @param c A net_context structure.
8114 * @param argc Standard main() style argc.
8115 * @param argv Standard main() style argv. Initial components are already
8119 int net_rpc(struct net_context
*c
, int argc
, const char **argv
)
8121 NET_API_STATUS status
;
8123 struct functable func
[] = {
8128 N_("Modify global audit settings"),
8129 N_("net rpc audit\n"
8130 " Modify global audit settings")
8136 N_("Show basic info about a domain"),
8138 " Show basic info about a domain")
8144 N_("Join a domain"),
8152 N_("Join a domain created in server manager"),
8153 N_("net rpc oldjoin\n"
8154 " Join a domain created in server manager")
8160 N_("Test that a join is valid"),
8161 N_("net rpc testjoin\n"
8162 " Test that a join is valid")
8168 N_("List/modify users"),
8170 " List/modify users")
8176 N_("Change a user password"),
8177 N_("net rpc password\n"
8178 " Change a user password\n"
8179 " Alias for net rpc user password")
8185 N_("List/modify groups"),
8186 N_("net rpc group\n"
8187 " List/modify groups")
8193 N_("List/modify shares"),
8194 N_("net rpc share\n"
8195 " List/modify shares")
8201 N_("List open files"),
8209 N_("List/modify printers"),
8210 N_("net rpc printer\n"
8211 " List/modify printers")
8215 net_rpc_changetrustpw
,
8217 N_("Change trust account password"),
8218 N_("net rpc changetrustpw\n"
8219 " Change trust account password")
8225 N_("Modify domain trusts"),
8226 N_("net rpc trustdom\n"
8227 " Modify domain trusts")
8233 N_("Abort a remote shutdown"),
8234 N_("net rpc abortshutdown\n"
8235 " Abort a remote shutdown")
8241 N_("Shutdown a remote server"),
8242 N_("net rpc shutdown\n"
8243 " Shutdown a remote server")
8249 N_("Sync a remote NT PDC's data into local passdb"),
8250 N_("net rpc vampire\n"
8251 " Sync a remote NT PDC's data into local passdb")
8257 N_("Fetch the domain sid into local secrets.tdb"),
8258 N_("net rpc getsid\n"
8259 " Fetch the domain sid into local secrets.tdb")
8265 N_("Manage privileges assigned to SID"),
8266 N_("net rpc rights\n"
8267 " Manage privileges assigned to SID")
8273 N_("Start/stop/query remote services"),
8274 N_("net rpc service\n"
8275 " Start/stop/query remote services")
8281 N_("Manage registry hives"),
8282 N_("net rpc registry\n"
8283 " Manage registry hives")
8289 N_("Open interactive shell on remote server"),
8290 N_("net rpc shell\n"
8291 " Open interactive shell on remote server")
8297 N_("Manage trusts"),
8298 N_("net rpc trust\n"
8305 N_("Configure a remote samba server"),
8307 " Configure a remote samba server")
8309 {NULL
, NULL
, 0, NULL
, NULL
}
8312 status
= libnetapi_net_init(&c
->netapi_ctx
);
8316 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
8317 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
8318 if (c
->opt_kerberos
) {
8319 libnetapi_set_use_kerberos(c
->netapi_ctx
);
8321 if (c
->opt_ccache
) {
8322 libnetapi_set_use_ccache(c
->netapi_ctx
);
8325 return net_run_function(c
, argc
, argv
, "net rpc", func
);