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"
26 static int net_mode_share
;
27 static bool sync_files(struct copy_clistate
*cp_clistate
, const char *mask
);
32 * @brief RPC based subcommands for the 'net' utility.
34 * This file should contain much of the functionality that used to
35 * be found in rpcclient, execpt that the commands should change
36 * less often, and the fucntionality should be sane (the user is not
37 * expected to know a rid/sid before they conduct an operation etc.)
39 * @todo Perhaps eventually these should be split out into a number
40 * of files, as this could get quite big.
45 * Many of the RPC functions need the domain sid. This function gets
46 * it at the start of every run
48 * @param cli A cli_state already connected to the remote machine
50 * @return The Domain SID of the remote machine.
53 NTSTATUS
net_get_remote_domain_sid(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
55 const char **domain_name
)
57 struct rpc_pipe_client
*lsa_pipe
;
59 NTSTATUS result
= NT_STATUS_OK
;
60 union lsa_PolicyInformation
*info
= NULL
;
62 result
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
.syntax_id
,
64 if (!NT_STATUS_IS_OK(result
)) {
65 d_fprintf(stderr
, "Could not initialise lsa pipe\n");
69 result
= rpccli_lsa_open_policy(lsa_pipe
, mem_ctx
, false,
70 SEC_RIGHTS_MAXIMUM_ALLOWED
,
72 if (!NT_STATUS_IS_OK(result
)) {
73 d_fprintf(stderr
, "open_policy failed: %s\n",
78 result
= rpccli_lsa_QueryInfoPolicy(lsa_pipe
, mem_ctx
,
80 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
82 if (!NT_STATUS_IS_OK(result
)) {
83 d_fprintf(stderr
, "lsaquery failed: %s\n",
88 *domain_name
= info
->account_domain
.name
.string
;
89 *domain_sid
= info
->account_domain
.sid
;
91 rpccli_lsa_Close(lsa_pipe
, mem_ctx
, &pol
);
92 TALLOC_FREE(lsa_pipe
);
98 * Run a single RPC command, from start to finish.
100 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
101 * @param conn_flag a NET_FLAG_ combination. Passed to
102 * net_make_ipc_connection.
103 * @param argc Standard main() style argc.
104 * @param argv Standard main() style argv. Initial components are already
106 * @return A shell status integer (0 for success).
109 int run_rpc_command(struct net_context
*c
,
110 struct cli_state
*cli_arg
,
117 struct cli_state
*cli
= NULL
;
118 struct rpc_pipe_client
*pipe_hnd
= NULL
;
122 const char *domain_name
;
124 /* make use of cli_state handed over as an argument, if possible */
126 nt_status
= net_make_ipc_connection(c
, conn_flags
, &cli
);
127 if (!NT_STATUS_IS_OK(nt_status
)) {
128 DEBUG(1, ("failed to make ipc connection: %s\n",
129 nt_errstr(nt_status
)));
142 if (!(mem_ctx
= talloc_init("run_rpc_command"))) {
143 DEBUG(0, ("talloc_init() failed\n"));
148 nt_status
= net_get_remote_domain_sid(cli
, mem_ctx
, &domain_sid
,
150 if (!NT_STATUS_IS_OK(nt_status
)) {
155 if (!(conn_flags
& NET_FLAGS_NO_PIPE
)) {
156 if (lp_client_schannel() && (pipe_idx
== PI_NETLOGON
)) {
157 /* Always try and create an schannel netlogon pipe. */
158 pipe_hnd
= cli_rpc_pipe_open_schannel(cli
, pipe_idx
,
159 PIPE_AUTH_LEVEL_PRIVACY
,
163 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
164 nt_errstr(nt_status
) ));
169 if (conn_flags
& NET_FLAGS_SEAL
) {
170 nt_status
= cli_rpc_pipe_open_ntlmssp(
171 cli
, cli_get_iface(pipe_idx
),
172 PIPE_AUTH_LEVEL_PRIVACY
,
173 lp_workgroup(), c
->opt_user_name
,
174 c
->opt_password
, &pipe_hnd
);
176 nt_status
= cli_rpc_pipe_open_noauth(
177 cli
, cli_get_iface(pipe_idx
),
180 if (!NT_STATUS_IS_OK(nt_status
)) {
181 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
182 cli_get_pipe_name(pipe_idx
),
183 nt_errstr(nt_status
) ));
190 nt_status
= fn(c
, domain_sid
, domain_name
, cli
, pipe_hnd
, mem_ctx
, argc
, argv
);
192 if (!NT_STATUS_IS_OK(nt_status
)) {
193 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status
)));
195 DEBUG(5, ("rpc command function succedded\n"));
198 if (!(conn_flags
& NET_FLAGS_NO_PIPE
)) {
200 TALLOC_FREE(pipe_hnd
);
204 /* close the connection only if it was opened here */
209 talloc_destroy(mem_ctx
);
210 return (!NT_STATUS_IS_OK(nt_status
));
214 * Force a change of the trust acccount password.
216 * All parameters are provided by the run_rpc_command function, except for
217 * argc, argv which are passed through.
219 * @param domain_sid The domain sid acquired from the remote server.
220 * @param cli A cli_state connected to the server.
221 * @param mem_ctx Talloc context, destroyed on completion of the function.
222 * @param argc Standard main() style argc.
223 * @param argv Standard main() style argv. Initial components are already
226 * @return Normal NTSTATUS return.
229 static NTSTATUS
rpc_changetrustpw_internals(struct net_context
*c
,
230 const DOM_SID
*domain_sid
,
231 const char *domain_name
,
232 struct cli_state
*cli
,
233 struct rpc_pipe_client
*pipe_hnd
,
239 return trust_pw_find_change_and_store_it(pipe_hnd
, mem_ctx
, c
->opt_target_workgroup
);
243 * Force a change of the trust acccount password.
245 * @param argc Standard main() style argc.
246 * @param argv Standard main() style argv. Initial components are already
249 * @return A shell status integer (0 for success).
252 int net_rpc_changetrustpw(struct net_context
*c
, int argc
, const char **argv
)
254 if (c
->display_usage
) {
256 "net rpc changetrustpw\n"
257 " Change the machine trust password\n");
261 return run_rpc_command(c
, NULL
, PI_NETLOGON
, NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
,
262 rpc_changetrustpw_internals
,
267 * Join a domain, the old way.
269 * This uses 'machinename' as the inital password, and changes it.
271 * The password should be created with 'server manager' or equiv first.
273 * All parameters are provided by the run_rpc_command function, except for
274 * argc, argv which are passed through.
276 * @param domain_sid The domain sid acquired from the remote server.
277 * @param cli A cli_state connected to the server.
278 * @param mem_ctx Talloc context, destroyed on completion of the function.
279 * @param argc Standard main() style argc.
280 * @param argv Standard main() style argv. Initial components are already
283 * @return Normal NTSTATUS return.
286 static NTSTATUS
rpc_oldjoin_internals(struct net_context
*c
,
287 const DOM_SID
*domain_sid
,
288 const char *domain_name
,
289 struct cli_state
*cli
,
290 struct rpc_pipe_client
*pipe_hnd
,
296 fstring trust_passwd
;
297 unsigned char orig_trust_passwd_hash
[16];
299 uint32 sec_channel_type
;
301 result
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
303 if (!NT_STATUS_IS_OK(result
)) {
304 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
307 nt_errstr(result
) ));
312 check what type of join - if the user want's to join as
313 a BDC, the server must agree that we are a BDC.
316 sec_channel_type
= get_sec_channel_type(argv
[0]);
318 sec_channel_type
= get_sec_channel_type(NULL
);
321 fstrcpy(trust_passwd
, global_myname());
322 strlower_m(trust_passwd
);
325 * Machine names can be 15 characters, but the max length on
326 * a password is 14. --jerry
329 trust_passwd
[14] = '\0';
331 E_md4hash(trust_passwd
, orig_trust_passwd_hash
);
333 result
= trust_pw_change_and_store_it(pipe_hnd
, mem_ctx
, c
->opt_target_workgroup
,
334 orig_trust_passwd_hash
,
337 if (NT_STATUS_IS_OK(result
))
338 printf("Joined domain %s.\n", c
->opt_target_workgroup
);
341 if (!secrets_store_domain_sid(c
->opt_target_workgroup
, domain_sid
)) {
342 DEBUG(0, ("error storing domain sid for %s\n", c
->opt_target_workgroup
));
343 result
= NT_STATUS_UNSUCCESSFUL
;
350 * Join a domain, the old way.
352 * @param argc Standard main() style argc.
353 * @param argv Standard main() style argv. Initial components are already
356 * @return A shell status integer (0 for success).
359 static int net_rpc_perform_oldjoin(struct net_context
*c
, int argc
, const char **argv
)
361 return run_rpc_command(c
, NULL
, PI_NETLOGON
,
362 NET_FLAGS_NO_PIPE
| NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
,
363 rpc_oldjoin_internals
,
368 * Join a domain, the old way. This function exists to allow
369 * the message to be displayed when oldjoin was explicitly
370 * requested, but not when it was implied by "net rpc join".
372 * @param argc Standard main() style argc.
373 * @param argv Standard main() style argv. Initial components are already
376 * @return A shell status integer (0 for success).
379 static int net_rpc_oldjoin(struct net_context
*c
, int argc
, const char **argv
)
383 if (c
->display_usage
) {
386 " Join a domain the old way\n");
390 rc
= net_rpc_perform_oldjoin(c
, argc
, argv
);
393 d_fprintf(stderr
, "Failed to join domain\n");
400 * 'net rpc join' entrypoint.
401 * @param argc Standard main() style argc.
402 * @param argv Standard main() style argv. Initial components are already
405 * Main 'net_rpc_join()' (where the admin username/password is used) is
407 * Try to just change the password, but if that doesn't work, use/prompt
408 * for a username/password.
411 int net_rpc_join(struct net_context
*c
, int argc
, const char **argv
)
413 if (c
->display_usage
) {
415 "net rpc join -U <username>[%%password] <type>\n"
417 " username\tName of the admin user"
418 " password\tPassword of the admin user, will "
419 "prompt if not specified\n"
420 " type\tCan be one of the following:\n"
421 "\t\tMEMBER\tJoin as member server (default)\n"
422 "\t\tBDC\tJoin as BDC\n"
423 "\t\tPDC\tJoin as PDC\n");
427 if (lp_server_role() == ROLE_STANDALONE
) {
428 d_printf("cannot join as standalone machine\n");
432 if (strlen(global_myname()) > 15) {
433 d_printf("Our netbios name can be at most 15 chars long, "
434 "\"%s\" is %u chars long\n",
435 global_myname(), (unsigned int)strlen(global_myname()));
439 if ((net_rpc_perform_oldjoin(c
, argc
, argv
) == 0))
442 return net_rpc_join_newstyle(c
, argc
, argv
);
446 * display info about a rpc domain
448 * All parameters are provided by the run_rpc_command function, except for
449 * argc, argv which are passed through.
451 * @param domain_sid The domain sid acquired from the remote server
452 * @param cli A cli_state connected to the server.
453 * @param mem_ctx Talloc context, destroyed on completion of the function.
454 * @param argc Standard main() style argc.
455 * @param argv Standard main() style argv. Initial components are already
458 * @return Normal NTSTATUS return.
461 NTSTATUS
rpc_info_internals(struct net_context
*c
,
462 const DOM_SID
*domain_sid
,
463 const char *domain_name
,
464 struct cli_state
*cli
,
465 struct rpc_pipe_client
*pipe_hnd
,
470 POLICY_HND connect_pol
, domain_pol
;
471 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
472 union samr_DomainInfo
*info
= NULL
;
475 sid_to_fstring(sid_str
, domain_sid
);
477 /* Get sam policy handle */
478 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
480 MAXIMUM_ALLOWED_ACCESS
,
482 if (!NT_STATUS_IS_OK(result
)) {
483 d_fprintf(stderr
, "Could not connect to SAM: %s\n", nt_errstr(result
));
487 /* Get domain policy handle */
488 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
490 MAXIMUM_ALLOWED_ACCESS
,
491 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
493 if (!NT_STATUS_IS_OK(result
)) {
494 d_fprintf(stderr
, "Could not open domain: %s\n", nt_errstr(result
));
498 result
= rpccli_samr_QueryDomainInfo(pipe_hnd
, mem_ctx
,
502 if (NT_STATUS_IS_OK(result
)) {
503 d_printf("Domain Name: %s\n", info
->info2
.domain_name
.string
);
504 d_printf("Domain SID: %s\n", sid_str
);
505 d_printf("Sequence number: %llu\n",
506 (unsigned long long)info
->info2
.sequence_num
);
507 d_printf("Num users: %u\n", info
->info2
.num_users
);
508 d_printf("Num domain groups: %u\n", info
->info2
.num_groups
);
509 d_printf("Num local groups: %u\n", info
->info2
.num_aliases
);
517 * 'net rpc info' entrypoint.
518 * @param argc Standard main() style argc.
519 * @param argv Standard main() style argv. Initial components are already
523 int net_rpc_info(struct net_context
*c
, int argc
, const char **argv
)
525 if (c
->display_usage
) {
528 " Display information about the domain\n");
532 return run_rpc_command(c
, NULL
, PI_SAMR
, NET_FLAGS_PDC
,
538 * Fetch domain SID into the local secrets.tdb.
540 * All parameters are provided by the run_rpc_command function, except for
541 * argc, argv which are passed through.
543 * @param domain_sid The domain sid acquired from the remote server.
544 * @param cli A cli_state connected to the server.
545 * @param mem_ctx Talloc context, destroyed on completion of the function.
546 * @param argc Standard main() style argc.
547 * @param argv Standard main() style argv. Initial components are already
550 * @return Normal NTSTATUS return.
553 static NTSTATUS
rpc_getsid_internals(struct net_context
*c
,
554 const DOM_SID
*domain_sid
,
555 const char *domain_name
,
556 struct cli_state
*cli
,
557 struct rpc_pipe_client
*pipe_hnd
,
564 sid_to_fstring(sid_str
, domain_sid
);
565 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
566 sid_str
, domain_name
);
568 if (!secrets_store_domain_sid(domain_name
, domain_sid
)) {
569 DEBUG(0,("Can't store domain SID\n"));
570 return NT_STATUS_UNSUCCESSFUL
;
577 * 'net rpc getsid' entrypoint.
578 * @param argc Standard main() style argc.
579 * @param argv Standard main() style argv. Initial components are already
583 int net_rpc_getsid(struct net_context
*c
, int argc
, const char **argv
)
585 if (c
->display_usage
) {
588 " Fetch domain SID into local secrets.tdb\n");
592 return run_rpc_command(c
, NULL
, PI_SAMR
,
593 NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
,
594 rpc_getsid_internals
,
598 /****************************************************************************/
601 * Basic usage function for 'net rpc user'.
602 * @param argc Standard main() style argc.
603 * @param argv Standard main() style argv. Initial components are already
607 static int rpc_user_usage(struct net_context
*c
, int argc
, const char **argv
)
609 return net_user_usage(c
, argc
, argv
);
613 * Add a new user to a remote RPC server.
615 * @param argc Standard main() style argc.
616 * @param argv Standard main() style argv. Initial components are already
619 * @return A shell status integer (0 for success).
622 static int rpc_user_add(struct net_context
*c
, int argc
, const char **argv
)
624 NET_API_STATUS status
;
625 struct USER_INFO_1 info1
;
626 uint32_t parm_error
= 0;
628 if (argc
< 1 || c
->display_usage
) {
629 rpc_user_usage(c
, argc
, argv
);
635 info1
.usri1_name
= argv
[0];
637 info1
.usri1_password
= argv
[1];
640 status
= NetUserAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
643 d_fprintf(stderr
, "Failed to add user '%s' with: %s.\n",
644 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
648 d_printf("Added user '%s'.\n", argv
[0]);
655 * Rename a user on a remote RPC server.
657 * All parameters are provided by the run_rpc_command function, except for
658 * argc, argv which are passed through.
660 * @param domain_sid The domain sid acquired from the remote server.
661 * @param cli A cli_state connected to the server.
662 * @param mem_ctx Talloc context, destroyed on completion of the function.
663 * @param argc Standard main() style argc.
664 * @param argv Standard main() style argv. Initial components are already
667 * @return Normal NTSTATUS return.
670 static NTSTATUS
rpc_user_rename_internals(struct net_context
*c
,
671 const DOM_SID
*domain_sid
,
672 const char *domain_name
,
673 struct cli_state
*cli
,
674 struct rpc_pipe_client
*pipe_hnd
,
679 POLICY_HND connect_pol
, domain_pol
, user_pol
;
680 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
681 uint32 info_level
= 7;
682 const char *old_name
, *new_name
;
683 struct samr_Ids user_rids
, name_types
;
684 struct lsa_String lsa_acct_name
;
685 union samr_UserInfo
*info
= NULL
;
687 if (argc
!= 2 || c
->display_usage
) {
688 rpc_user_usage(c
, argc
, argv
);
695 /* Get sam policy handle */
697 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
699 MAXIMUM_ALLOWED_ACCESS
,
702 if (!NT_STATUS_IS_OK(result
)) {
706 /* Get domain policy handle */
708 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
710 MAXIMUM_ALLOWED_ACCESS
,
711 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
713 if (!NT_STATUS_IS_OK(result
)) {
717 init_lsa_String(&lsa_acct_name
, old_name
);
719 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
725 if (!NT_STATUS_IS_OK(result
)) {
729 /* Open domain user */
730 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
732 MAXIMUM_ALLOWED_ACCESS
,
736 if (!NT_STATUS_IS_OK(result
)) {
740 /* Query user info */
741 result
= rpccli_samr_QueryUserInfo(pipe_hnd
, mem_ctx
,
746 if (!NT_STATUS_IS_OK(result
)) {
750 init_samr_user_info7(&info
->info7
, new_name
);
753 result
= rpccli_samr_SetUserInfo2(pipe_hnd
, mem_ctx
,
758 if (!NT_STATUS_IS_OK(result
)) {
763 if (!NT_STATUS_IS_OK(result
)) {
764 d_fprintf(stderr
, "Failed to rename user from %s to %s - %s\n", old_name
, new_name
,
767 d_printf("Renamed user from %s to %s\n", old_name
, new_name
);
773 * Rename a user on a remote RPC server.
775 * @param argc Standard main() style argc.
776 * @param argv Standard main() style argv. Initial components are already
779 * @return A shell status integer (0 for success).
782 static int rpc_user_rename(struct net_context
*c
, int argc
, const char **argv
)
784 return run_rpc_command(c
, NULL
, PI_SAMR
, 0, rpc_user_rename_internals
,
789 * Delete a user from a remote RPC server.
791 * @param argc Standard main() style argc.
792 * @param argv Standard main() style argv. Initial components are already
795 * @return A shell status integer (0 for success).
798 static int rpc_user_delete(struct net_context
*c
, int argc
, const char **argv
)
800 NET_API_STATUS status
;
802 if (argc
< 1 || c
->display_usage
) {
803 rpc_user_usage(c
, argc
, argv
);
807 status
= NetUserDel(c
->opt_host
, argv
[0]);
810 d_fprintf(stderr
, "Failed to delete user '%s' with: %s.\n",
812 libnetapi_get_error_string(c
->netapi_ctx
, status
));
815 d_printf("Deleted user '%s'.\n", argv
[0]);
822 * Set a password for a user on a remote RPC server.
824 * All parameters are provided by the run_rpc_command function, except for
825 * argc, argv which are passed through.
827 * @param domain_sid The domain sid acquired from the remote server.
828 * @param cli A cli_state connected to the server.
829 * @param mem_ctx Talloc context, destroyed on completion of the function.
830 * @param argc Standard main() style argc.
831 * @param argv Standard main() style argv. Initial components are already
834 * @return Normal NTSTATUS return.
837 static NTSTATUS
rpc_user_password_internals(struct net_context
*c
,
838 const DOM_SID
*domain_sid
,
839 const char *domain_name
,
840 struct cli_state
*cli
,
841 struct rpc_pipe_client
*pipe_hnd
,
846 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
847 POLICY_HND connect_pol
, domain_pol
, user_pol
;
850 const char *new_password
;
852 union samr_UserInfo info
;
854 if (argc
< 1 || c
->display_usage
) {
855 rpc_user_usage(c
, argc
, argv
);
862 new_password
= argv
[1];
864 asprintf(&prompt
, "Enter new password for %s:", user
);
865 new_password
= getpass(prompt
);
869 /* Get sam policy and domain handles */
871 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
873 MAXIMUM_ALLOWED_ACCESS
,
876 if (!NT_STATUS_IS_OK(result
)) {
880 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
882 MAXIMUM_ALLOWED_ACCESS
,
883 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
886 if (!NT_STATUS_IS_OK(result
)) {
890 /* Get handle on user */
893 struct samr_Ids user_rids
, name_types
;
894 struct lsa_String lsa_acct_name
;
896 init_lsa_String(&lsa_acct_name
, user
);
898 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
904 if (!NT_STATUS_IS_OK(result
)) {
908 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
910 MAXIMUM_ALLOWED_ACCESS
,
914 if (!NT_STATUS_IS_OK(result
)) {
919 /* Set password on account */
921 encode_pw_buffer(pwbuf
, new_password
, STR_UNICODE
);
923 init_samr_user_info24(&info
.info24
, pwbuf
, 24);
925 SamOEMhashBlob(info
.info24
.password
.data
, 516,
926 &cli
->user_session_key
);
928 result
= rpccli_samr_SetUserInfo2(pipe_hnd
, mem_ctx
,
933 if (!NT_STATUS_IS_OK(result
)) {
937 /* Display results */
945 * Set a user's password on a remote RPC server.
947 * @param argc Standard main() style argc.
948 * @param argv Standard main() style argv. Initial components are already
951 * @return A shell status integer (0 for success).
954 static int rpc_user_password(struct net_context
*c
, int argc
, const char **argv
)
956 return run_rpc_command(c
, NULL
, PI_SAMR
, 0, rpc_user_password_internals
,
961 * List user's groups on a remote RPC server.
963 * All parameters are provided by the run_rpc_command function, except for
964 * argc, argv which are passed through.
966 * @param domain_sid The domain sid acquired from the remote server.
967 * @param cli A cli_state connected to the server.
968 * @param mem_ctx Talloc context, destroyed on completion of the function.
969 * @param argc Standard main() style argc.
970 * @param argv Standard main() style argv. Initial components are already
973 * @return Normal NTSTATUS return.
976 static NTSTATUS
rpc_user_info_internals(struct net_context
*c
,
977 const DOM_SID
*domain_sid
,
978 const char *domain_name
,
979 struct cli_state
*cli
,
980 struct rpc_pipe_client
*pipe_hnd
,
985 POLICY_HND connect_pol
, domain_pol
, user_pol
;
986 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
988 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
989 struct lsa_Strings names
;
990 struct samr_Ids types
;
991 uint32_t *lrids
= NULL
;
992 struct samr_Ids rids
, name_types
;
993 struct lsa_String lsa_acct_name
;
996 if (argc
< 1 || c
->display_usage
) {
997 rpc_user_usage(c
, argc
, argv
);
1000 /* Get sam policy handle */
1002 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
1004 MAXIMUM_ALLOWED_ACCESS
,
1006 if (!NT_STATUS_IS_OK(result
)) goto done
;
1008 /* Get domain policy handle */
1010 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
1012 MAXIMUM_ALLOWED_ACCESS
,
1013 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
1015 if (!NT_STATUS_IS_OK(result
)) goto done
;
1017 /* Get handle on user */
1019 init_lsa_String(&lsa_acct_name
, argv
[0]);
1021 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
1028 if (!NT_STATUS_IS_OK(result
)) goto done
;
1030 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
1032 MAXIMUM_ALLOWED_ACCESS
,
1035 if (!NT_STATUS_IS_OK(result
)) goto done
;
1037 result
= rpccli_samr_GetGroupsForUser(pipe_hnd
, mem_ctx
,
1041 if (!NT_STATUS_IS_OK(result
)) goto done
;
1045 if (rid_array
->count
) {
1046 if ((lrids
= TALLOC_ARRAY(mem_ctx
, uint32
, rid_array
->count
)) == NULL
) {
1047 result
= NT_STATUS_NO_MEMORY
;
1051 for (i
= 0; i
< rid_array
->count
; i
++)
1052 lrids
[i
] = rid_array
->rids
[i
].rid
;
1054 result
= rpccli_samr_LookupRids(pipe_hnd
, mem_ctx
,
1061 if (!NT_STATUS_IS_OK(result
)) {
1065 /* Display results */
1067 for (i
= 0; i
< names
.count
; i
++)
1068 printf("%s\n", names
.names
[i
].string
);
1075 * List a user's groups from a remote RPC server.
1077 * @param argc Standard main() style argc.
1078 * @param argv Standard main() style argv. Initial components are already
1081 * @return A shell status integer (0 for success)
1084 static int rpc_user_info(struct net_context
*c
, int argc
, const char **argv
)
1086 return run_rpc_command(c
, NULL
, PI_SAMR
, 0, rpc_user_info_internals
,
1091 * List users on a remote RPC server.
1093 * All parameters are provided by the run_rpc_command function, except for
1094 * argc, argv which are passed through.
1096 * @param domain_sid The domain sid acquired from the remote server.
1097 * @param cli A cli_state connected to the server.
1098 * @param mem_ctx Talloc context, destroyed on completion of the function.
1099 * @param argc Standard main() style argc.
1100 * @param argv Standard main() style argv. Initial components are already
1103 * @return Normal NTSTATUS return.
1106 static NTSTATUS
rpc_user_list_internals(struct net_context
*c
,
1107 const DOM_SID
*domain_sid
,
1108 const char *domain_name
,
1109 struct cli_state
*cli
,
1110 struct rpc_pipe_client
*pipe_hnd
,
1111 TALLOC_CTX
*mem_ctx
,
1115 POLICY_HND connect_pol
, domain_pol
;
1116 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1117 uint32 start_idx
=0, num_entries
, i
, loop_count
= 0;
1119 /* Get sam policy handle */
1121 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
1123 MAXIMUM_ALLOWED_ACCESS
,
1125 if (!NT_STATUS_IS_OK(result
)) {
1129 /* Get domain policy handle */
1131 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
1133 MAXIMUM_ALLOWED_ACCESS
,
1134 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
1136 if (!NT_STATUS_IS_OK(result
)) {
1140 /* Query domain users */
1141 if (c
->opt_long_list_entries
)
1142 d_printf("\nUser name Comment"
1143 "\n-----------------------------\n");
1145 const char *user
= NULL
;
1146 const char *desc
= NULL
;
1147 uint32 max_entries
, max_size
;
1148 uint32_t total_size
, returned_size
;
1149 union samr_DispInfo info
;
1151 get_query_dispinfo_params(
1152 loop_count
, &max_entries
, &max_size
);
1154 result
= rpccli_samr_QueryDisplayInfo(pipe_hnd
, mem_ctx
,
1164 start_idx
+= info
.info1
.count
;
1165 num_entries
= info
.info1
.count
;
1167 for (i
= 0; i
< num_entries
; i
++) {
1168 user
= info
.info1
.entries
[i
].account_name
.string
;
1169 if (c
->opt_long_list_entries
)
1170 desc
= info
.info1
.entries
[i
].description
.string
;
1171 if (c
->opt_long_list_entries
)
1172 printf("%-21.21s %s\n", user
, desc
);
1174 printf("%s\n", user
);
1176 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1183 * 'net rpc user' entrypoint.
1184 * @param argc Standard main() style argc.
1185 * @param argv Standard main() style argv. Initial components are already
1189 int net_rpc_user(struct net_context
*c
, int argc
, const char **argv
)
1191 NET_API_STATUS status
;
1193 struct functable func
[] = {
1198 "Add specified user",
1199 "net rpc user add\n"
1200 " Add specified user"
1206 "List domain groups of user",
1207 "net rpc user info\n"
1208 " Lis domain groups of user"
1214 "Remove specified user",
1215 "net rpc user delete\n"
1216 " Remove specified user"
1222 "Change user password",
1223 "net rpc user password\n"
1224 " Change user password"
1230 "Rename specified user",
1231 "net rpc user rename\n"
1232 " Rename specified user"
1234 {NULL
, NULL
, 0, NULL
, NULL
}
1237 status
= libnetapi_init(&c
->netapi_ctx
);
1241 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
1242 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
1245 if (c
->display_usage
) {
1246 d_printf("Usage:\n");
1247 d_printf("net rpc user\n"
1248 " List all users\n");
1249 net_display_usage_from_functable(func
);
1253 return run_rpc_command(c
, NULL
,PI_SAMR
, 0,
1254 rpc_user_list_internals
,
1258 return net_run_function(c
, argc
, argv
, "net rpc user", func
);
1261 static NTSTATUS
rpc_sh_user_list(struct net_context
*c
,
1262 TALLOC_CTX
*mem_ctx
,
1263 struct rpc_sh_ctx
*ctx
,
1264 struct rpc_pipe_client
*pipe_hnd
,
1265 int argc
, const char **argv
)
1267 return rpc_user_list_internals(c
, ctx
->domain_sid
, ctx
->domain_name
,
1268 ctx
->cli
, pipe_hnd
, mem_ctx
,
1272 static NTSTATUS
rpc_sh_user_info(struct net_context
*c
,
1273 TALLOC_CTX
*mem_ctx
,
1274 struct rpc_sh_ctx
*ctx
,
1275 struct rpc_pipe_client
*pipe_hnd
,
1276 int argc
, const char **argv
)
1278 return rpc_user_info_internals(c
, ctx
->domain_sid
, ctx
->domain_name
,
1279 ctx
->cli
, pipe_hnd
, mem_ctx
,
1283 static NTSTATUS
rpc_sh_handle_user(struct net_context
*c
,
1284 TALLOC_CTX
*mem_ctx
,
1285 struct rpc_sh_ctx
*ctx
,
1286 struct rpc_pipe_client
*pipe_hnd
,
1287 int argc
, const char **argv
,
1289 struct net_context
*c
,
1290 TALLOC_CTX
*mem_ctx
,
1291 struct rpc_sh_ctx
*ctx
,
1292 struct rpc_pipe_client
*pipe_hnd
,
1293 POLICY_HND
*user_hnd
,
1294 int argc
, const char **argv
))
1296 POLICY_HND connect_pol
, domain_pol
, user_pol
;
1297 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1300 enum lsa_SidType type
;
1303 d_fprintf(stderr
, "usage: %s <username>\n", ctx
->whoami
);
1304 return NT_STATUS_INVALID_PARAMETER
;
1307 ZERO_STRUCT(connect_pol
);
1308 ZERO_STRUCT(domain_pol
);
1309 ZERO_STRUCT(user_pol
);
1311 result
= net_rpc_lookup_name(c
, mem_ctx
, rpc_pipe_np_smb_conn(pipe_hnd
),
1312 argv
[0], NULL
, NULL
, &sid
, &type
);
1313 if (!NT_STATUS_IS_OK(result
)) {
1314 d_fprintf(stderr
, "Could not lookup %s: %s\n", argv
[0],
1319 if (type
!= SID_NAME_USER
) {
1320 d_fprintf(stderr
, "%s is a %s, not a user\n", argv
[0],
1321 sid_type_lookup(type
));
1322 result
= NT_STATUS_NO_SUCH_USER
;
1326 if (!sid_peek_check_rid(ctx
->domain_sid
, &sid
, &rid
)) {
1327 d_fprintf(stderr
, "%s is not in our domain\n", argv
[0]);
1328 result
= NT_STATUS_NO_SUCH_USER
;
1332 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
1334 MAXIMUM_ALLOWED_ACCESS
,
1336 if (!NT_STATUS_IS_OK(result
)) {
1340 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
1342 MAXIMUM_ALLOWED_ACCESS
,
1345 if (!NT_STATUS_IS_OK(result
)) {
1349 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
1351 MAXIMUM_ALLOWED_ACCESS
,
1354 if (!NT_STATUS_IS_OK(result
)) {
1358 result
= fn(c
, mem_ctx
, ctx
, pipe_hnd
, &user_pol
, argc
-1, argv
+1);
1361 if (is_valid_policy_hnd(&user_pol
)) {
1362 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &user_pol
);
1364 if (is_valid_policy_hnd(&domain_pol
)) {
1365 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &domain_pol
);
1367 if (is_valid_policy_hnd(&connect_pol
)) {
1368 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
1373 static NTSTATUS
rpc_sh_user_show_internals(struct net_context
*c
,
1374 TALLOC_CTX
*mem_ctx
,
1375 struct rpc_sh_ctx
*ctx
,
1376 struct rpc_pipe_client
*pipe_hnd
,
1377 POLICY_HND
*user_hnd
,
1378 int argc
, const char **argv
)
1381 union samr_UserInfo
*info
= NULL
;
1384 d_fprintf(stderr
, "usage: %s show <username>\n", ctx
->whoami
);
1385 return NT_STATUS_INVALID_PARAMETER
;
1388 result
= rpccli_samr_QueryUserInfo(pipe_hnd
, mem_ctx
,
1392 if (!NT_STATUS_IS_OK(result
)) {
1396 d_printf("user rid: %d, group rid: %d\n",
1398 info
->info21
.primary_gid
);
1403 static NTSTATUS
rpc_sh_user_show(struct net_context
*c
,
1404 TALLOC_CTX
*mem_ctx
,
1405 struct rpc_sh_ctx
*ctx
,
1406 struct rpc_pipe_client
*pipe_hnd
,
1407 int argc
, const char **argv
)
1409 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1410 rpc_sh_user_show_internals
);
1413 #define FETCHSTR(name, rec) \
1414 do { if (strequal(ctx->thiscmd, name)) { \
1415 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1418 #define SETSTR(name, rec, flag) \
1419 do { if (strequal(ctx->thiscmd, name)) { \
1420 init_lsa_String(&(info->info21.rec), argv[0]); \
1421 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1424 static NTSTATUS
rpc_sh_user_str_edit_internals(struct net_context
*c
,
1425 TALLOC_CTX
*mem_ctx
,
1426 struct rpc_sh_ctx
*ctx
,
1427 struct rpc_pipe_client
*pipe_hnd
,
1428 POLICY_HND
*user_hnd
,
1429 int argc
, const char **argv
)
1432 const char *username
;
1433 const char *oldval
= "";
1434 union samr_UserInfo
*info
= NULL
;
1437 d_fprintf(stderr
, "usage: %s <username> [new value|NULL]\n",
1439 return NT_STATUS_INVALID_PARAMETER
;
1442 result
= rpccli_samr_QueryUserInfo(pipe_hnd
, mem_ctx
,
1446 if (!NT_STATUS_IS_OK(result
)) {
1450 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1452 FETCHSTR("fullname", full_name
);
1453 FETCHSTR("homedir", home_directory
);
1454 FETCHSTR("homedrive", home_drive
);
1455 FETCHSTR("logonscript", logon_script
);
1456 FETCHSTR("profilepath", profile_path
);
1457 FETCHSTR("description", description
);
1460 d_printf("%s's %s: [%s]\n", username
, ctx
->thiscmd
, oldval
);
1464 if (strcmp(argv
[0], "NULL") == 0) {
1468 ZERO_STRUCT(info
->info21
);
1470 SETSTR("fullname", full_name
, FULL_NAME
);
1471 SETSTR("homedir", home_directory
, HOME_DIRECTORY
);
1472 SETSTR("homedrive", home_drive
, HOME_DRIVE
);
1473 SETSTR("logonscript", logon_script
, LOGON_SCRIPT
);
1474 SETSTR("profilepath", profile_path
, PROFILE_PATH
);
1475 SETSTR("description", description
, DESCRIPTION
);
1477 result
= rpccli_samr_SetUserInfo(pipe_hnd
, mem_ctx
,
1482 d_printf("Set %s's %s from [%s] to [%s]\n", username
,
1483 ctx
->thiscmd
, oldval
, argv
[0]);
1490 #define HANDLEFLG(name, rec) \
1491 do { if (strequal(ctx->thiscmd, name)) { \
1492 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1494 newflags = oldflags | ACB_##rec; \
1496 newflags = oldflags & ~ACB_##rec; \
1499 static NTSTATUS
rpc_sh_user_str_edit(struct net_context
*c
,
1500 TALLOC_CTX
*mem_ctx
,
1501 struct rpc_sh_ctx
*ctx
,
1502 struct rpc_pipe_client
*pipe_hnd
,
1503 int argc
, const char **argv
)
1505 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1506 rpc_sh_user_str_edit_internals
);
1509 static NTSTATUS
rpc_sh_user_flag_edit_internals(struct net_context
*c
,
1510 TALLOC_CTX
*mem_ctx
,
1511 struct rpc_sh_ctx
*ctx
,
1512 struct rpc_pipe_client
*pipe_hnd
,
1513 POLICY_HND
*user_hnd
,
1514 int argc
, const char **argv
)
1517 const char *username
;
1518 const char *oldval
= "unknown";
1519 uint32 oldflags
, newflags
;
1521 union samr_UserInfo
*info
= NULL
;
1524 ((argc
== 1) && !strequal(argv
[0], "yes") &&
1525 !strequal(argv
[0], "no"))) {
1526 d_fprintf(stderr
, "usage: %s <username> [yes|no]\n",
1528 return NT_STATUS_INVALID_PARAMETER
;
1531 newval
= strequal(argv
[0], "yes");
1533 result
= rpccli_samr_QueryUserInfo(pipe_hnd
, mem_ctx
,
1537 if (!NT_STATUS_IS_OK(result
)) {
1541 username
= talloc_strdup(mem_ctx
, info
->info21
.account_name
.string
);
1542 oldflags
= info
->info21
.acct_flags
;
1543 newflags
= info
->info21
.acct_flags
;
1545 HANDLEFLG("disabled", DISABLED
);
1546 HANDLEFLG("pwnotreq", PWNOTREQ
);
1547 HANDLEFLG("autolock", AUTOLOCK
);
1548 HANDLEFLG("pwnoexp", PWNOEXP
);
1551 d_printf("%s's %s flag: %s\n", username
, ctx
->thiscmd
, oldval
);
1555 ZERO_STRUCT(info
->info21
);
1557 info
->info21
.acct_flags
= newflags
;
1558 info
->info21
.fields_present
= SAMR_FIELD_ACCT_FLAGS
;
1560 result
= rpccli_samr_SetUserInfo(pipe_hnd
, mem_ctx
,
1565 if (NT_STATUS_IS_OK(result
)) {
1566 d_printf("Set %s's %s flag from [%s] to [%s]\n", username
,
1567 ctx
->thiscmd
, oldval
, argv
[0]);
1575 static NTSTATUS
rpc_sh_user_flag_edit(struct net_context
*c
,
1576 TALLOC_CTX
*mem_ctx
,
1577 struct rpc_sh_ctx
*ctx
,
1578 struct rpc_pipe_client
*pipe_hnd
,
1579 int argc
, const char **argv
)
1581 return rpc_sh_handle_user(c
, mem_ctx
, ctx
, pipe_hnd
, argc
, argv
,
1582 rpc_sh_user_flag_edit_internals
);
1585 struct rpc_sh_cmd
*net_rpc_user_edit_cmds(struct net_context
*c
,
1586 TALLOC_CTX
*mem_ctx
,
1587 struct rpc_sh_ctx
*ctx
)
1589 static struct rpc_sh_cmd cmds
[] = {
1591 { "fullname", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1592 "Show/Set a user's full name" },
1594 { "homedir", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1595 "Show/Set a user's home directory" },
1597 { "homedrive", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1598 "Show/Set a user's home drive" },
1600 { "logonscript", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1601 "Show/Set a user's logon script" },
1603 { "profilepath", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1604 "Show/Set a user's profile path" },
1606 { "description", NULL
, PI_SAMR
, rpc_sh_user_str_edit
,
1607 "Show/Set a user's description" },
1609 { "disabled", NULL
, PI_SAMR
, rpc_sh_user_flag_edit
,
1610 "Show/Set whether a user is disabled" },
1612 { "autolock", NULL
, PI_SAMR
, rpc_sh_user_flag_edit
,
1613 "Show/Set whether a user locked out" },
1615 { "pwnotreq", NULL
, PI_SAMR
, rpc_sh_user_flag_edit
,
1616 "Show/Set whether a user does not need a password" },
1618 { "pwnoexp", NULL
, PI_SAMR
, rpc_sh_user_flag_edit
,
1619 "Show/Set whether a user's password does not expire" },
1621 { NULL
, NULL
, 0, NULL
, NULL
}
1627 struct rpc_sh_cmd
*net_rpc_user_cmds(struct net_context
*c
,
1628 TALLOC_CTX
*mem_ctx
,
1629 struct rpc_sh_ctx
*ctx
)
1631 static struct rpc_sh_cmd cmds
[] = {
1633 { "list", NULL
, PI_SAMR
, rpc_sh_user_list
,
1634 "List available users" },
1636 { "info", NULL
, PI_SAMR
, rpc_sh_user_info
,
1637 "List the domain groups a user is member of" },
1639 { "show", NULL
, PI_SAMR
, rpc_sh_user_show
,
1640 "Show info about a user" },
1642 { "edit", net_rpc_user_edit_cmds
, 0, NULL
,
1643 "Show/Modify a user's fields" },
1645 { NULL
, NULL
, 0, NULL
, NULL
}
1651 /****************************************************************************/
1654 * Basic usage function for 'net rpc group'.
1655 * @param argc Standard main() style argc.
1656 * @param argv Standard main() style argv. Initial components are already
1660 static int rpc_group_usage(struct net_context
*c
, int argc
, const char **argv
)
1662 return net_group_usage(c
, argc
, argv
);
1666 * Delete group on a remote RPC server.
1668 * All parameters are provided by the run_rpc_command function, except for
1669 * argc, argv which are passed through.
1671 * @param domain_sid The domain sid acquired from the remote server.
1672 * @param cli A cli_state connected to the server.
1673 * @param mem_ctx Talloc context, destroyed on completion of the function.
1674 * @param argc Standard main() style argc.
1675 * @param argv Standard main() style argv. Initial components are already
1678 * @return Normal NTSTATUS return.
1681 static NTSTATUS
rpc_group_delete_internals(struct net_context
*c
,
1682 const DOM_SID
*domain_sid
,
1683 const char *domain_name
,
1684 struct cli_state
*cli
,
1685 struct rpc_pipe_client
*pipe_hnd
,
1686 TALLOC_CTX
*mem_ctx
,
1690 POLICY_HND connect_pol
, domain_pol
, group_pol
, user_pol
;
1691 bool group_is_primary
= false;
1692 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1694 struct samr_RidTypeArray
*rids
= NULL
;
1697 /* DOM_GID *user_gids; */
1699 struct samr_Ids group_rids
, name_types
;
1700 struct lsa_String lsa_acct_name
;
1701 union samr_UserInfo
*info
= NULL
;
1703 if (argc
< 1 || c
->display_usage
) {
1704 rpc_group_usage(c
, argc
,argv
);
1705 return NT_STATUS_OK
; /* ok? */
1708 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
1710 MAXIMUM_ALLOWED_ACCESS
,
1713 if (!NT_STATUS_IS_OK(result
)) {
1714 d_fprintf(stderr
, "Request samr_Connect2 failed\n");
1718 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
1720 MAXIMUM_ALLOWED_ACCESS
,
1721 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
1724 if (!NT_STATUS_IS_OK(result
)) {
1725 d_fprintf(stderr
, "Request open_domain failed\n");
1729 init_lsa_String(&lsa_acct_name
, argv
[0]);
1731 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
1737 if (!NT_STATUS_IS_OK(result
)) {
1738 d_fprintf(stderr
, "Lookup of '%s' failed\n",argv
[0]);
1742 switch (name_types
.ids
[0])
1744 case SID_NAME_DOM_GRP
:
1745 result
= rpccli_samr_OpenGroup(pipe_hnd
, mem_ctx
,
1747 MAXIMUM_ALLOWED_ACCESS
,
1750 if (!NT_STATUS_IS_OK(result
)) {
1751 d_fprintf(stderr
, "Request open_group failed");
1755 group_rid
= group_rids
.ids
[0];
1757 result
= rpccli_samr_QueryGroupMember(pipe_hnd
, mem_ctx
,
1761 if (!NT_STATUS_IS_OK(result
)) {
1762 d_fprintf(stderr
, "Unable to query group members of %s",argv
[0]);
1766 if (c
->opt_verbose
) {
1767 d_printf("Domain Group %s (rid: %d) has %d members\n",
1768 argv
[0],group_rid
, rids
->count
);
1771 /* Check if group is anyone's primary group */
1772 for (i
= 0; i
< rids
->count
; i
++)
1774 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
1776 MAXIMUM_ALLOWED_ACCESS
,
1780 if (!NT_STATUS_IS_OK(result
)) {
1781 d_fprintf(stderr
, "Unable to open group member %d\n",
1786 result
= rpccli_samr_QueryUserInfo(pipe_hnd
, mem_ctx
,
1791 if (!NT_STATUS_IS_OK(result
)) {
1792 d_fprintf(stderr
, "Unable to lookup userinfo for group member %d\n",
1797 if (info
->info21
.primary_gid
== group_rid
) {
1798 if (c
->opt_verbose
) {
1799 d_printf("Group is primary group of %s\n",
1800 info
->info21
.account_name
.string
);
1802 group_is_primary
= true;
1805 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &user_pol
);
1808 if (group_is_primary
) {
1809 d_fprintf(stderr
, "Unable to delete group because some "
1810 "of it's members have it as primary group\n");
1811 result
= NT_STATUS_MEMBERS_PRIMARY_GROUP
;
1815 /* remove all group members */
1816 for (i
= 0; i
< rids
->count
; i
++)
1819 d_printf("Remove group member %d...",
1821 result
= rpccli_samr_DeleteGroupMember(pipe_hnd
, mem_ctx
,
1825 if (NT_STATUS_IS_OK(result
)) {
1830 d_printf("failed\n");
1835 result
= rpccli_samr_DeleteDomainGroup(pipe_hnd
, mem_ctx
,
1839 /* removing a local group is easier... */
1840 case SID_NAME_ALIAS
:
1841 result
= rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
1843 MAXIMUM_ALLOWED_ACCESS
,
1847 if (!NT_STATUS_IS_OK(result
)) {
1848 d_fprintf(stderr
, "Request open_alias failed\n");
1852 result
= rpccli_samr_DeleteDomAlias(pipe_hnd
, mem_ctx
,
1856 d_fprintf(stderr
, "%s is of type %s. This command is only for deleting local or global groups\n",
1857 argv
[0],sid_type_lookup(name_types
.ids
[0]));
1858 result
= NT_STATUS_UNSUCCESSFUL
;
1862 if (NT_STATUS_IS_OK(result
)) {
1864 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types
.ids
[0]),argv
[0]);
1866 d_fprintf(stderr
, "Deleting of %s failed: %s\n",argv
[0],
1867 get_friendly_nt_error_msg(result
));
1875 static int rpc_group_delete(struct net_context
*c
, int argc
, const char **argv
)
1877 return run_rpc_command(c
, NULL
, PI_SAMR
, 0, rpc_group_delete_internals
,
1881 static int rpc_group_add_internals(struct net_context
*c
, int argc
, const char **argv
)
1883 NET_API_STATUS status
;
1884 struct GROUP_INFO_1 info1
;
1885 uint32_t parm_error
= 0;
1887 if (argc
!= 1 || c
->display_usage
) {
1888 rpc_group_usage(c
, argc
, argv
);
1894 info1
.grpi1_name
= argv
[0];
1895 if (c
->opt_comment
&& strlen(c
->opt_comment
) > 0) {
1896 info1
.grpi1_comment
= c
->opt_comment
;
1899 status
= NetGroupAdd(c
->opt_host
, 1, (uint8_t *)&info1
, &parm_error
);
1902 d_fprintf(stderr
, "Failed to add group '%s' with: %s.\n",
1903 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
1907 d_printf("Added group '%s'.\n", argv
[0]);
1913 static NTSTATUS
rpc_alias_add_internals(struct net_context
*c
,
1914 const DOM_SID
*domain_sid
,
1915 const char *domain_name
,
1916 struct cli_state
*cli
,
1917 struct rpc_pipe_client
*pipe_hnd
,
1918 TALLOC_CTX
*mem_ctx
,
1922 POLICY_HND connect_pol
, domain_pol
, alias_pol
;
1923 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1924 union samr_AliasInfo alias_info
;
1925 struct lsa_String alias_name
;
1928 if (argc
!= 1 || c
->display_usage
) {
1929 rpc_group_usage(c
, argc
, argv
);
1930 return NT_STATUS_OK
;
1933 init_lsa_String(&alias_name
, argv
[0]);
1935 /* Get sam policy handle */
1937 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
1939 MAXIMUM_ALLOWED_ACCESS
,
1941 if (!NT_STATUS_IS_OK(result
)) goto done
;
1943 /* Get domain policy handle */
1945 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
1947 MAXIMUM_ALLOWED_ACCESS
,
1948 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
1950 if (!NT_STATUS_IS_OK(result
)) goto done
;
1952 /* Create the group */
1954 result
= rpccli_samr_CreateDomAlias(pipe_hnd
, mem_ctx
,
1957 MAXIMUM_ALLOWED_ACCESS
,
1960 if (!NT_STATUS_IS_OK(result
)) goto done
;
1962 if (strlen(c
->opt_comment
) == 0) goto done
;
1964 /* We've got a comment to set */
1966 init_lsa_String(&alias_info
.description
, c
->opt_comment
);
1968 result
= rpccli_samr_SetAliasInfo(pipe_hnd
, mem_ctx
,
1973 if (!NT_STATUS_IS_OK(result
)) goto done
;
1976 if (NT_STATUS_IS_OK(result
))
1977 DEBUG(5, ("add alias succeeded\n"));
1979 d_fprintf(stderr
, "add alias failed: %s\n", nt_errstr(result
));
1984 static int rpc_group_add(struct net_context
*c
, int argc
, const char **argv
)
1986 if (c
->opt_localgroup
)
1987 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
1988 rpc_alias_add_internals
,
1991 return rpc_group_add_internals(c
, argc
, argv
);
1994 static NTSTATUS
get_sid_from_name(struct cli_state
*cli
,
1995 TALLOC_CTX
*mem_ctx
,
1998 enum lsa_SidType
*type
)
2000 DOM_SID
*sids
= NULL
;
2001 enum lsa_SidType
*types
= NULL
;
2002 struct rpc_pipe_client
*pipe_hnd
;
2004 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2006 result
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
.syntax_id
,
2008 if (!NT_STATUS_IS_OK(result
)) {
2012 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, false,
2013 SEC_RIGHTS_MAXIMUM_ALLOWED
, &lsa_pol
);
2015 if (!NT_STATUS_IS_OK(result
)) {
2019 result
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
2020 &name
, NULL
, 1, &sids
, &types
);
2022 if (NT_STATUS_IS_OK(result
)) {
2023 sid_copy(sid
, &sids
[0]);
2027 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &lsa_pol
);
2031 TALLOC_FREE(pipe_hnd
);
2034 if (!NT_STATUS_IS_OK(result
) && (StrnCaseCmp(name
, "S-", 2) == 0)) {
2036 /* Try as S-1-5-whatever */
2040 if (string_to_sid(&tmp_sid
, name
)) {
2041 sid_copy(sid
, &tmp_sid
);
2042 *type
= SID_NAME_UNKNOWN
;
2043 result
= NT_STATUS_OK
;
2050 static NTSTATUS
rpc_add_groupmem(struct rpc_pipe_client
*pipe_hnd
,
2051 TALLOC_CTX
*mem_ctx
,
2052 const DOM_SID
*group_sid
,
2055 POLICY_HND connect_pol
, domain_pol
;
2058 POLICY_HND group_pol
;
2060 struct samr_Ids rids
, rid_types
;
2061 struct lsa_String lsa_acct_name
;
2065 sid_copy(&sid
, group_sid
);
2067 if (!sid_split_rid(&sid
, &group_rid
)) {
2068 return NT_STATUS_UNSUCCESSFUL
;
2071 /* Get sam policy handle */
2072 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2074 MAXIMUM_ALLOWED_ACCESS
,
2076 if (!NT_STATUS_IS_OK(result
)) {
2080 /* Get domain policy handle */
2081 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2083 MAXIMUM_ALLOWED_ACCESS
,
2086 if (!NT_STATUS_IS_OK(result
)) {
2090 init_lsa_String(&lsa_acct_name
, member
);
2092 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
2099 if (!NT_STATUS_IS_OK(result
)) {
2100 d_fprintf(stderr
, "Could not lookup up group member %s\n", member
);
2104 result
= rpccli_samr_OpenGroup(pipe_hnd
, mem_ctx
,
2106 MAXIMUM_ALLOWED_ACCESS
,
2110 if (!NT_STATUS_IS_OK(result
)) {
2114 result
= rpccli_samr_AddGroupMember(pipe_hnd
, mem_ctx
,
2117 0x0005); /* unknown flags */
2120 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
2124 static NTSTATUS
rpc_add_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2125 TALLOC_CTX
*mem_ctx
,
2126 const DOM_SID
*alias_sid
,
2129 POLICY_HND connect_pol
, domain_pol
;
2132 POLICY_HND alias_pol
;
2135 enum lsa_SidType member_type
;
2139 sid_copy(&sid
, alias_sid
);
2141 if (!sid_split_rid(&sid
, &alias_rid
)) {
2142 return NT_STATUS_UNSUCCESSFUL
;
2145 result
= get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd
), mem_ctx
,
2146 member
, &member_sid
, &member_type
);
2148 if (!NT_STATUS_IS_OK(result
)) {
2149 d_fprintf(stderr
, "Could not lookup up group member %s\n", member
);
2153 /* Get sam policy handle */
2154 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2156 MAXIMUM_ALLOWED_ACCESS
,
2158 if (!NT_STATUS_IS_OK(result
)) {
2162 /* Get domain policy handle */
2163 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2165 MAXIMUM_ALLOWED_ACCESS
,
2168 if (!NT_STATUS_IS_OK(result
)) {
2172 result
= rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
2174 MAXIMUM_ALLOWED_ACCESS
,
2178 if (!NT_STATUS_IS_OK(result
)) {
2182 result
= rpccli_samr_AddAliasMember(pipe_hnd
, mem_ctx
,
2186 if (!NT_STATUS_IS_OK(result
)) {
2191 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
2195 static NTSTATUS
rpc_group_addmem_internals(struct net_context
*c
,
2196 const DOM_SID
*domain_sid
,
2197 const char *domain_name
,
2198 struct cli_state
*cli
,
2199 struct rpc_pipe_client
*pipe_hnd
,
2200 TALLOC_CTX
*mem_ctx
,
2205 enum lsa_SidType group_type
;
2207 if (argc
!= 2 || c
->display_usage
) {
2209 "net rpc group addmem <group> <member>\n"
2210 " Add a member to a group\n"
2211 " group\tGroup to add member to\n"
2212 " member\tMember to add to group\n");
2213 return NT_STATUS_UNSUCCESSFUL
;
2216 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2217 &group_sid
, &group_type
))) {
2218 d_fprintf(stderr
, "Could not lookup group name %s\n", argv
[0]);
2219 return NT_STATUS_UNSUCCESSFUL
;
2222 if (group_type
== SID_NAME_DOM_GRP
) {
2223 NTSTATUS result
= rpc_add_groupmem(pipe_hnd
, mem_ctx
,
2224 &group_sid
, argv
[1]);
2226 if (!NT_STATUS_IS_OK(result
)) {
2227 d_fprintf(stderr
, "Could not add %s to %s: %s\n",
2228 argv
[1], argv
[0], nt_errstr(result
));
2233 if (group_type
== SID_NAME_ALIAS
) {
2234 NTSTATUS result
= rpc_add_aliasmem(pipe_hnd
, mem_ctx
,
2235 &group_sid
, argv
[1]);
2237 if (!NT_STATUS_IS_OK(result
)) {
2238 d_fprintf(stderr
, "Could not add %s to %s: %s\n",
2239 argv
[1], argv
[0], nt_errstr(result
));
2244 d_fprintf(stderr
, "Can only add members to global or local groups "
2245 "which %s is not\n", argv
[0]);
2247 return NT_STATUS_UNSUCCESSFUL
;
2250 static int rpc_group_addmem(struct net_context
*c
, int argc
, const char **argv
)
2252 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
2253 rpc_group_addmem_internals
,
2257 static NTSTATUS
rpc_del_groupmem(struct net_context
*c
,
2258 struct rpc_pipe_client
*pipe_hnd
,
2259 TALLOC_CTX
*mem_ctx
,
2260 const DOM_SID
*group_sid
,
2263 POLICY_HND connect_pol
, domain_pol
;
2266 POLICY_HND group_pol
;
2268 struct samr_Ids rids
, rid_types
;
2269 struct lsa_String lsa_acct_name
;
2273 sid_copy(&sid
, group_sid
);
2275 if (!sid_split_rid(&sid
, &group_rid
))
2276 return NT_STATUS_UNSUCCESSFUL
;
2278 /* Get sam policy handle */
2279 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2281 MAXIMUM_ALLOWED_ACCESS
,
2283 if (!NT_STATUS_IS_OK(result
))
2286 /* Get domain policy handle */
2287 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2289 MAXIMUM_ALLOWED_ACCESS
,
2292 if (!NT_STATUS_IS_OK(result
))
2295 init_lsa_String(&lsa_acct_name
, member
);
2297 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
2303 if (!NT_STATUS_IS_OK(result
)) {
2304 d_fprintf(stderr
, "Could not lookup up group member %s\n", member
);
2308 result
= rpccli_samr_OpenGroup(pipe_hnd
, mem_ctx
,
2310 MAXIMUM_ALLOWED_ACCESS
,
2314 if (!NT_STATUS_IS_OK(result
))
2317 result
= rpccli_samr_DeleteGroupMember(pipe_hnd
, mem_ctx
,
2322 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
2326 static NTSTATUS
rpc_del_aliasmem(struct rpc_pipe_client
*pipe_hnd
,
2327 TALLOC_CTX
*mem_ctx
,
2328 const DOM_SID
*alias_sid
,
2331 POLICY_HND connect_pol
, domain_pol
;
2334 POLICY_HND alias_pol
;
2337 enum lsa_SidType member_type
;
2341 sid_copy(&sid
, alias_sid
);
2343 if (!sid_split_rid(&sid
, &alias_rid
))
2344 return NT_STATUS_UNSUCCESSFUL
;
2346 result
= get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd
), mem_ctx
,
2347 member
, &member_sid
, &member_type
);
2349 if (!NT_STATUS_IS_OK(result
)) {
2350 d_fprintf(stderr
, "Could not lookup up group member %s\n", member
);
2354 /* Get sam policy handle */
2355 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2357 MAXIMUM_ALLOWED_ACCESS
,
2359 if (!NT_STATUS_IS_OK(result
)) {
2363 /* Get domain policy handle */
2364 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2366 MAXIMUM_ALLOWED_ACCESS
,
2369 if (!NT_STATUS_IS_OK(result
)) {
2373 result
= rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
2375 MAXIMUM_ALLOWED_ACCESS
,
2379 if (!NT_STATUS_IS_OK(result
))
2382 result
= rpccli_samr_DeleteAliasMember(pipe_hnd
, mem_ctx
,
2386 if (!NT_STATUS_IS_OK(result
))
2390 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
2394 static NTSTATUS
rpc_group_delmem_internals(struct net_context
*c
,
2395 const DOM_SID
*domain_sid
,
2396 const char *domain_name
,
2397 struct cli_state
*cli
,
2398 struct rpc_pipe_client
*pipe_hnd
,
2399 TALLOC_CTX
*mem_ctx
,
2404 enum lsa_SidType group_type
;
2406 if (argc
!= 2 || c
->display_usage
) {
2408 "net rpc group delmem <group> <member>\n"
2409 " Delete a member from a group\n"
2410 " group\tGroup to delete member from\n"
2411 " member\tMember to delete from group\n");
2412 return NT_STATUS_UNSUCCESSFUL
;
2415 if (!NT_STATUS_IS_OK(get_sid_from_name(cli
, mem_ctx
, argv
[0],
2416 &group_sid
, &group_type
))) {
2417 d_fprintf(stderr
, "Could not lookup group name %s\n", argv
[0]);
2418 return NT_STATUS_UNSUCCESSFUL
;
2421 if (group_type
== SID_NAME_DOM_GRP
) {
2422 NTSTATUS result
= rpc_del_groupmem(c
, pipe_hnd
, mem_ctx
,
2423 &group_sid
, argv
[1]);
2425 if (!NT_STATUS_IS_OK(result
)) {
2426 d_fprintf(stderr
, "Could not del %s from %s: %s\n",
2427 argv
[1], argv
[0], nt_errstr(result
));
2432 if (group_type
== SID_NAME_ALIAS
) {
2433 NTSTATUS result
= rpc_del_aliasmem(pipe_hnd
, mem_ctx
,
2434 &group_sid
, argv
[1]);
2436 if (!NT_STATUS_IS_OK(result
)) {
2437 d_fprintf(stderr
, "Could not del %s from %s: %s\n",
2438 argv
[1], argv
[0], nt_errstr(result
));
2443 d_fprintf(stderr
, "Can only delete members from global or local groups "
2444 "which %s is not\n", argv
[0]);
2446 return NT_STATUS_UNSUCCESSFUL
;
2449 static int rpc_group_delmem(struct net_context
*c
, int argc
, const char **argv
)
2451 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
2452 rpc_group_delmem_internals
,
2457 * List groups on a remote RPC server.
2459 * All parameters are provided by the run_rpc_command function, except for
2460 * argc, argv which are passes through.
2462 * @param domain_sid The domain sid acquired from the remote server.
2463 * @param cli A cli_state connected to the server.
2464 * @param mem_ctx Talloc context, destroyed on completion of the function.
2465 * @param argc Standard main() style argc.
2466 * @param argv Standard main() style argv. Initial components are already
2469 * @return Normal NTSTATUS return.
2472 static NTSTATUS
rpc_group_list_internals(struct net_context
*c
,
2473 const DOM_SID
*domain_sid
,
2474 const char *domain_name
,
2475 struct cli_state
*cli
,
2476 struct rpc_pipe_client
*pipe_hnd
,
2477 TALLOC_CTX
*mem_ctx
,
2481 POLICY_HND connect_pol
, domain_pol
;
2482 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2483 uint32 start_idx
=0, max_entries
=250, num_entries
, i
, loop_count
= 0;
2484 struct samr_SamArray
*groups
= NULL
;
2485 bool global
= false;
2487 bool builtin
= false;
2489 if (c
->display_usage
) {
2491 "net rpc group list [global] [local] [builtin]\n"
2492 " List groups on RPC server\n"
2493 " global\tList global groups\n"
2494 " local\tList local groups\n"
2495 " builtin\tList builtin groups\n"
2496 " If none of global, local or builtin is "
2497 "specified, all three options are considered set\n");
2498 return NT_STATUS_OK
;
2507 for (i
=0; i
<argc
; i
++) {
2508 if (strequal(argv
[i
], "global"))
2511 if (strequal(argv
[i
], "local"))
2514 if (strequal(argv
[i
], "builtin"))
2518 /* Get sam policy handle */
2520 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2522 MAXIMUM_ALLOWED_ACCESS
,
2524 if (!NT_STATUS_IS_OK(result
)) {
2528 /* Get domain policy handle */
2530 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2532 MAXIMUM_ALLOWED_ACCESS
,
2533 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
2535 if (!NT_STATUS_IS_OK(result
)) {
2539 /* Query domain groups */
2540 if (c
->opt_long_list_entries
)
2541 d_printf("\nGroup name Comment"
2542 "\n-----------------------------\n");
2544 uint32_t max_size
, total_size
, returned_size
;
2545 union samr_DispInfo info
;
2549 get_query_dispinfo_params(
2550 loop_count
, &max_entries
, &max_size
);
2552 result
= rpccli_samr_QueryDisplayInfo(pipe_hnd
, mem_ctx
,
2561 num_entries
= info
.info3
.count
;
2562 start_idx
+= info
.info3
.count
;
2564 if (!NT_STATUS_IS_OK(result
) &&
2565 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2568 for (i
= 0; i
< num_entries
; i
++) {
2570 const char *group
= NULL
;
2571 const char *desc
= NULL
;
2573 group
= info
.info3
.entries
[i
].account_name
.string
;
2574 desc
= info
.info3
.entries
[i
].description
.string
;
2576 if (c
->opt_long_list_entries
)
2577 printf("%-21.21s %-50.50s\n",
2580 printf("%s\n", group
);
2582 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2583 /* query domain aliases */
2588 result
= rpccli_samr_EnumDomainAliases(pipe_hnd
, mem_ctx
,
2594 if (!NT_STATUS_IS_OK(result
) &&
2595 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2598 for (i
= 0; i
< num_entries
; i
++) {
2600 const char *description
= NULL
;
2602 if (c
->opt_long_list_entries
) {
2604 POLICY_HND alias_pol
;
2605 union samr_AliasInfo
*info
= NULL
;
2607 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
2610 groups
->entries
[i
].idx
,
2612 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd
, mem_ctx
,
2616 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd
, mem_ctx
,
2618 description
= info
->description
.string
;
2622 if (description
!= NULL
) {
2623 printf("%-21.21s %-50.50s\n",
2624 groups
->entries
[i
].name
.string
,
2627 printf("%s\n", groups
->entries
[i
].name
.string
);
2630 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2631 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &domain_pol
);
2632 /* Get builtin policy handle */
2634 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2636 MAXIMUM_ALLOWED_ACCESS
,
2637 CONST_DISCARD(struct dom_sid2
*, &global_sid_Builtin
),
2639 if (!NT_STATUS_IS_OK(result
)) {
2642 /* query builtin aliases */
2645 if (!builtin
) break;
2647 result
= rpccli_samr_EnumDomainAliases(pipe_hnd
, mem_ctx
,
2653 if (!NT_STATUS_IS_OK(result
) &&
2654 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
2657 for (i
= 0; i
< num_entries
; i
++) {
2659 const char *description
= NULL
;
2661 if (c
->opt_long_list_entries
) {
2663 POLICY_HND alias_pol
;
2664 union samr_AliasInfo
*info
= NULL
;
2666 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
2669 groups
->entries
[i
].idx
,
2671 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd
, mem_ctx
,
2675 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd
, mem_ctx
,
2677 description
= info
->description
.string
;
2681 if (description
!= NULL
) {
2682 printf("%-21.21s %-50.50s\n",
2683 groups
->entries
[i
].name
.string
,
2686 printf("%s\n", groups
->entries
[i
].name
.string
);
2689 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2695 static int rpc_group_list(struct net_context
*c
, int argc
, const char **argv
)
2697 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
2698 rpc_group_list_internals
,
2702 static NTSTATUS
rpc_list_group_members(struct net_context
*c
,
2703 struct rpc_pipe_client
*pipe_hnd
,
2704 TALLOC_CTX
*mem_ctx
,
2705 const char *domain_name
,
2706 const DOM_SID
*domain_sid
,
2707 POLICY_HND
*domain_pol
,
2711 POLICY_HND group_pol
;
2712 uint32 num_members
, *group_rids
;
2714 struct samr_RidTypeArray
*rids
= NULL
;
2715 struct lsa_Strings names
;
2716 struct samr_Ids types
;
2719 sid_to_fstring(sid_str
, domain_sid
);
2721 result
= rpccli_samr_OpenGroup(pipe_hnd
, mem_ctx
,
2723 MAXIMUM_ALLOWED_ACCESS
,
2727 if (!NT_STATUS_IS_OK(result
))
2730 result
= rpccli_samr_QueryGroupMember(pipe_hnd
, mem_ctx
,
2734 if (!NT_STATUS_IS_OK(result
))
2737 num_members
= rids
->count
;
2738 group_rids
= rids
->rids
;
2740 while (num_members
> 0) {
2741 int this_time
= 512;
2743 if (num_members
< this_time
)
2744 this_time
= num_members
;
2746 result
= rpccli_samr_LookupRids(pipe_hnd
, mem_ctx
,
2753 if (!NT_STATUS_IS_OK(result
))
2756 /* We only have users as members, but make the output
2757 the same as the output of alias members */
2759 for (i
= 0; i
< this_time
; i
++) {
2761 if (c
->opt_long_list_entries
) {
2762 printf("%s-%d %s\\%s %d\n", sid_str
,
2763 group_rids
[i
], domain_name
,
2764 names
.names
[i
].string
,
2767 printf("%s\\%s\n", domain_name
,
2768 names
.names
[i
].string
);
2772 num_members
-= this_time
;
2776 return NT_STATUS_OK
;
2779 static NTSTATUS
rpc_list_alias_members(struct net_context
*c
,
2780 struct rpc_pipe_client
*pipe_hnd
,
2781 TALLOC_CTX
*mem_ctx
,
2782 POLICY_HND
*domain_pol
,
2786 struct rpc_pipe_client
*lsa_pipe
;
2787 POLICY_HND alias_pol
, lsa_pol
;
2789 DOM_SID
*alias_sids
;
2792 enum lsa_SidType
*types
;
2794 struct lsa_SidArray sid_array
;
2796 result
= rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
2798 MAXIMUM_ALLOWED_ACCESS
,
2802 if (!NT_STATUS_IS_OK(result
))
2805 result
= rpccli_samr_GetMembersInAlias(pipe_hnd
, mem_ctx
,
2809 if (!NT_STATUS_IS_OK(result
)) {
2810 d_fprintf(stderr
, "Couldn't list alias members\n");
2814 num_members
= sid_array
.num_sids
;
2816 if (num_members
== 0) {
2817 return NT_STATUS_OK
;
2820 result
= cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd
),
2821 &ndr_table_lsarpc
.syntax_id
,
2823 if (!NT_STATUS_IS_OK(result
)) {
2824 d_fprintf(stderr
, "Couldn't open LSA pipe. Error was %s\n",
2825 nt_errstr(result
) );
2829 result
= rpccli_lsa_open_policy(lsa_pipe
, mem_ctx
, true,
2830 SEC_RIGHTS_MAXIMUM_ALLOWED
, &lsa_pol
);
2832 if (!NT_STATUS_IS_OK(result
)) {
2833 d_fprintf(stderr
, "Couldn't open LSA policy handle\n");
2834 TALLOC_FREE(lsa_pipe
);
2838 alias_sids
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, num_members
);
2840 d_fprintf(stderr
, "Out of memory\n");
2841 TALLOC_FREE(lsa_pipe
);
2842 return NT_STATUS_NO_MEMORY
;
2845 for (i
=0; i
<num_members
; i
++) {
2846 sid_copy(&alias_sids
[i
], sid_array
.sids
[i
].sid
);
2849 result
= rpccli_lsa_lookup_sids(lsa_pipe
, mem_ctx
, &lsa_pol
,
2850 num_members
, alias_sids
,
2851 &domains
, &names
, &types
);
2853 if (!NT_STATUS_IS_OK(result
) &&
2854 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
2855 d_fprintf(stderr
, "Couldn't lookup SIDs\n");
2856 TALLOC_FREE(lsa_pipe
);
2860 for (i
= 0; i
< num_members
; i
++) {
2862 sid_to_fstring(sid_str
, &alias_sids
[i
]);
2864 if (c
->opt_long_list_entries
) {
2865 printf("%s %s\\%s %d\n", sid_str
,
2866 domains
[i
] ? domains
[i
] : "*unknown*",
2867 names
[i
] ? names
[i
] : "*unknown*", types
[i
]);
2870 printf("%s\\%s\n", domains
[i
], names
[i
]);
2872 printf("%s\n", sid_str
);
2876 TALLOC_FREE(lsa_pipe
);
2877 return NT_STATUS_OK
;
2880 static NTSTATUS
rpc_group_members_internals(struct net_context
*c
,
2881 const DOM_SID
*domain_sid
,
2882 const char *domain_name
,
2883 struct cli_state
*cli
,
2884 struct rpc_pipe_client
*pipe_hnd
,
2885 TALLOC_CTX
*mem_ctx
,
2890 POLICY_HND connect_pol
, domain_pol
;
2891 struct samr_Ids rids
, rid_types
;
2892 struct lsa_String lsa_acct_name
;
2894 /* Get sam policy handle */
2896 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
2898 MAXIMUM_ALLOWED_ACCESS
,
2901 if (!NT_STATUS_IS_OK(result
))
2904 /* Get domain policy handle */
2906 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2908 MAXIMUM_ALLOWED_ACCESS
,
2909 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
2912 if (!NT_STATUS_IS_OK(result
))
2915 init_lsa_String(&lsa_acct_name
, argv
[0]); /* sure? */
2917 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
2924 if (!NT_STATUS_IS_OK(result
)) {
2926 /* Ok, did not find it in the global sam, try with builtin */
2928 DOM_SID sid_Builtin
;
2930 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &domain_pol
);
2932 sid_copy(&sid_Builtin
, &global_sid_Builtin
);
2934 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
2936 MAXIMUM_ALLOWED_ACCESS
,
2940 if (!NT_STATUS_IS_OK(result
)) {
2941 d_fprintf(stderr
, "Couldn't find group %s\n", argv
[0]);
2945 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
2952 if (!NT_STATUS_IS_OK(result
)) {
2953 d_fprintf(stderr
, "Couldn't find group %s\n", argv
[0]);
2958 if (rids
.count
!= 1) {
2959 d_fprintf(stderr
, "Couldn't find group %s\n", argv
[0]);
2963 if (rid_types
.ids
[0] == SID_NAME_DOM_GRP
) {
2964 return rpc_list_group_members(c
, pipe_hnd
, mem_ctx
, domain_name
,
2965 domain_sid
, &domain_pol
,
2969 if (rid_types
.ids
[0] == SID_NAME_ALIAS
) {
2970 return rpc_list_alias_members(c
, pipe_hnd
, mem_ctx
, &domain_pol
,
2974 return NT_STATUS_NO_SUCH_GROUP
;
2977 static int rpc_group_members(struct net_context
*c
, int argc
, const char **argv
)
2979 if (argc
!= 1 || c
->display_usage
) {
2980 return rpc_group_usage(c
, argc
, argv
);
2983 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
2984 rpc_group_members_internals
,
2988 static int rpc_group_rename_internals(struct net_context
*c
, int argc
, const char **argv
)
2990 NET_API_STATUS status
;
2991 struct GROUP_INFO_0 g0
;
2995 d_printf("Usage: 'net rpc group rename group newname'\n");
2999 g0
.grpi0_name
= argv
[1];
3001 status
= NetGroupSetInfo(c
->opt_host
,
3008 d_fprintf(stderr
, "Renaming group %s failed with: %s\n",
3009 argv
[0], libnetapi_get_error_string(c
->netapi_ctx
,
3017 static int rpc_group_rename(struct net_context
*c
, int argc
, const char **argv
)
3019 if (argc
!= 2 || c
->display_usage
) {
3020 return rpc_group_usage(c
, argc
, argv
);
3023 return rpc_group_rename_internals(c
, argc
, argv
);
3027 * 'net rpc group' entrypoint.
3028 * @param argc Standard main() style argc.
3029 * @param argv Standard main() style argv. Initial components are already
3033 int net_rpc_group(struct net_context
*c
, int argc
, const char **argv
)
3035 NET_API_STATUS status
;
3037 struct functable func
[] = {
3042 "Create specified group",
3043 "net rpc group add\n"
3044 " Create specified group"
3050 "Delete specified group",
3051 "net rpc group delete\n"
3052 " Delete specified group"
3058 "Add member to group",
3059 "net rpc group addmem\n"
3060 " Add member to group"
3066 "Remove member from group",
3067 "net rpc group delmem\n"
3068 " Remove member from group"
3075 "net rpc group list\n"
3082 "List group members",
3083 "net rpc group members\n"
3084 " List group members"
3091 "net rpc group rename\n"
3094 {NULL
, NULL
, 0, NULL
, NULL
}
3097 status
= libnetapi_init(&c
->netapi_ctx
);
3101 libnetapi_set_username(c
->netapi_ctx
, c
->opt_user_name
);
3102 libnetapi_set_password(c
->netapi_ctx
, c
->opt_password
);
3105 if (c
->display_usage
) {
3106 d_printf("Usage:\n");
3107 d_printf("net rpc group\n"
3108 " Alias for net rpc group list global local "
3110 net_display_usage_from_functable(func
);
3114 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
3115 rpc_group_list_internals
,
3119 return net_run_function(c
, argc
, argv
, "net rpc group", func
);
3122 /****************************************************************************/
3124 static int rpc_share_usage(struct net_context
*c
, int argc
, const char **argv
)
3126 return net_share_usage(c
, argc
, argv
);
3130 * Add a share on a remote RPC server.
3132 * All parameters are provided by the run_rpc_command function, except for
3133 * argc, argv which are passed through.
3135 * @param domain_sid The domain sid acquired from the remote server.
3136 * @param cli A cli_state connected to the server.
3137 * @param mem_ctx Talloc context, destroyed on completion of the function.
3138 * @param argc Standard main() style argc.
3139 * @param argv Standard main() style argv. Initial components are already
3142 * @return Normal NTSTATUS return.
3144 static NTSTATUS
rpc_share_add_internals(struct net_context
*c
,
3145 const DOM_SID
*domain_sid
,
3146 const char *domain_name
,
3147 struct cli_state
*cli
,
3148 struct rpc_pipe_client
*pipe_hnd
,
3149 TALLOC_CTX
*mem_ctx
,int argc
,
3156 uint32 type
= STYPE_DISKTREE
; /* only allow disk shares to be added */
3157 uint32 num_users
=0, perms
=0;
3158 char *password
=NULL
; /* don't allow a share password */
3160 union srvsvc_NetShareInfo info
;
3161 struct srvsvc_NetShareInfo2 info2
;
3162 uint32_t parm_error
= 0;
3164 if ((sharename
= talloc_strdup(mem_ctx
, argv
[0])) == NULL
) {
3165 return NT_STATUS_NO_MEMORY
;
3168 path
= strchr(sharename
, '=');
3170 return NT_STATUS_UNSUCCESSFUL
;
3173 info2
.name
= sharename
;
3175 info2
.comment
= c
->opt_comment
;
3176 info2
.permissions
= perms
;
3177 info2
.max_users
= c
->opt_maxusers
;
3178 info2
.current_users
= num_users
;
3180 info2
.password
= password
;
3182 info
.info2
= &info2
;
3184 status
= rpccli_srvsvc_NetShareAdd(pipe_hnd
, mem_ctx
,
3193 static int rpc_share_add(struct net_context
*c
, int argc
, const char **argv
)
3195 if ((argc
< 1) || !strchr(argv
[0], '=') || c
->display_usage
) {
3196 return rpc_share_usage(c
, argc
, argv
);
3198 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
3199 rpc_share_add_internals
,
3204 * Delete a share on a remote RPC server.
3206 * All parameters are provided by the run_rpc_command function, except for
3207 * argc, argv which are passed through.
3209 * @param domain_sid The domain sid acquired from the remote server.
3210 * @param cli A cli_state connected to the server.
3211 * @param mem_ctx Talloc context, destroyed on completion of the function.
3212 * @param argc Standard main() style argc.
3213 * @param argv Standard main() style argv. Initial components are already
3216 * @return Normal NTSTATUS return.
3218 static NTSTATUS
rpc_share_del_internals(struct net_context
*c
,
3219 const DOM_SID
*domain_sid
,
3220 const char *domain_name
,
3221 struct cli_state
*cli
,
3222 struct rpc_pipe_client
*pipe_hnd
,
3223 TALLOC_CTX
*mem_ctx
,
3229 return rpccli_srvsvc_NetShareDel(pipe_hnd
, mem_ctx
,
3237 * Delete a share on a remote RPC server.
3239 * @param domain_sid The domain sid acquired from the remote server.
3240 * @param argc Standard main() style argc.
3241 * @param argv Standard main() style argv. Initial components are already
3244 * @return A shell status integer (0 for success).
3246 static int rpc_share_delete(struct net_context
*c
, int argc
, const char **argv
)
3248 if (argc
< 1 || c
->display_usage
) {
3249 return rpc_share_usage(c
, argc
, argv
);
3251 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
3252 rpc_share_del_internals
,
3257 * Formatted print of share info
3259 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3262 static void display_share_info_1(struct net_context
*c
,
3263 struct srvsvc_NetShareInfo1
*r
)
3265 if (c
->opt_long_list_entries
) {
3266 d_printf("%-12s %-8.8s %-50s\n",
3268 c
->share_type
[r
->type
& ~(STYPE_TEMPORARY
|STYPE_HIDDEN
)],
3271 d_printf("%s\n", r
->name
);
3275 static WERROR
get_share_info(struct net_context
*c
,
3276 struct rpc_pipe_client
*pipe_hnd
,
3277 TALLOC_CTX
*mem_ctx
,
3281 struct srvsvc_NetShareInfoCtr
*info_ctr
)
3285 union srvsvc_NetShareInfo info
;
3287 /* no specific share requested, enumerate all */
3290 uint32_t preferred_len
= 0xffffffff;
3291 uint32_t total_entries
= 0;
3292 uint32_t resume_handle
= 0;
3294 info_ctr
->level
= level
;
3296 status
= rpccli_srvsvc_NetShareEnumAll(pipe_hnd
, mem_ctx
,
3306 /* request just one share */
3307 status
= rpccli_srvsvc_NetShareGetInfo(pipe_hnd
, mem_ctx
,
3314 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
3319 ZERO_STRUCTP(info_ctr
);
3321 info_ctr
->level
= level
;
3326 struct srvsvc_NetShareCtr1
*ctr1
;
3328 ctr1
= TALLOC_ZERO_P(mem_ctx
, struct srvsvc_NetShareCtr1
);
3329 W_ERROR_HAVE_NO_MEMORY(ctr1
);
3332 ctr1
->array
= info
.info1
;
3334 info_ctr
->ctr
.ctr1
= ctr1
;
3338 struct srvsvc_NetShareCtr2
*ctr2
;
3340 ctr2
= TALLOC_ZERO_P(mem_ctx
, struct srvsvc_NetShareCtr2
);
3341 W_ERROR_HAVE_NO_MEMORY(ctr2
);
3344 ctr2
->array
= info
.info2
;
3346 info_ctr
->ctr
.ctr2
= ctr2
;
3350 struct srvsvc_NetShareCtr502
*ctr502
;
3352 ctr502
= TALLOC_ZERO_P(mem_ctx
, struct srvsvc_NetShareCtr502
);
3353 W_ERROR_HAVE_NO_MEMORY(ctr502
);
3356 ctr502
->array
= info
.info502
;
3358 info_ctr
->ctr
.ctr502
= ctr502
;
3366 * List shares on a remote RPC server.
3368 * All parameters are provided by the run_rpc_command function, except for
3369 * argc, argv which are passed through.
3371 * @param domain_sid The domain sid acquired from the remote server.
3372 * @param cli A cli_state connected to the server.
3373 * @param mem_ctx Talloc context, destroyed on completion of the function.
3374 * @param argc Standard main() style argc.
3375 * @param argv Standard main() style argv. Initial components are already
3378 * @return Normal NTSTATUS return.
3381 static NTSTATUS
rpc_share_list_internals(struct net_context
*c
,
3382 const DOM_SID
*domain_sid
,
3383 const char *domain_name
,
3384 struct cli_state
*cli
,
3385 struct rpc_pipe_client
*pipe_hnd
,
3386 TALLOC_CTX
*mem_ctx
,
3390 struct srvsvc_NetShareInfoCtr info_ctr
;
3391 struct srvsvc_NetShareCtr1 ctr1
;
3393 uint32 i
, level
= 1;
3395 ZERO_STRUCT(info_ctr
);
3399 info_ctr
.ctr
.ctr1
= &ctr1
;
3401 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3403 if (!W_ERROR_IS_OK(result
))
3406 /* Display results */
3408 if (c
->opt_long_list_entries
) {
3410 "\nEnumerating shared resources (exports) on remote server:\n\n"
3411 "\nShare name Type Description\n"
3412 "---------- ---- -----------\n");
3414 for (i
= 0; i
< info_ctr
.ctr
.ctr1
->count
; i
++)
3415 display_share_info_1(c
, &info_ctr
.ctr
.ctr1
->array
[i
]);
3417 return W_ERROR_IS_OK(result
) ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
3421 * 'net rpc share list' entrypoint.
3422 * @param argc Standard main() style argc.
3423 * @param argv Standard main() style argv. Initial components are already
3426 static int rpc_share_list(struct net_context
*c
, int argc
, const char **argv
)
3428 if (c
->display_usage
) {
3430 "net rpc share list\n"
3431 " List shares on remote server\n");
3435 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0, rpc_share_list_internals
,
3439 static bool check_share_availability(struct cli_state
*cli
, const char *netname
)
3441 if (!cli_send_tconX(cli
, netname
, "A:", "", 0)) {
3442 d_printf("skipping [%s]: not a file share.\n", netname
);
3452 static bool check_share_sanity(struct net_context
*c
, struct cli_state
*cli
,
3453 const char *netname
, uint32 type
)
3455 /* only support disk shares */
3456 if (! ( type
== STYPE_DISKTREE
|| type
== (STYPE_DISKTREE
| STYPE_HIDDEN
)) ) {
3457 printf("share [%s] is not a diskshare (type: %x)\n", netname
, type
);
3461 /* skip builtin shares */
3462 /* FIXME: should print$ be added too ? */
3463 if (strequal(netname
,"IPC$") || strequal(netname
,"ADMIN$") ||
3464 strequal(netname
,"global"))
3467 if (c
->opt_exclude
&& in_list(netname
, c
->opt_exclude
, false)) {
3468 printf("excluding [%s]\n", netname
);
3472 return check_share_availability(cli
, netname
);
3476 * Migrate shares from a remote RPC server to the local RPC server.
3478 * All parameters are provided by the run_rpc_command function, except for
3479 * argc, argv which are passed through.
3481 * @param domain_sid The domain sid acquired from the remote server.
3482 * @param cli A cli_state connected to the server.
3483 * @param mem_ctx Talloc context, destroyed on completion of the function.
3484 * @param argc Standard main() style argc.
3485 * @param argv Standard main() style argv. Initial components are already
3488 * @return Normal NTSTATUS return.
3491 static NTSTATUS
rpc_share_migrate_shares_internals(struct net_context
*c
,
3492 const DOM_SID
*domain_sid
,
3493 const char *domain_name
,
3494 struct cli_state
*cli
,
3495 struct rpc_pipe_client
*pipe_hnd
,
3496 TALLOC_CTX
*mem_ctx
,
3501 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3502 struct srvsvc_NetShareInfoCtr ctr_src
;
3504 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
3505 struct cli_state
*cli_dst
= NULL
;
3506 uint32 level
= 502; /* includes secdesc */
3507 uint32_t parm_error
= 0;
3509 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3511 if (!W_ERROR_IS_OK(result
))
3514 /* connect destination PI_SRVSVC */
3515 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
, PI_SRVSVC
);
3516 if (!NT_STATUS_IS_OK(nt_status
))
3520 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
3522 union srvsvc_NetShareInfo info
;
3523 struct srvsvc_NetShareInfo502 info502
=
3524 ctr_src
.ctr
.ctr502
->array
[i
];
3526 /* reset error-code */
3527 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3529 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
3532 /* finally add the share on the dst server */
3534 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3535 info502
.name
, info502
.path
, info502
.comment
);
3537 info
.info502
= &info502
;
3539 nt_status
= rpccli_srvsvc_NetShareAdd(srvsvc_pipe
, mem_ctx
,
3540 srvsvc_pipe
->desthost
,
3546 if (W_ERROR_V(result
) == W_ERROR_V(WERR_ALREADY_EXISTS
)) {
3547 printf(" [%s] does already exist\n",
3552 if (!NT_STATUS_IS_OK(nt_status
) || !W_ERROR_IS_OK(result
)) {
3553 printf("cannot add share: %s\n", dos_errstr(result
));
3559 nt_status
= NT_STATUS_OK
;
3563 cli_shutdown(cli_dst
);
3571 * Migrate shares from a RPC server to another.
3573 * @param argc Standard main() style argc.
3574 * @param argv Standard main() style argv. Initial components are already
3577 * @return A shell status integer (0 for success).
3579 static int rpc_share_migrate_shares(struct net_context
*c
, int argc
,
3582 if (c
->display_usage
) {
3584 "net rpc share migrate shares\n"
3585 " Migrate shares to local server\n");
3590 printf("no server to migrate\n");
3594 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
3595 rpc_share_migrate_shares_internals
,
3602 * @param f file_info
3603 * @param mask current search mask
3604 * @param state arg-pointer
3607 static void copy_fn(const char *mnt
, file_info
*f
,
3608 const char *mask
, void *state
)
3610 static NTSTATUS nt_status
;
3611 static struct copy_clistate
*local_state
;
3612 static fstring filename
, new_mask
;
3615 struct net_context
*c
;
3617 local_state
= (struct copy_clistate
*)state
;
3618 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3622 if (strequal(f
->name
, ".") || strequal(f
->name
, ".."))
3625 DEBUG(3,("got mask: %s, name: %s\n", mask
, f
->name
));
3628 if (f
->mode
& aDIR
) {
3630 DEBUG(3,("got dir: %s\n", f
->name
));
3632 fstrcpy(dir
, local_state
->cwd
);
3634 fstrcat(dir
, f
->name
);
3636 switch (net_mode_share
)
3638 case NET_MODE_SHARE_MIGRATE
:
3639 /* create that directory */
3640 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
3641 local_state
->cli_share_src
,
3642 local_state
->cli_share_dst
,
3644 c
->opt_acls
? true : false,
3645 c
->opt_attrs
? true : false,
3646 c
->opt_timestamps
? true:false,
3650 d_fprintf(stderr
, "Unsupported mode %d\n", net_mode_share
);
3654 if (!NT_STATUS_IS_OK(nt_status
))
3655 printf("could not handle dir %s: %s\n",
3656 dir
, nt_errstr(nt_status
));
3658 /* search below that directory */
3659 fstrcpy(new_mask
, dir
);
3660 fstrcat(new_mask
, "\\*");
3662 old_dir
= local_state
->cwd
;
3663 local_state
->cwd
= dir
;
3664 if (!sync_files(local_state
, new_mask
))
3665 printf("could not handle files\n");
3666 local_state
->cwd
= old_dir
;
3673 fstrcpy(filename
, local_state
->cwd
);
3674 fstrcat(filename
, "\\");
3675 fstrcat(filename
, f
->name
);
3677 DEBUG(3,("got file: %s\n", filename
));
3679 switch (net_mode_share
)
3681 case NET_MODE_SHARE_MIGRATE
:
3682 nt_status
= net_copy_file(c
, local_state
->mem_ctx
,
3683 local_state
->cli_share_src
,
3684 local_state
->cli_share_dst
,
3686 c
->opt_acls
? true : false,
3687 c
->opt_attrs
? true : false,
3688 c
->opt_timestamps
? true: false,
3692 d_fprintf(stderr
, "Unsupported file mode %d\n", net_mode_share
);
3696 if (!NT_STATUS_IS_OK(nt_status
))
3697 printf("could not handle file %s: %s\n",
3698 filename
, nt_errstr(nt_status
));
3703 * sync files, can be called recursivly to list files
3704 * and then call copy_fn for each file
3706 * @param cp_clistate pointer to the copy_clistate we work with
3707 * @param mask the current search mask
3709 * @return Boolean result
3711 static bool sync_files(struct copy_clistate
*cp_clistate
, const char *mask
)
3713 struct cli_state
*targetcli
;
3714 char *targetpath
= NULL
;
3716 DEBUG(3,("calling cli_list with mask: %s\n", mask
));
3718 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate
->cli_share_src
,
3719 mask
, &targetcli
, &targetpath
) ) {
3720 d_fprintf(stderr
, "cli_resolve_path %s failed with error: %s\n",
3721 mask
, cli_errstr(cp_clistate
->cli_share_src
));
3725 if (cli_list(targetcli
, targetpath
, cp_clistate
->attribute
, copy_fn
, cp_clistate
) == -1) {
3726 d_fprintf(stderr
, "listing %s failed with error: %s\n",
3727 mask
, cli_errstr(targetcli
));
3736 * Set the top level directory permissions before we do any further copies.
3737 * Should set up ACL inheritance.
3740 bool copy_top_level_perms(struct net_context
*c
,
3741 struct copy_clistate
*cp_clistate
,
3742 const char *sharename
)
3744 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3746 switch (net_mode_share
) {
3747 case NET_MODE_SHARE_MIGRATE
:
3748 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename
));
3749 nt_status
= net_copy_fileattr(c
,
3750 cp_clistate
->mem_ctx
,
3751 cp_clistate
->cli_share_src
,
3752 cp_clistate
->cli_share_dst
,
3754 c
->opt_acls
? true : false,
3755 c
->opt_attrs
? true : false,
3756 c
->opt_timestamps
? true: false,
3760 d_fprintf(stderr
, "Unsupported mode %d\n", net_mode_share
);
3764 if (!NT_STATUS_IS_OK(nt_status
)) {
3765 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3766 sharename
, nt_errstr(nt_status
));
3774 * Sync all files inside a remote share to another share (over smb).
3776 * All parameters are provided by the run_rpc_command function, except for
3777 * argc, argv which are passed through.
3779 * @param domain_sid The domain sid acquired from the remote server.
3780 * @param cli A cli_state connected to the server.
3781 * @param mem_ctx Talloc context, destroyed on completion of the function.
3782 * @param argc Standard main() style argc.
3783 * @param argv Standard main() style argv. Initial components are already
3786 * @return Normal NTSTATUS return.
3789 static NTSTATUS
rpc_share_migrate_files_internals(struct net_context
*c
,
3790 const DOM_SID
*domain_sid
,
3791 const char *domain_name
,
3792 struct cli_state
*cli
,
3793 struct rpc_pipe_client
*pipe_hnd
,
3794 TALLOC_CTX
*mem_ctx
,
3799 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3800 struct srvsvc_NetShareInfoCtr ctr_src
;
3803 struct copy_clistate cp_clistate
;
3804 bool got_src_share
= false;
3805 bool got_dst_share
= false;
3806 const char *mask
= "\\*";
3809 dst
= SMB_STRDUP(c
->opt_destination
?c
->opt_destination
:"127.0.0.1");
3811 nt_status
= NT_STATUS_NO_MEMORY
;
3815 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3818 if (!W_ERROR_IS_OK(result
))
3821 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
3823 struct srvsvc_NetShareInfo502 info502
=
3824 ctr_src
.ctr
.ctr502
->array
[i
];
3826 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
3829 /* one might not want to mirror whole discs :) */
3830 if (strequal(info502
.name
, "print$") || info502
.name
[1] == '$') {
3831 d_printf("skipping [%s]: builtin/hidden share\n", info502
.name
);
3835 switch (net_mode_share
)
3837 case NET_MODE_SHARE_MIGRATE
:
3841 d_fprintf(stderr
, "Unsupported mode %d\n", net_mode_share
);
3844 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3846 c
->opt_acls
? "including" : "without",
3847 c
->opt_attrs
? "including" : "without",
3848 c
->opt_timestamps
? "(preserving timestamps)" : "");
3850 cp_clistate
.mem_ctx
= mem_ctx
;
3851 cp_clistate
.cli_share_src
= NULL
;
3852 cp_clistate
.cli_share_dst
= NULL
;
3853 cp_clistate
.cwd
= NULL
;
3854 cp_clistate
.attribute
= aSYSTEM
| aHIDDEN
| aDIR
;
3857 /* open share source */
3858 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_src
,
3859 &cli
->dest_ss
, cli
->desthost
,
3860 info502
.name
, "A:");
3861 if (!NT_STATUS_IS_OK(nt_status
))
3864 got_src_share
= true;
3866 if (net_mode_share
== NET_MODE_SHARE_MIGRATE
) {
3867 /* open share destination */
3868 nt_status
= connect_to_service(c
, &cp_clistate
.cli_share_dst
,
3869 NULL
, dst
, info502
.name
, "A:");
3870 if (!NT_STATUS_IS_OK(nt_status
))
3873 got_dst_share
= true;
3876 if (!copy_top_level_perms(c
, &cp_clistate
, info502
.name
)) {
3877 d_fprintf(stderr
, "Could not handle the top level directory permissions for the share: %s\n", info502
.name
);
3878 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3882 if (!sync_files(&cp_clistate
, mask
)) {
3883 d_fprintf(stderr
, "could not handle files for share: %s\n", info502
.name
);
3884 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3889 nt_status
= NT_STATUS_OK
;
3894 cli_shutdown(cp_clistate
.cli_share_src
);
3897 cli_shutdown(cp_clistate
.cli_share_dst
);
3904 static int rpc_share_migrate_files(struct net_context
*c
, int argc
, const char **argv
)
3906 if (c
->display_usage
) {
3908 "net share migrate files\n"
3909 " Migrate files to local server\n");
3914 d_printf("no server to migrate\n");
3918 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
3919 rpc_share_migrate_files_internals
,
3924 * Migrate share-ACLs from a remote RPC server to the local RPC server.
3926 * All parameters are provided by the run_rpc_command function, except for
3927 * argc, argv which are passed through.
3929 * @param domain_sid The domain sid acquired from the remote server.
3930 * @param cli A cli_state connected to the server.
3931 * @param mem_ctx Talloc context, destroyed on completion of the function.
3932 * @param argc Standard main() style argc.
3933 * @param argv Standard main() style argv. Initial components are already
3936 * @return Normal NTSTATUS return.
3939 static NTSTATUS
rpc_share_migrate_security_internals(struct net_context
*c
,
3940 const DOM_SID
*domain_sid
,
3941 const char *domain_name
,
3942 struct cli_state
*cli
,
3943 struct rpc_pipe_client
*pipe_hnd
,
3944 TALLOC_CTX
*mem_ctx
,
3949 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
3950 struct srvsvc_NetShareInfoCtr ctr_src
;
3951 union srvsvc_NetShareInfo info
;
3953 struct rpc_pipe_client
*srvsvc_pipe
= NULL
;
3954 struct cli_state
*cli_dst
= NULL
;
3955 uint32 level
= 502; /* includes secdesc */
3956 uint32_t parm_error
= 0;
3958 result
= get_share_info(c
, pipe_hnd
, mem_ctx
, level
, argc
, argv
,
3961 if (!W_ERROR_IS_OK(result
))
3964 /* connect destination PI_SRVSVC */
3965 nt_status
= connect_dst_pipe(c
, &cli_dst
, &srvsvc_pipe
, PI_SRVSVC
);
3966 if (!NT_STATUS_IS_OK(nt_status
))
3970 for (i
= 0; i
< ctr_src
.ctr
.ctr502
->count
; i
++) {
3972 struct srvsvc_NetShareInfo502 info502
=
3973 ctr_src
.ctr
.ctr502
->array
[i
];
3975 /* reset error-code */
3976 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3978 if (!check_share_sanity(c
, cli
, info502
.name
, info502
.type
))
3981 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3982 info502
.name
, info502
.path
, info502
.comment
);
3985 display_sec_desc(info502
.sd_buf
.sd
);
3987 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3988 info
.info502
= &info502
;
3990 /* finally modify the share on the dst server */
3991 nt_status
= rpccli_srvsvc_NetShareSetInfo(srvsvc_pipe
, mem_ctx
,
3992 srvsvc_pipe
->desthost
,
3998 if (!NT_STATUS_IS_OK(nt_status
) || !W_ERROR_IS_OK(result
)) {
3999 printf("cannot set share-acl: %s\n", dos_errstr(result
));
4005 nt_status
= NT_STATUS_OK
;
4009 cli_shutdown(cli_dst
);
4017 * Migrate share-acls from a RPC server to another.
4019 * @param argc Standard main() style argc.
4020 * @param argv Standard main() style argv. Initial components are already
4023 * @return A shell status integer (0 for success).
4025 static int rpc_share_migrate_security(struct net_context
*c
, int argc
,
4028 if (c
->display_usage
) {
4030 "net rpc share migrate security\n"
4031 " Migrate share-acls to local server\n");
4036 d_printf("no server to migrate\n");
4040 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4041 rpc_share_migrate_security_internals
,
4046 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4047 * from one server to another.
4049 * @param argc Standard main() style argc.
4050 * @param argv Standard main() style argv. Initial components are already
4053 * @return A shell status integer (0 for success).
4056 static int rpc_share_migrate_all(struct net_context
*c
, int argc
,
4061 if (c
->display_usage
) {
4063 "net rpc share migrate all\n"
4064 " Migrates shares including all share settings\n");
4069 d_printf("no server to migrate\n");
4073 /* order is important. we don't want to be locked out by the share-acl
4074 * before copying files - gd */
4076 ret
= run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4077 rpc_share_migrate_shares_internals
, argc
, argv
);
4081 ret
= run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4082 rpc_share_migrate_files_internals
, argc
, argv
);
4086 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4087 rpc_share_migrate_security_internals
, argc
,
4093 * 'net rpc share migrate' entrypoint.
4094 * @param argc Standard main() style argc.
4095 * @param argv Standard main() style argv. Initial components are already
4098 static int rpc_share_migrate(struct net_context
*c
, int argc
, const char **argv
)
4101 struct functable func
[] = {
4104 rpc_share_migrate_all
,
4106 "Migrate shares from remote to local server",
4107 "net rpc share migrate all\n"
4108 " Migrate shares from remote to local server"
4112 rpc_share_migrate_files
,
4114 "Migrate files from remote to local server",
4115 "net rpc share migrate files\n"
4116 " Migrate files from remote to local server"
4120 rpc_share_migrate_security
,
4122 "Migrate share-ACLs from remote to local server",
4123 "net rpc share migrate security\n"
4124 " Migrate share-ACLs from remote to local server"
4128 rpc_share_migrate_shares
,
4130 "Migrate shares from remote to local server",
4131 "net rpc share migrate shares\n"
4132 " Migrate shares from remote to local server"
4134 {NULL
, NULL
, 0, NULL
, NULL
}
4137 net_mode_share
= NET_MODE_SHARE_MIGRATE
;
4139 return net_run_function(c
, argc
, argv
, "net rpc share migrate", func
);
4148 static int num_server_aliases
;
4149 static struct full_alias
*server_aliases
;
4152 * Add an alias to the static list.
4154 static void push_alias(TALLOC_CTX
*mem_ctx
, struct full_alias
*alias
)
4156 if (server_aliases
== NULL
)
4157 server_aliases
= SMB_MALLOC_ARRAY(struct full_alias
, 100);
4159 server_aliases
[num_server_aliases
] = *alias
;
4160 num_server_aliases
+= 1;
4164 * For a specific domain on the server, fetch all the aliases
4165 * and their members. Add all of them to the server_aliases.
4168 static NTSTATUS
rpc_fetch_domain_aliases(struct rpc_pipe_client
*pipe_hnd
,
4169 TALLOC_CTX
*mem_ctx
,
4170 POLICY_HND
*connect_pol
,
4171 const DOM_SID
*domain_sid
)
4173 uint32 start_idx
, max_entries
, num_entries
, i
;
4174 struct samr_SamArray
*groups
= NULL
;
4176 POLICY_HND domain_pol
;
4178 /* Get domain policy handle */
4180 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
4182 MAXIMUM_ALLOWED_ACCESS
,
4183 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
4185 if (!NT_STATUS_IS_OK(result
))
4192 result
= rpccli_samr_EnumDomainAliases(pipe_hnd
, mem_ctx
,
4198 for (i
= 0; i
< num_entries
; i
++) {
4200 POLICY_HND alias_pol
;
4201 struct full_alias alias
;
4202 struct lsa_SidArray sid_array
;
4205 result
= rpccli_samr_OpenAlias(pipe_hnd
, mem_ctx
,
4207 MAXIMUM_ALLOWED_ACCESS
,
4208 groups
->entries
[i
].idx
,
4210 if (!NT_STATUS_IS_OK(result
))
4213 result
= rpccli_samr_GetMembersInAlias(pipe_hnd
, mem_ctx
,
4216 if (!NT_STATUS_IS_OK(result
))
4219 alias
.num_members
= sid_array
.num_sids
;
4221 result
= rpccli_samr_Close(pipe_hnd
, mem_ctx
, &alias_pol
);
4222 if (!NT_STATUS_IS_OK(result
))
4225 alias
.members
= NULL
;
4227 if (alias
.num_members
> 0) {
4228 alias
.members
= SMB_MALLOC_ARRAY(DOM_SID
, alias
.num_members
);
4230 for (j
= 0; j
< alias
.num_members
; j
++)
4231 sid_copy(&alias
.members
[j
],
4232 sid_array
.sids
[j
].sid
);
4235 sid_copy(&alias
.sid
, domain_sid
);
4236 sid_append_rid(&alias
.sid
, groups
->entries
[i
].idx
);
4238 push_alias(mem_ctx
, &alias
);
4240 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
4242 result
= NT_STATUS_OK
;
4245 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &domain_pol
);
4251 * Dump server_aliases as names for debugging purposes.
4254 static NTSTATUS
rpc_aliaslist_dump(struct net_context
*c
,
4255 const DOM_SID
*domain_sid
,
4256 const char *domain_name
,
4257 struct cli_state
*cli
,
4258 struct rpc_pipe_client
*pipe_hnd
,
4259 TALLOC_CTX
*mem_ctx
,
4267 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
4268 SEC_RIGHTS_MAXIMUM_ALLOWED
,
4270 if (!NT_STATUS_IS_OK(result
))
4273 for (i
=0; i
<num_server_aliases
; i
++) {
4276 enum lsa_SidType
*types
;
4279 struct full_alias
*alias
= &server_aliases
[i
];
4281 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
, 1,
4283 &domains
, &names
, &types
);
4284 if (!NT_STATUS_IS_OK(result
))
4287 DEBUG(1, ("%s\\%s %d: ", domains
[0], names
[0], types
[0]));
4289 if (alias
->num_members
== 0) {
4294 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &lsa_pol
,
4297 &domains
, &names
, &types
);
4299 if (!NT_STATUS_IS_OK(result
) &&
4300 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
4303 for (j
=0; j
<alias
->num_members
; j
++)
4304 DEBUG(1, ("%s\\%s (%d); ",
4305 domains
[j
] ? domains
[j
] : "*unknown*",
4306 names
[j
] ? names
[j
] : "*unknown*",types
[j
]));
4310 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &lsa_pol
);
4312 return NT_STATUS_OK
;
4316 * Fetch a list of all server aliases and their members into
4320 static NTSTATUS
rpc_aliaslist_internals(struct net_context
*c
,
4321 const DOM_SID
*domain_sid
,
4322 const char *domain_name
,
4323 struct cli_state
*cli
,
4324 struct rpc_pipe_client
*pipe_hnd
,
4325 TALLOC_CTX
*mem_ctx
,
4330 POLICY_HND connect_pol
;
4332 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
4334 MAXIMUM_ALLOWED_ACCESS
,
4337 if (!NT_STATUS_IS_OK(result
))
4340 result
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4341 &global_sid_Builtin
);
4343 if (!NT_STATUS_IS_OK(result
))
4346 result
= rpc_fetch_domain_aliases(pipe_hnd
, mem_ctx
, &connect_pol
,
4349 rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_pol
);
4354 static void init_user_token(NT_USER_TOKEN
*token
, DOM_SID
*user_sid
)
4356 token
->num_sids
= 4;
4358 if (!(token
->user_sids
= SMB_MALLOC_ARRAY(DOM_SID
, 4))) {
4359 d_fprintf(stderr
, "malloc failed\n");
4360 token
->num_sids
= 0;
4364 token
->user_sids
[0] = *user_sid
;
4365 sid_copy(&token
->user_sids
[1], &global_sid_World
);
4366 sid_copy(&token
->user_sids
[2], &global_sid_Network
);
4367 sid_copy(&token
->user_sids
[3], &global_sid_Authenticated_Users
);
4370 static void free_user_token(NT_USER_TOKEN
*token
)
4372 SAFE_FREE(token
->user_sids
);
4375 static bool is_sid_in_token(NT_USER_TOKEN
*token
, DOM_SID
*sid
)
4379 for (i
=0; i
<token
->num_sids
; i
++) {
4380 if (sid_compare(sid
, &token
->user_sids
[i
]) == 0)
4386 static void add_sid_to_token(NT_USER_TOKEN
*token
, DOM_SID
*sid
)
4388 if (is_sid_in_token(token
, sid
))
4391 token
->user_sids
= SMB_REALLOC_ARRAY(token
->user_sids
, DOM_SID
, token
->num_sids
+1);
4392 if (!token
->user_sids
) {
4396 sid_copy(&token
->user_sids
[token
->num_sids
], sid
);
4398 token
->num_sids
+= 1;
4403 NT_USER_TOKEN token
;
4406 static void dump_user_token(struct user_token
*token
)
4410 d_printf("%s\n", token
->name
);
4412 for (i
=0; i
<token
->token
.num_sids
; i
++) {
4413 d_printf(" %s\n", sid_string_tos(&token
->token
.user_sids
[i
]));
4417 static bool is_alias_member(DOM_SID
*sid
, struct full_alias
*alias
)
4421 for (i
=0; i
<alias
->num_members
; i
++) {
4422 if (sid_compare(sid
, &alias
->members
[i
]) == 0)
4429 static void collect_sid_memberships(NT_USER_TOKEN
*token
, DOM_SID sid
)
4433 for (i
=0; i
<num_server_aliases
; i
++) {
4434 if (is_alias_member(&sid
, &server_aliases
[i
]))
4435 add_sid_to_token(token
, &server_aliases
[i
].sid
);
4440 * We got a user token with all the SIDs we can know about without asking the
4441 * server directly. These are the user and domain group sids. All of these can
4442 * be members of aliases. So scan the list of aliases for each of the SIDs and
4443 * add them to the token.
4446 static void collect_alias_memberships(NT_USER_TOKEN
*token
)
4448 int num_global_sids
= token
->num_sids
;
4451 for (i
=0; i
<num_global_sids
; i
++) {
4452 collect_sid_memberships(token
, token
->user_sids
[i
]);
4456 static bool get_user_sids(const char *domain
, const char *user
, NT_USER_TOKEN
*token
)
4458 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4459 enum wbcSidType type
;
4461 struct wbcDomainSid wsid
;
4462 char *sid_str
= NULL
;
4464 uint32_t num_groups
;
4465 gid_t
*groups
= NULL
;
4468 fstr_sprintf(full_name
, "%s%c%s",
4469 domain
, *lp_winbind_separator(), user
);
4471 /* First let's find out the user sid */
4473 wbc_status
= wbcLookupName(domain
, user
, &wsid
, &type
);
4475 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4476 DEBUG(1, ("winbind could not find %s: %s\n",
4477 full_name
, wbcErrorString(wbc_status
)));
4481 wbc_status
= wbcSidToString(&wsid
, &sid_str
);
4482 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4486 if (type
!= SID_NAME_USER
) {
4487 wbcFreeMemory(sid_str
);
4488 DEBUG(1, ("%s is not a user\n", full_name
));
4492 string_to_sid(&user_sid
, sid_str
);
4493 wbcFreeMemory(sid_str
);
4496 init_user_token(token
, &user_sid
);
4498 /* And now the groups winbind knows about */
4500 wbc_status
= wbcGetGroups(full_name
, &num_groups
, &groups
);
4501 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4502 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4503 full_name
, wbcErrorString(wbc_status
)));
4507 for (i
= 0; i
< num_groups
; i
++) {
4508 gid_t gid
= groups
[i
];
4511 wbc_status
= wbcGidToSid(gid
, &wsid
);
4512 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4513 DEBUG(1, ("winbind could not find SID of gid %d: %s\n",
4514 gid
, wbcErrorString(wbc_status
)));
4515 wbcFreeMemory(groups
);
4519 wbc_status
= wbcSidToString(&wsid
, &sid_str
);
4520 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4521 wbcFreeMemory(groups
);
4525 DEBUG(3, (" %s\n", sid_str
));
4527 string_to_sid(&sid
, sid_str
);
4528 wbcFreeMemory(sid_str
);
4531 add_sid_to_token(token
, &sid
);
4533 wbcFreeMemory(groups
);
4539 * Get a list of all user tokens we want to look at
4542 static bool get_user_tokens(struct net_context
*c
, int *num_tokens
,
4543 struct user_token
**user_tokens
)
4545 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
4546 uint32_t i
, num_users
;
4548 struct user_token
*result
;
4549 TALLOC_CTX
*frame
= NULL
;
4551 if (lp_winbind_use_default_domain() &&
4552 (c
->opt_target_workgroup
== NULL
)) {
4553 d_fprintf(stderr
, "winbind use default domain = yes set, "
4554 "please specify a workgroup\n");
4558 /* Send request to winbind daemon */
4560 wbc_status
= wbcListUsers(NULL
, &num_users
, &users
);
4561 if (!WBC_ERROR_IS_OK(wbc_status
)) {
4562 DEBUG(1, ("winbind could not list users: %s\n",
4563 wbcErrorString(wbc_status
)));
4567 result
= SMB_MALLOC_ARRAY(struct user_token
, num_users
);
4569 if (result
== NULL
) {
4570 DEBUG(1, ("Could not malloc sid array\n"));
4571 wbcFreeMemory(users
);
4575 frame
= talloc_stackframe();
4576 for (i
=0; i
< num_users
; i
++) {
4577 fstring domain
, user
;
4580 fstrcpy(result
[i
].name
, users
[i
]);
4582 p
= strchr(users
[i
], *lp_winbind_separator());
4584 DEBUG(3, ("%s\n", users
[i
]));
4587 fstrcpy(domain
, c
->opt_target_workgroup
);
4588 fstrcpy(user
, users
[i
]);
4591 fstrcpy(domain
, users
[i
]);
4596 get_user_sids(domain
, user
, &(result
[i
].token
));
4600 wbcFreeMemory(users
);
4602 *num_tokens
= num_users
;
4603 *user_tokens
= result
;
4608 static bool get_user_tokens_from_file(FILE *f
,
4610 struct user_token
**tokens
)
4612 struct user_token
*token
= NULL
;
4617 if (fgets(line
, sizeof(line
)-1, f
) == NULL
) {
4621 if (line
[strlen(line
)-1] == '\n')
4622 line
[strlen(line
)-1] = '\0';
4624 if (line
[0] == ' ') {
4628 string_to_sid(&sid
, &line
[1]);
4630 if (token
== NULL
) {
4631 DEBUG(0, ("File does not begin with username"));
4635 add_sid_to_token(&token
->token
, &sid
);
4639 /* And a new user... */
4642 *tokens
= SMB_REALLOC_ARRAY(*tokens
, struct user_token
, *num_tokens
);
4643 if (*tokens
== NULL
) {
4644 DEBUG(0, ("Could not realloc tokens\n"));
4648 token
= &((*tokens
)[*num_tokens
-1]);
4650 fstrcpy(token
->name
, line
);
4651 token
->token
.num_sids
= 0;
4652 token
->token
.user_sids
= NULL
;
4661 * Show the list of all users that have access to a share
4664 static void show_userlist(struct rpc_pipe_client
*pipe_hnd
,
4665 TALLOC_CTX
*mem_ctx
,
4666 const char *netname
,
4668 struct user_token
*tokens
)
4671 SEC_DESC
*share_sd
= NULL
;
4672 SEC_DESC
*root_sd
= NULL
;
4673 struct cli_state
*cli
= rpc_pipe_np_smb_conn(pipe_hnd
);
4675 union srvsvc_NetShareInfo info
;
4680 status
= rpccli_srvsvc_NetShareGetInfo(pipe_hnd
, mem_ctx
,
4687 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
4688 DEBUG(1, ("Coult not query secdesc for share %s\n",
4693 share_sd
= info
.info502
->sd_buf
.sd
;
4694 if (share_sd
== NULL
) {
4695 DEBUG(1, ("Got no secdesc for share %s\n",
4701 if (!cli_send_tconX(cli
, netname
, "A:", "", 0)) {
4705 fnum
= cli_nt_create(cli
, "\\", READ_CONTROL_ACCESS
);
4708 root_sd
= cli_query_secdesc(cli
, fnum
, mem_ctx
);
4711 for (i
=0; i
<num_tokens
; i
++) {
4714 if (share_sd
!= NULL
) {
4715 if (!se_access_check(share_sd
, &tokens
[i
].token
,
4716 1, &acc_granted
, &status
)) {
4717 DEBUG(1, ("Could not check share_sd for "
4723 if (!NT_STATUS_IS_OK(status
))
4727 if (root_sd
== NULL
) {
4728 d_printf(" %s\n", tokens
[i
].name
);
4732 if (!se_access_check(root_sd
, &tokens
[i
].token
,
4733 1, &acc_granted
, &status
)) {
4734 DEBUG(1, ("Could not check root_sd for user %s\n",
4739 if (!NT_STATUS_IS_OK(status
))
4742 d_printf(" %s\n", tokens
[i
].name
);
4746 cli_close(cli
, fnum
);
4758 static void collect_share(const char *name
, uint32 m
,
4759 const char *comment
, void *state
)
4761 struct share_list
*share_list
= (struct share_list
*)state
;
4763 if (m
!= STYPE_DISKTREE
)
4766 share_list
->num_shares
+= 1;
4767 share_list
->shares
= SMB_REALLOC_ARRAY(share_list
->shares
, char *, share_list
->num_shares
);
4768 if (!share_list
->shares
) {
4769 share_list
->num_shares
= 0;
4772 share_list
->shares
[share_list
->num_shares
-1] = SMB_STRDUP(name
);
4776 * List shares on a remote RPC server, including the security descriptors.
4778 * All parameters are provided by the run_rpc_command function, except for
4779 * argc, argv which are passed through.
4781 * @param domain_sid The domain sid acquired from the remote server.
4782 * @param cli A cli_state connected to the server.
4783 * @param mem_ctx Talloc context, destroyed on completion of the function.
4784 * @param argc Standard main() style argc.
4785 * @param argv Standard main() style argv. Initial components are already
4788 * @return Normal NTSTATUS return.
4791 static NTSTATUS
rpc_share_allowedusers_internals(struct net_context
*c
,
4792 const DOM_SID
*domain_sid
,
4793 const char *domain_name
,
4794 struct cli_state
*cli
,
4795 struct rpc_pipe_client
*pipe_hnd
,
4796 TALLOC_CTX
*mem_ctx
,
4806 struct user_token
*tokens
= NULL
;
4809 struct share_list share_list
;
4814 f
= fopen(argv
[0], "r");
4818 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno
)));
4819 return NT_STATUS_UNSUCCESSFUL
;
4822 r
= get_user_tokens_from_file(f
, &num_tokens
, &tokens
);
4828 DEBUG(0, ("Could not read users from file\n"));
4829 return NT_STATUS_UNSUCCESSFUL
;
4832 for (i
=0; i
<num_tokens
; i
++)
4833 collect_alias_memberships(&tokens
[i
].token
);
4835 init_enum_hnd(&hnd
, 0);
4837 share_list
.num_shares
= 0;
4838 share_list
.shares
= NULL
;
4840 ret
= cli_RNetShareEnum(cli
, collect_share
, &share_list
);
4843 DEBUG(0, ("Error returning browse list: %s\n",
4848 for (i
= 0; i
< share_list
.num_shares
; i
++) {
4849 char *netname
= share_list
.shares
[i
];
4851 if (netname
[strlen(netname
)-1] == '$')
4854 d_printf("%s\n", netname
);
4856 show_userlist(pipe_hnd
, mem_ctx
, netname
,
4857 num_tokens
, tokens
);
4860 for (i
=0; i
<num_tokens
; i
++) {
4861 free_user_token(&tokens
[i
].token
);
4864 SAFE_FREE(share_list
.shares
);
4866 return NT_STATUS_OK
;
4869 static int rpc_share_allowedusers(struct net_context
*c
, int argc
,
4874 if (c
->display_usage
) {
4876 "net rpc share allowedusers\n"
4877 " List allowed users\n");
4881 result
= run_rpc_command(c
, NULL
, PI_SAMR
, 0,
4882 rpc_aliaslist_internals
,
4887 result
= run_rpc_command(c
, NULL
, PI_LSARPC
, 0,
4893 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4894 rpc_share_allowedusers_internals
,
4898 int net_usersidlist(struct net_context
*c
, int argc
, const char **argv
)
4901 struct user_token
*tokens
= NULL
;
4905 net_usersidlist_usage(c
, argc
, argv
);
4909 if (!get_user_tokens(c
, &num_tokens
, &tokens
)) {
4910 DEBUG(0, ("Could not get the user/sid list\n"));
4914 for (i
=0; i
<num_tokens
; i
++) {
4915 dump_user_token(&tokens
[i
]);
4916 free_user_token(&tokens
[i
].token
);
4923 int net_usersidlist_usage(struct net_context
*c
, int argc
, const char **argv
)
4925 d_printf("net usersidlist\n"
4926 "\tprints out a list of all users the running winbind knows\n"
4927 "\tabout, together with all their SIDs. This is used as\n"
4928 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4930 net_common_flags_usage(c
, argc
, argv
);
4935 * 'net rpc share' entrypoint.
4936 * @param argc Standard main() style argc.
4937 * @param argv Standard main() style argv. Initial components are already
4941 int net_rpc_share(struct net_context
*c
, int argc
, const char **argv
)
4943 struct functable func
[] = {
4949 "net rpc share add\n"
4957 "net rpc share delete\n"
4962 rpc_share_allowedusers
,
4964 "Modify allowed users",
4965 "net rpc share allowedusers\n"
4966 " Modify allowed users"
4972 "Migrate share to local server",
4973 "net rpc share migrate\n"
4974 " Migrate share to local server"
4981 "net rpc share list\n"
4984 {NULL
, NULL
, 0, NULL
, NULL
}
4989 if (c
->display_usage
) {
4993 " Alias for net rpc share list\n");
4994 net_display_usage_from_functable(func
);
4998 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
4999 rpc_share_list_internals
,
5003 return net_run_function(c
, argc
, argv
, "net rpc share", func
);
5006 static NTSTATUS
rpc_sh_share_list(struct net_context
*c
,
5007 TALLOC_CTX
*mem_ctx
,
5008 struct rpc_sh_ctx
*ctx
,
5009 struct rpc_pipe_client
*pipe_hnd
,
5010 int argc
, const char **argv
)
5012 return rpc_share_list_internals(c
, ctx
->domain_sid
, ctx
->domain_name
,
5013 ctx
->cli
, pipe_hnd
, mem_ctx
,
5017 static NTSTATUS
rpc_sh_share_add(struct net_context
*c
,
5018 TALLOC_CTX
*mem_ctx
,
5019 struct rpc_sh_ctx
*ctx
,
5020 struct rpc_pipe_client
*pipe_hnd
,
5021 int argc
, const char **argv
)
5025 uint32_t parm_err
= 0;
5026 union srvsvc_NetShareInfo info
;
5027 struct srvsvc_NetShareInfo2 info2
;
5029 if ((argc
< 2) || (argc
> 3)) {
5030 d_fprintf(stderr
, "usage: %s <share> <path> [comment]\n",
5032 return NT_STATUS_INVALID_PARAMETER
;
5035 info2
.name
= argv
[0];
5036 info2
.type
= STYPE_DISKTREE
;
5037 info2
.comment
= (argc
== 3) ? argv
[2] : "";
5038 info2
.permissions
= 0;
5039 info2
.max_users
= 0;
5040 info2
.current_users
= 0;
5041 info2
.path
= argv
[1];
5042 info2
.password
= NULL
;
5044 info
.info2
= &info2
;
5046 status
= rpccli_srvsvc_NetShareAdd(pipe_hnd
, mem_ctx
,
5056 static NTSTATUS
rpc_sh_share_delete(struct net_context
*c
,
5057 TALLOC_CTX
*mem_ctx
,
5058 struct rpc_sh_ctx
*ctx
,
5059 struct rpc_pipe_client
*pipe_hnd
,
5060 int argc
, const char **argv
)
5066 d_fprintf(stderr
, "usage: %s <share>\n", ctx
->whoami
);
5067 return NT_STATUS_INVALID_PARAMETER
;
5070 status
= rpccli_srvsvc_NetShareDel(pipe_hnd
, mem_ctx
,
5079 static NTSTATUS
rpc_sh_share_info(struct net_context
*c
,
5080 TALLOC_CTX
*mem_ctx
,
5081 struct rpc_sh_ctx
*ctx
,
5082 struct rpc_pipe_client
*pipe_hnd
,
5083 int argc
, const char **argv
)
5085 union srvsvc_NetShareInfo info
;
5090 d_fprintf(stderr
, "usage: %s <share>\n", ctx
->whoami
);
5091 return NT_STATUS_INVALID_PARAMETER
;
5094 status
= rpccli_srvsvc_NetShareGetInfo(pipe_hnd
, mem_ctx
,
5100 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
)) {
5104 d_printf("Name: %s\n", info
.info2
->name
);
5105 d_printf("Comment: %s\n", info
.info2
->comment
);
5106 d_printf("Path: %s\n", info
.info2
->path
);
5107 d_printf("Password: %s\n", info
.info2
->password
);
5110 return werror_to_ntstatus(result
);
5113 struct rpc_sh_cmd
*net_rpc_share_cmds(struct net_context
*c
, TALLOC_CTX
*mem_ctx
,
5114 struct rpc_sh_ctx
*ctx
)
5116 static struct rpc_sh_cmd cmds
[] = {
5118 { "list", NULL
, PI_SRVSVC
, rpc_sh_share_list
,
5119 "List available shares" },
5121 { "add", NULL
, PI_SRVSVC
, rpc_sh_share_add
,
5124 { "delete", NULL
, PI_SRVSVC
, rpc_sh_share_delete
,
5127 { "info", NULL
, PI_SRVSVC
, rpc_sh_share_info
,
5128 "Get information about a share" },
5130 { NULL
, NULL
, 0, NULL
, NULL
}
5136 /****************************************************************************/
5138 static int rpc_file_usage(struct net_context
*c
, int argc
, const char **argv
)
5140 return net_file_usage(c
, argc
, argv
);
5144 * Close a file on a remote RPC server.
5146 * All parameters are provided by the run_rpc_command function, except for
5147 * argc, argv which are passed through.
5149 * @param c A net_context structure.
5150 * @param domain_sid The domain sid acquired from the remote server.
5151 * @param cli A cli_state connected to the server.
5152 * @param mem_ctx Talloc context, destroyed on completion of the function.
5153 * @param argc Standard main() style argc.
5154 * @param argv Standard main() style argv. Initial components are already
5157 * @return Normal NTSTATUS return.
5159 static NTSTATUS
rpc_file_close_internals(struct net_context
*c
,
5160 const DOM_SID
*domain_sid
,
5161 const char *domain_name
,
5162 struct cli_state
*cli
,
5163 struct rpc_pipe_client
*pipe_hnd
,
5164 TALLOC_CTX
*mem_ctx
,
5168 return rpccli_srvsvc_NetFileClose(pipe_hnd
, mem_ctx
,
5170 atoi(argv
[0]), NULL
);
5174 * Close a file on a remote RPC server.
5176 * @param argc Standard main() style argc.
5177 * @param argv Standard main() style argv. Initial components are already
5180 * @return A shell status integer (0 for success).
5182 static int rpc_file_close(struct net_context
*c
, int argc
, const char **argv
)
5184 if (argc
< 1 || c
->display_usage
) {
5185 return rpc_file_usage(c
, argc
, argv
);
5188 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
5189 rpc_file_close_internals
,
5194 * Formatted print of open file info
5196 * @param r struct srvsvc_NetFileInfo3 contents
5199 static void display_file_info_3(struct srvsvc_NetFileInfo3
*r
)
5201 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5202 r
->fid
, r
->user
, r
->permissions
, r
->num_locks
, r
->path
);
5206 * List open files on a remote RPC server.
5208 * All parameters are provided by the run_rpc_command function, except for
5209 * argc, argv which are passed through.
5211 * @param c A net_context structure.
5212 * @param domain_sid The domain sid acquired from the remote server.
5213 * @param cli A cli_state connected to the server.
5214 * @param mem_ctx Talloc context, destroyed on completion of the function.
5215 * @param argc Standard main() style argc.
5216 * @param argv Standard main() style argv. Initial components are already
5219 * @return Normal NTSTATUS return.
5222 static NTSTATUS
rpc_file_list_internals(struct net_context
*c
,
5223 const DOM_SID
*domain_sid
,
5224 const char *domain_name
,
5225 struct cli_state
*cli
,
5226 struct rpc_pipe_client
*pipe_hnd
,
5227 TALLOC_CTX
*mem_ctx
,
5231 struct srvsvc_NetFileInfoCtr info_ctr
;
5232 struct srvsvc_NetFileCtr3 ctr3
;
5235 uint32 preferred_len
= 0xffffffff, i
;
5236 const char *username
=NULL
;
5237 uint32_t total_entries
= 0;
5238 uint32_t resume_handle
= 0;
5240 /* if argc > 0, must be user command */
5242 username
= smb_xstrdup(argv
[0]);
5244 ZERO_STRUCT(info_ctr
);
5248 info_ctr
.ctr
.ctr3
= &ctr3
;
5250 status
= rpccli_srvsvc_NetFileEnum(pipe_hnd
, mem_ctx
,
5260 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(result
))
5263 /* Display results */
5266 "\nEnumerating open files on remote server:\n\n"
5267 "\nFileId Opened by Perms Locks Path"
5268 "\n------ --------- ----- ----- ---- \n");
5269 for (i
= 0; i
< total_entries
; i
++)
5270 display_file_info_3(&info_ctr
.ctr
.ctr3
->array
[i
]);
5272 return W_ERROR_IS_OK(result
) ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
5276 * List files for a user on a remote RPC server.
5278 * @param argc Standard main() style argc.
5279 * @param argv Standard main() style argv. Initial components are already
5282 * @return A shell status integer (0 for success)..
5285 static int rpc_file_user(struct net_context
*c
, int argc
, const char **argv
)
5287 if (argc
< 1 || c
->display_usage
) {
5288 return rpc_file_usage(c
, argc
, argv
);
5291 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
5292 rpc_file_list_internals
,
5297 * 'net rpc file' entrypoint.
5298 * @param argc Standard main() style argc.
5299 * @param argv Standard main() style argv. Initial components are already
5303 int net_rpc_file(struct net_context
*c
, int argc
, const char **argv
)
5305 struct functable func
[] = {
5310 "Close opened file",
5311 "net rpc file close\n"
5312 " Close opened file"
5318 "List files opened by user",
5319 "net rpc file user\n"
5320 " List files opened by user"
5327 "Display information about opened file",
5328 "net rpc file info\n"
5329 " Display information about opened file"
5332 {NULL
, NULL
, 0, NULL
, NULL
}
5336 if (c
->display_usage
) {
5337 d_printf("Usage:\n");
5338 d_printf("net rpc file\n"
5339 " List opened files\n");
5340 net_display_usage_from_functable(func
);
5344 return run_rpc_command(c
, NULL
, PI_SRVSVC
, 0,
5345 rpc_file_list_internals
,
5349 return net_run_function(c
, argc
, argv
, "net rpc file", func
);
5353 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5355 * All parameters are provided by the run_rpc_command function, except for
5356 * argc, argv which are passed through.
5358 * @param c A net_context structure.
5359 * @param domain_sid The domain sid acquired from the remote server.
5360 * @param cli A cli_state connected to the server.
5361 * @param mem_ctx Talloc context, destroyed on completion of the function.
5362 * @param argc Standard main() style argc.
5363 * @param argv Standard main() style argv. Initial components are already
5366 * @return Normal NTSTATUS return.
5369 static NTSTATUS
rpc_shutdown_abort_internals(struct net_context
*c
,
5370 const DOM_SID
*domain_sid
,
5371 const char *domain_name
,
5372 struct cli_state
*cli
,
5373 struct rpc_pipe_client
*pipe_hnd
,
5374 TALLOC_CTX
*mem_ctx
,
5378 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5380 result
= rpccli_initshutdown_Abort(pipe_hnd
, mem_ctx
, NULL
, NULL
);
5382 if (NT_STATUS_IS_OK(result
)) {
5383 d_printf("\nShutdown successfully aborted\n");
5384 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5386 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5392 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5394 * All parameters are provided by the run_rpc_command function, except for
5395 * argc, argv which are passed through.
5397 * @param c A net_context structure.
5398 * @param domain_sid The domain sid acquired from the remote server.
5399 * @param cli A cli_state connected to the server.
5400 * @param mem_ctx Talloc context, destroyed on completion of the function.
5401 * @param argc Standard main() style argc.
5402 * @param argv Standard main() style argv. Initial components are already
5405 * @return Normal NTSTATUS return.
5408 static NTSTATUS
rpc_reg_shutdown_abort_internals(struct net_context
*c
,
5409 const DOM_SID
*domain_sid
,
5410 const char *domain_name
,
5411 struct cli_state
*cli
,
5412 struct rpc_pipe_client
*pipe_hnd
,
5413 TALLOC_CTX
*mem_ctx
,
5417 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5419 result
= rpccli_winreg_AbortSystemShutdown(pipe_hnd
, mem_ctx
, NULL
, NULL
);
5421 if (NT_STATUS_IS_OK(result
)) {
5422 d_printf("\nShutdown successfully aborted\n");
5423 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5425 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5431 * ABORT the shutdown of a remote RPC server.
5433 * @param argc Standard main() style argc.
5434 * @param argv Standard main() style argv. Initial components are already
5437 * @return A shell status integer (0 for success).
5440 static int rpc_shutdown_abort(struct net_context
*c
, int argc
,
5445 if (c
->display_usage
) {
5447 "net rpc abortshutdown\n"
5448 " Abort a scheduled shutdown\n");
5452 rc
= run_rpc_command(c
, NULL
, PI_INITSHUTDOWN
, 0,
5453 rpc_shutdown_abort_internals
, argc
, argv
);
5458 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5460 return run_rpc_command(c
, NULL
, PI_WINREG
, 0,
5461 rpc_reg_shutdown_abort_internals
,
5466 * Shut down a remote RPC Server via initshutdown pipe.
5468 * All parameters are provided by the run_rpc_command function, except for
5469 * argc, argv which are passed through.
5471 * @param c A net_context structure.
5472 * @param domain_sid The domain sid acquired from the remote server.
5473 * @param cli A cli_state connected to the server.
5474 * @param mem_ctx Talloc context, destroyed on completion of the function.
5475 * @param argc Standard main() style argc.
5476 * @param argv Standard main() style argv. Initial components are already
5479 * @return Normal NTSTATUS return.
5482 NTSTATUS
rpc_init_shutdown_internals(struct net_context
*c
,
5483 const DOM_SID
*domain_sid
,
5484 const char *domain_name
,
5485 struct cli_state
*cli
,
5486 struct rpc_pipe_client
*pipe_hnd
,
5487 TALLOC_CTX
*mem_ctx
,
5491 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5492 const char *msg
= "This machine will be shutdown shortly";
5493 uint32 timeout
= 20;
5494 struct initshutdown_String msg_string
;
5495 struct initshutdown_String_sub s
;
5497 if (c
->opt_comment
) {
5498 msg
= c
->opt_comment
;
5500 if (c
->opt_timeout
) {
5501 timeout
= c
->opt_timeout
;
5505 msg_string
.name
= &s
;
5507 /* create an entry */
5508 result
= rpccli_initshutdown_Init(pipe_hnd
, mem_ctx
, NULL
,
5509 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5512 if (NT_STATUS_IS_OK(result
)) {
5513 d_printf("\nShutdown of remote machine succeeded\n");
5514 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5516 DEBUG(1,("Shutdown of remote machine failed!\n"));
5522 * Shut down a remote RPC Server via winreg pipe.
5524 * All parameters are provided by the run_rpc_command function, except for
5525 * argc, argv which are passed through.
5527 * @param c A net_context structure.
5528 * @param domain_sid The domain sid acquired from the remote server.
5529 * @param cli A cli_state connected to the server.
5530 * @param mem_ctx Talloc context, destroyed on completion of the function.
5531 * @param argc Standard main() style argc.
5532 * @param argv Standard main() style argv. Initial components are already
5535 * @return Normal NTSTATUS return.
5538 NTSTATUS
rpc_reg_shutdown_internals(struct net_context
*c
,
5539 const DOM_SID
*domain_sid
,
5540 const char *domain_name
,
5541 struct cli_state
*cli
,
5542 struct rpc_pipe_client
*pipe_hnd
,
5543 TALLOC_CTX
*mem_ctx
,
5547 const char *msg
= "This machine will be shutdown shortly";
5548 uint32 timeout
= 20;
5549 struct initshutdown_String msg_string
;
5550 struct initshutdown_String_sub s
;
5554 if (c
->opt_comment
) {
5555 msg
= c
->opt_comment
;
5558 msg_string
.name
= &s
;
5560 if (c
->opt_timeout
) {
5561 timeout
= c
->opt_timeout
;
5564 /* create an entry */
5565 result
= rpccli_winreg_InitiateSystemShutdown(pipe_hnd
, mem_ctx
, NULL
,
5566 &msg_string
, timeout
, c
->opt_force
, c
->opt_reboot
,
5569 if (NT_STATUS_IS_OK(result
)) {
5570 d_printf("\nShutdown of remote machine succeeded\n");
5572 d_fprintf(stderr
, "\nShutdown of remote machine failed\n");
5573 if ( W_ERROR_EQUAL(werr
, WERR_MACHINE_LOCKED
) )
5574 d_fprintf(stderr
, "\nMachine locked, use -f switch to force\n");
5576 d_fprintf(stderr
, "\nresult was: %s\n", dos_errstr(werr
));
5583 * Shut down a remote RPC server.
5585 * @param argc Standard main() style argc.
5586 * @param argv Standard main() style argv. Initial components are already
5589 * @return A shell status integer (0 for success).
5592 static int rpc_shutdown(struct net_context
*c
, int argc
, const char **argv
)
5596 if (c
->display_usage
) {
5598 "net rpc shutdown\n"
5599 " Shut down a remote RPC server\n");
5603 rc
= run_rpc_command(c
, NULL
, PI_INITSHUTDOWN
, 0,
5604 rpc_init_shutdown_internals
, argc
, argv
);
5607 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5608 rc
= run_rpc_command(c
, NULL
, PI_WINREG
, 0,
5609 rpc_reg_shutdown_internals
, argc
, argv
);
5615 /***************************************************************************
5616 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5617 ***************************************************************************/
5620 * Add interdomain trust account to the RPC server.
5621 * All parameters (except for argc and argv) are passed by run_rpc_command
5624 * @param c A net_context structure.
5625 * @param domain_sid The domain sid acquired from the server.
5626 * @param cli A cli_state connected to the server.
5627 * @param mem_ctx Talloc context, destroyed on completion of the function.
5628 * @param argc Standard main() style argc.
5629 * @param argv Standard main() style argv. Initial components are already
5632 * @return normal NTSTATUS return code.
5635 static NTSTATUS
rpc_trustdom_add_internals(struct net_context
*c
,
5636 const DOM_SID
*domain_sid
,
5637 const char *domain_name
,
5638 struct cli_state
*cli
,
5639 struct rpc_pipe_client
*pipe_hnd
,
5640 TALLOC_CTX
*mem_ctx
,
5644 POLICY_HND connect_pol
, domain_pol
, user_pol
;
5645 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5647 struct lsa_String lsa_acct_name
;
5649 uint32 acct_flags
=0;
5651 uint32_t access_granted
= 0;
5652 union samr_UserInfo info
;
5653 unsigned int orig_timeout
;
5656 d_printf("Usage: net rpc trustdom add <domain_name> "
5657 "<trust password>\n");
5658 return NT_STATUS_INVALID_PARAMETER
;
5662 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5665 if (asprintf(&acct_name
, "%s$", argv
[0]) < 0) {
5666 return NT_STATUS_NO_MEMORY
;
5669 strupper_m(acct_name
);
5671 init_lsa_String(&lsa_acct_name
, acct_name
);
5673 /* Get samr policy handle */
5674 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
5676 MAXIMUM_ALLOWED_ACCESS
,
5678 if (!NT_STATUS_IS_OK(result
)) {
5682 /* Get domain policy handle */
5683 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
5685 MAXIMUM_ALLOWED_ACCESS
,
5686 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
5688 if (!NT_STATUS_IS_OK(result
)) {
5692 /* This call can take a long time - allow the server to time out.
5693 * 35 seconds should do it. */
5695 orig_timeout
= rpccli_set_timeout(pipe_hnd
, 35000);
5697 /* Create trusting domain's account */
5698 acb_info
= ACB_NORMAL
;
5699 acct_flags
= SEC_GENERIC_READ
| SEC_GENERIC_WRITE
| SEC_GENERIC_EXECUTE
|
5700 SEC_STD_WRITE_DAC
| SEC_STD_DELETE
|
5701 SAMR_USER_ACCESS_SET_PASSWORD
|
5702 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
5703 SAMR_USER_ACCESS_SET_ATTRIBUTES
;
5705 result
= rpccli_samr_CreateUser2(pipe_hnd
, mem_ctx
,
5714 /* And restore our original timeout. */
5715 rpccli_set_timeout(pipe_hnd
, orig_timeout
);
5717 if (!NT_STATUS_IS_OK(result
)) {
5718 d_printf("net rpc trustdom add: create user %s failed %s\n",
5719 acct_name
, nt_errstr(result
));
5725 struct samr_LogonHours hours
;
5726 struct lsa_BinaryString parameters
;
5727 const int units_per_week
= 168;
5730 encode_pw_buffer(pwbuf
, argv
[1], STR_UNICODE
);
5732 ZERO_STRUCT(notime
);
5734 ZERO_STRUCT(parameters
);
5736 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
5738 result
= NT_STATUS_NO_MEMORY
;
5741 hours
.units_per_week
= units_per_week
;
5742 memset(hours
.bits
, 0xFF, units_per_week
);
5744 init_samr_user_info23(&info
.info23
,
5745 notime
, notime
, notime
,
5746 notime
, notime
, notime
,
5747 NULL
, NULL
, NULL
, NULL
, NULL
,
5748 NULL
, NULL
, NULL
, NULL
, ¶meters
,
5749 0, 0, ACB_DOMTRUST
, SAMR_FIELD_ACCT_FLAGS
,
5751 0, 0, 0, 0, 0, 0, 0,
5754 SamOEMhashBlob(info
.info23
.password
.data
, 516,
5755 &cli
->user_session_key
);
5757 result
= rpccli_samr_SetUserInfo2(pipe_hnd
, mem_ctx
,
5762 if (!NT_STATUS_IS_OK(result
)) {
5763 DEBUG(0,("Could not set trust account password: %s\n",
5764 nt_errstr(result
)));
5770 SAFE_FREE(acct_name
);
5775 * Create interdomain trust account for a remote domain.
5777 * @param argc Standard argc.
5778 * @param argv Standard argv without initial components.
5780 * @return Integer status (0 means success).
5783 static int rpc_trustdom_add(struct net_context
*c
, int argc
, const char **argv
)
5785 if (argc
> 0 && !c
->display_usage
) {
5786 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
5787 rpc_trustdom_add_internals
, argc
, argv
);
5790 "net rpc trustdom add <domain_name> <trust password>\n");
5797 * Remove interdomain trust account from the RPC server.
5798 * All parameters (except for argc and argv) are passed by run_rpc_command
5801 * @param c A net_context structure.
5802 * @param domain_sid The domain sid acquired from the server.
5803 * @param cli A cli_state connected to the server.
5804 * @param mem_ctx Talloc context, destroyed on completion of the function.
5805 * @param argc Standard main() style argc.
5806 * @param argv Standard main() style argv. Initial components are already
5809 * @return normal NTSTATUS return code.
5812 static NTSTATUS
rpc_trustdom_del_internals(struct net_context
*c
,
5813 const DOM_SID
*domain_sid
,
5814 const char *domain_name
,
5815 struct cli_state
*cli
,
5816 struct rpc_pipe_client
*pipe_hnd
,
5817 TALLOC_CTX
*mem_ctx
,
5821 POLICY_HND connect_pol
, domain_pol
, user_pol
;
5822 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
5824 DOM_SID trust_acct_sid
;
5825 struct samr_Ids user_rids
, name_types
;
5826 struct lsa_String lsa_acct_name
;
5829 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5830 return NT_STATUS_INVALID_PARAMETER
;
5834 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5836 acct_name
= talloc_asprintf(mem_ctx
, "%s$", argv
[0]);
5838 if (acct_name
== NULL
)
5839 return NT_STATUS_NO_MEMORY
;
5841 strupper_m(acct_name
);
5843 /* Get samr policy handle */
5844 result
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
5846 MAXIMUM_ALLOWED_ACCESS
,
5848 if (!NT_STATUS_IS_OK(result
)) {
5852 /* Get domain policy handle */
5853 result
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
5855 MAXIMUM_ALLOWED_ACCESS
,
5856 CONST_DISCARD(struct dom_sid2
*, domain_sid
),
5858 if (!NT_STATUS_IS_OK(result
)) {
5862 init_lsa_String(&lsa_acct_name
, acct_name
);
5864 result
= rpccli_samr_LookupNames(pipe_hnd
, mem_ctx
,
5871 if (!NT_STATUS_IS_OK(result
)) {
5872 d_printf("net rpc trustdom del: LookupNames on user %s failed %s\n",
5873 acct_name
, nt_errstr(result
) );
5877 result
= rpccli_samr_OpenUser(pipe_hnd
, mem_ctx
,
5879 MAXIMUM_ALLOWED_ACCESS
,
5883 if (!NT_STATUS_IS_OK(result
)) {
5884 d_printf("net rpc trustdom del: OpenUser on user %s failed %s\n",
5885 acct_name
, nt_errstr(result
) );
5889 /* append the rid to the domain sid */
5890 sid_copy(&trust_acct_sid
, domain_sid
);
5891 if (!sid_append_rid(&trust_acct_sid
, user_rids
.ids
[0])) {
5895 /* remove the sid */
5897 result
= rpccli_samr_RemoveMemberFromForeignDomain(pipe_hnd
, mem_ctx
,
5900 if (!NT_STATUS_IS_OK(result
)) {
5901 d_printf("net rpc trustdom del: RemoveMemberFromForeignDomain on user %s failed %s\n",
5902 acct_name
, nt_errstr(result
) );
5908 result
= rpccli_samr_DeleteUser(pipe_hnd
, mem_ctx
,
5911 if (!NT_STATUS_IS_OK(result
)) {
5912 d_printf("net rpc trustdom del: DeleteUser on user %s failed %s\n",
5913 acct_name
, nt_errstr(result
) );
5917 if (!NT_STATUS_IS_OK(result
)) {
5918 d_printf("Could not set trust account password: %s\n",
5928 * Delete interdomain trust account for a remote domain.
5930 * @param argc Standard argc.
5931 * @param argv Standard argv without initial components.
5933 * @return Integer status (0 means success).
5936 static int rpc_trustdom_del(struct net_context
*c
, int argc
, const char **argv
)
5938 if (argc
> 0 && !c
->display_usage
) {
5939 return run_rpc_command(c
, NULL
, PI_SAMR
, 0,
5940 rpc_trustdom_del_internals
, argc
, argv
);
5943 "net rpc trustdom del <domain>\n");
5948 static NTSTATUS
rpc_trustdom_get_pdc(struct net_context
*c
,
5949 struct cli_state
*cli
,
5950 TALLOC_CTX
*mem_ctx
,
5951 const char *domain_name
)
5953 char *dc_name
= NULL
;
5954 const char *buffer
= NULL
;
5955 struct rpc_pipe_client
*netr
;
5958 /* Use NetServerEnum2 */
5960 if (cli_get_pdc_name(cli
, domain_name
, &dc_name
)) {
5962 return NT_STATUS_OK
;
5965 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
5966 for domain %s\n", domain_name
));
5968 /* Try netr_GetDcName */
5970 status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_netlogon
.syntax_id
,
5972 if (!NT_STATUS_IS_OK(status
)) {
5976 status
= rpccli_netr_GetDcName(netr
, mem_ctx
,
5983 if (NT_STATUS_IS_OK(status
)) {
5987 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
5988 for domain %s\n", domain_name
));
5994 * Establish trust relationship to a trusting domain.
5995 * Interdomain account must already be created on remote PDC.
5997 * @param c A net_context structure.
5998 * @param argc Standard argc.
5999 * @param argv Standard argv without initial components.
6001 * @return Integer status (0 means success).
6004 static int rpc_trustdom_establish(struct net_context
*c
, int argc
,
6007 struct cli_state
*cli
= NULL
;
6008 struct sockaddr_storage server_ss
;
6009 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6010 POLICY_HND connect_hnd
;
6011 TALLOC_CTX
*mem_ctx
;
6013 DOM_SID
*domain_sid
;
6018 union lsa_PolicyInformation
*info
= NULL
;
6021 * Connect to \\server\ipc$ as 'our domain' account with password
6024 if (argc
!= 1 || c
->display_usage
) {
6026 "net rpc trustdom establish <domain_name>\n");
6030 domain_name
= smb_xstrdup(argv
[0]);
6031 strupper_m(domain_name
);
6033 /* account name used at first is our domain's name with '$' */
6034 asprintf(&acct_name
, "%s$", lp_workgroup());
6035 strupper_m(acct_name
);
6038 * opt_workgroup will be used by connection functions further,
6039 * hence it should be set to remote domain name instead of ours
6041 if (c
->opt_workgroup
) {
6042 c
->opt_workgroup
= smb_xstrdup(domain_name
);
6045 c
->opt_user_name
= acct_name
;
6047 /* find the domain controller */
6048 if (!net_find_pdc(&server_ss
, pdc_name
, domain_name
)) {
6049 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name
));
6053 /* connect to ipc$ as username/password */
6054 nt_status
= connect_to_ipc(c
, &cli
, &server_ss
, pdc_name
);
6055 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
)) {
6057 /* Is it trusting domain account for sure ? */
6058 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6059 nt_errstr(nt_status
)));
6063 /* store who we connected to */
6065 saf_store( domain_name
, pdc_name
);
6068 * Connect to \\server\ipc$ again (this time anonymously)
6071 nt_status
= connect_to_ipc_anonymous(c
, &cli
, &server_ss
,
6074 if (NT_STATUS_IS_ERR(nt_status
)) {
6075 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6076 domain_name
, nt_errstr(nt_status
)));
6080 if (!(mem_ctx
= talloc_init("establishing trust relationship to "
6081 "domain %s", domain_name
))) {
6082 DEBUG(0, ("talloc_init() failed\n"));
6087 /* Make sure we're talking to a proper server */
6089 nt_status
= rpc_trustdom_get_pdc(c
, cli
, mem_ctx
, domain_name
);
6090 if (!NT_STATUS_IS_OK(nt_status
)) {
6092 talloc_destroy(mem_ctx
);
6097 * Call LsaOpenPolicy and LsaQueryInfo
6100 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
.syntax_id
,
6102 if (!NT_STATUS_IS_OK(nt_status
)) {
6103 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status
) ));
6105 talloc_destroy(mem_ctx
);
6109 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true, SEC_RIGHTS_QUERY_VALUE
,
6111 if (NT_STATUS_IS_ERR(nt_status
)) {
6112 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6113 nt_errstr(nt_status
)));
6115 talloc_destroy(mem_ctx
);
6119 /* Querying info level 5 */
6121 nt_status
= rpccli_lsa_QueryInfoPolicy(pipe_hnd
, mem_ctx
,
6123 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6125 if (NT_STATUS_IS_ERR(nt_status
)) {
6126 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6127 nt_errstr(nt_status
)));
6129 talloc_destroy(mem_ctx
);
6133 domain_sid
= info
->account_domain
.sid
;
6135 /* There should be actually query info level 3 (following nt serv behaviour),
6136 but I still don't know if it's _really_ necessary */
6139 * Store the password in secrets db
6142 if (!pdb_set_trusteddom_pw(domain_name
, c
->opt_password
, domain_sid
)) {
6143 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6145 talloc_destroy(mem_ctx
);
6150 * Close the pipes and clean up
6153 nt_status
= rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &connect_hnd
);
6154 if (NT_STATUS_IS_ERR(nt_status
)) {
6155 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6156 nt_errstr(nt_status
)));
6158 talloc_destroy(mem_ctx
);
6164 talloc_destroy(mem_ctx
);
6166 d_printf("Trust to domain %s established\n", domain_name
);
6171 * Revoke trust relationship to the remote domain.
6173 * @param c A net_context structure.
6174 * @param argc Standard argc.
6175 * @param argv Standard argv without initial components.
6177 * @return Integer status (0 means success).
6180 static int rpc_trustdom_revoke(struct net_context
*c
, int argc
,
6186 if (argc
< 1 || c
->display_usage
) {
6188 "net rpc trustdom revoke <domain_name>\n"
6189 " Revoke trust relationship\n"
6190 " domain_name\tName of domain to revoke trust\n");
6194 /* generate upper cased domain name */
6195 domain_name
= smb_xstrdup(argv
[0]);
6196 strupper_m(domain_name
);
6198 /* delete password of the trust */
6199 if (!pdb_del_trusteddom_pw(domain_name
)) {
6200 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6207 SAFE_FREE(domain_name
);
6211 static NTSTATUS
rpc_query_domain_sid(struct net_context
*c
,
6212 const DOM_SID
*domain_sid
,
6213 const char *domain_name
,
6214 struct cli_state
*cli
,
6215 struct rpc_pipe_client
*pipe_hnd
,
6216 TALLOC_CTX
*mem_ctx
,
6221 sid_to_fstring(str_sid
, domain_sid
);
6222 d_printf("%s\n", str_sid
);
6223 return NT_STATUS_OK
;
6226 static void print_trusted_domain(DOM_SID
*dom_sid
, const char *trusted_dom_name
)
6228 fstring ascii_sid
, padding
;
6229 int pad_len
, col_len
= 20;
6231 /* convert sid into ascii string */
6232 sid_to_fstring(ascii_sid
, dom_sid
);
6234 /* calculate padding space for d_printf to look nicer */
6235 pad_len
= col_len
- strlen(trusted_dom_name
);
6236 padding
[pad_len
] = 0;
6237 do padding
[--pad_len
] = ' '; while (pad_len
);
6239 d_printf("%s%s%s\n", trusted_dom_name
, padding
, ascii_sid
);
6242 static NTSTATUS
vampire_trusted_domain(struct rpc_pipe_client
*pipe_hnd
,
6243 TALLOC_CTX
*mem_ctx
,
6246 const char *trusted_dom_name
)
6249 union lsa_TrustedDomainInfo
*info
= NULL
;
6250 char *cleartextpwd
= NULL
;
6251 uint8_t nt_hash
[16];
6254 nt_status
= rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd
, mem_ctx
,
6257 LSA_TRUSTED_DOMAIN_INFO_PASSWORD
,
6259 if (NT_STATUS_IS_ERR(nt_status
)) {
6260 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6261 nt_errstr(nt_status
)));
6265 data
= data_blob(info
->password
.password
->data
,
6266 info
->password
.password
->length
);
6268 if (!rpccli_get_pwd_hash(pipe_hnd
, nt_hash
)) {
6269 DEBUG(0, ("Could not retrieve password hash\n"));
6273 cleartextpwd
= decrypt_trustdom_secret(nt_hash
, &data
);
6275 if (cleartextpwd
== NULL
) {
6276 DEBUG(0,("retrieved NULL password\n"));
6277 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6281 if (!pdb_set_trusteddom_pw(trusted_dom_name
, cleartextpwd
, &dom_sid
)) {
6282 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6283 nt_status
= NT_STATUS_UNSUCCESSFUL
;
6287 #ifdef DEBUG_PASSWORD
6288 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6289 "password: [%s]\n", trusted_dom_name
,
6290 sid_string_dbg(&dom_sid
), cleartextpwd
));
6294 SAFE_FREE(cleartextpwd
);
6295 data_blob_free(&data
);
6300 static int rpc_trustdom_vampire(struct net_context
*c
, int argc
,
6303 /* common variables */
6304 TALLOC_CTX
* mem_ctx
;
6305 struct cli_state
*cli
= NULL
;
6306 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6308 const char *domain_name
= NULL
;
6309 DOM_SID
*queried_dom_sid
;
6310 POLICY_HND connect_hnd
;
6311 union lsa_PolicyInformation
*info
= NULL
;
6313 /* trusted domains listing variables */
6314 unsigned int enum_ctx
= 0;
6316 struct lsa_DomainList dom_list
;
6319 if (c
->display_usage
) {
6321 "net rpc trustdom vampire\n"
6322 " Vampire trust relationship from remote server\n");
6327 * Listing trusted domains (stored in secrets.tdb, if local)
6330 mem_ctx
= talloc_init("trust relationships vampire");
6333 * set domain and pdc name to local samba server (default)
6334 * or to remote one given in command line
6337 if (StrCaseCmp(c
->opt_workgroup
, lp_workgroup())) {
6338 domain_name
= c
->opt_workgroup
;
6339 c
->opt_target_workgroup
= c
->opt_workgroup
;
6341 fstrcpy(pdc_name
, global_myname());
6342 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
6343 c
->opt_target_workgroup
= domain_name
;
6346 /* open \PIPE\lsarpc and open policy handle */
6347 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
6348 if (!NT_STATUS_IS_OK(nt_status
)) {
6349 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6350 nt_errstr(nt_status
)));
6351 talloc_destroy(mem_ctx
);
6355 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
.syntax_id
,
6357 if (!NT_STATUS_IS_OK(nt_status
)) {
6358 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6359 nt_errstr(nt_status
) ));
6361 talloc_destroy(mem_ctx
);
6365 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, SEC_RIGHTS_QUERY_VALUE
,
6367 if (NT_STATUS_IS_ERR(nt_status
)) {
6368 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6369 nt_errstr(nt_status
)));
6371 talloc_destroy(mem_ctx
);
6375 /* query info level 5 to obtain sid of a domain being queried */
6376 nt_status
= rpccli_lsa_QueryInfoPolicy(pipe_hnd
, mem_ctx
,
6378 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6381 if (NT_STATUS_IS_ERR(nt_status
)) {
6382 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6383 nt_errstr(nt_status
)));
6385 talloc_destroy(mem_ctx
);
6389 queried_dom_sid
= info
->account_domain
.sid
;
6392 * Keep calling LsaEnumTrustdom over opened pipe until
6393 * the end of enumeration is reached
6396 d_printf("Vampire trusted domains:\n\n");
6399 nt_status
= rpccli_lsa_EnumTrustDom(pipe_hnd
, mem_ctx
,
6404 if (NT_STATUS_IS_ERR(nt_status
)) {
6405 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6406 nt_errstr(nt_status
)));
6408 talloc_destroy(mem_ctx
);
6412 for (i
= 0; i
< dom_list
.count
; i
++) {
6414 print_trusted_domain(dom_list
.domains
[i
].sid
,
6415 dom_list
.domains
[i
].name
.string
);
6417 nt_status
= vampire_trusted_domain(pipe_hnd
, mem_ctx
, &connect_hnd
,
6418 *dom_list
.domains
[i
].sid
,
6419 dom_list
.domains
[i
].name
.string
);
6420 if (!NT_STATUS_IS_OK(nt_status
)) {
6422 talloc_destroy(mem_ctx
);
6428 * in case of no trusted domains say something rather
6429 * than just display blank line
6431 if (!dom_list
.count
) d_printf("none\n");
6433 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
6435 /* close this connection before doing next one */
6436 nt_status
= rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &connect_hnd
);
6437 if (NT_STATUS_IS_ERR(nt_status
)) {
6438 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6439 nt_errstr(nt_status
)));
6441 talloc_destroy(mem_ctx
);
6445 /* close lsarpc pipe and connection to IPC$ */
6448 talloc_destroy(mem_ctx
);
6452 static int rpc_trustdom_list(struct net_context
*c
, int argc
, const char **argv
)
6454 /* common variables */
6455 TALLOC_CTX
* mem_ctx
;
6456 struct cli_state
*cli
= NULL
, *remote_cli
= NULL
;
6457 struct rpc_pipe_client
*pipe_hnd
= NULL
;
6459 const char *domain_name
= NULL
;
6460 DOM_SID
*queried_dom_sid
;
6462 int ascii_dom_name_len
;
6463 POLICY_HND connect_hnd
;
6464 union lsa_PolicyInformation
*info
= NULL
;
6466 /* trusted domains listing variables */
6467 unsigned int num_domains
, enum_ctx
= 0;
6468 int i
, pad_len
, col_len
= 20;
6469 struct lsa_DomainList dom_list
;
6472 /* trusting domains listing variables */
6473 POLICY_HND domain_hnd
;
6474 struct samr_SamArray
*trusts
= NULL
;
6476 if (c
->display_usage
) {
6478 "net rpc trustdom list\n"
6479 " List trust relationships\n");
6484 * Listing trusted domains (stored in secrets.tdb, if local)
6487 mem_ctx
= talloc_init("trust relationships listing");
6490 * set domain and pdc name to local samba server (default)
6491 * or to remote one given in command line
6494 if (StrCaseCmp(c
->opt_workgroup
, lp_workgroup())) {
6495 domain_name
= c
->opt_workgroup
;
6496 c
->opt_target_workgroup
= c
->opt_workgroup
;
6498 fstrcpy(pdc_name
, global_myname());
6499 domain_name
= talloc_strdup(mem_ctx
, lp_workgroup());
6500 c
->opt_target_workgroup
= domain_name
;
6503 /* open \PIPE\lsarpc and open policy handle */
6504 nt_status
= net_make_ipc_connection(c
, NET_FLAGS_PDC
, &cli
);
6505 if (!NT_STATUS_IS_OK(nt_status
)) {
6506 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6507 nt_errstr(nt_status
)));
6508 talloc_destroy(mem_ctx
);
6512 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_lsarpc
.syntax_id
,
6514 if (!NT_STATUS_IS_OK(nt_status
)) {
6515 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6516 nt_errstr(nt_status
) ));
6518 talloc_destroy(mem_ctx
);
6522 nt_status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, false, SEC_RIGHTS_QUERY_VALUE
,
6524 if (NT_STATUS_IS_ERR(nt_status
)) {
6525 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6526 nt_errstr(nt_status
)));
6528 talloc_destroy(mem_ctx
);
6532 /* query info level 5 to obtain sid of a domain being queried */
6533 nt_status
= rpccli_lsa_QueryInfoPolicy(pipe_hnd
, mem_ctx
,
6535 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
6538 if (NT_STATUS_IS_ERR(nt_status
)) {
6539 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6540 nt_errstr(nt_status
)));
6542 talloc_destroy(mem_ctx
);
6546 queried_dom_sid
= info
->account_domain
.sid
;
6549 * Keep calling LsaEnumTrustdom over opened pipe until
6550 * the end of enumeration is reached
6553 d_printf("Trusted domains list:\n\n");
6556 nt_status
= rpccli_lsa_EnumTrustDom(pipe_hnd
, mem_ctx
,
6561 if (NT_STATUS_IS_ERR(nt_status
)) {
6562 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6563 nt_errstr(nt_status
)));
6565 talloc_destroy(mem_ctx
);
6569 for (i
= 0; i
< dom_list
.count
; i
++) {
6570 print_trusted_domain(dom_list
.domains
[i
].sid
,
6571 dom_list
.domains
[i
].name
.string
);
6575 * in case of no trusted domains say something rather
6576 * than just display blank line
6578 if (!dom_list
.count
) d_printf("none\n");
6580 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
6582 /* close this connection before doing next one */
6583 nt_status
= rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &connect_hnd
);
6584 if (NT_STATUS_IS_ERR(nt_status
)) {
6585 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6586 nt_errstr(nt_status
)));
6588 talloc_destroy(mem_ctx
);
6592 TALLOC_FREE(pipe_hnd
);
6595 * Listing trusting domains (stored in passdb backend, if local)
6598 d_printf("\nTrusting domains list:\n\n");
6601 * Open \PIPE\samr and get needed policy handles
6603 nt_status
= cli_rpc_pipe_open_noauth(cli
, &ndr_table_samr
.syntax_id
,
6605 if (!NT_STATUS_IS_OK(nt_status
)) {
6606 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status
)));
6608 talloc_destroy(mem_ctx
);
6613 nt_status
= rpccli_samr_Connect2(pipe_hnd
, mem_ctx
,
6615 SA_RIGHT_SAM_OPEN_DOMAIN
,
6617 if (!NT_STATUS_IS_OK(nt_status
)) {
6618 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6619 nt_errstr(nt_status
)));
6621 talloc_destroy(mem_ctx
);
6625 /* SamrOpenDomain - we have to open domain policy handle in order to be
6626 able to enumerate accounts*/
6627 nt_status
= rpccli_samr_OpenDomain(pipe_hnd
, mem_ctx
,
6629 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
6632 if (!NT_STATUS_IS_OK(nt_status
)) {
6633 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6634 nt_errstr(nt_status
)));
6636 talloc_destroy(mem_ctx
);
6641 * perform actual enumeration
6644 enum_ctx
= 0; /* reset enumeration context from last enumeration */
6647 nt_status
= rpccli_samr_EnumDomainUsers(pipe_hnd
, mem_ctx
,
6654 if (NT_STATUS_IS_ERR(nt_status
)) {
6655 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6656 nt_errstr(nt_status
)));
6658 talloc_destroy(mem_ctx
);
6662 for (i
= 0; i
< num_domains
; i
++) {
6664 char *str
= CONST_DISCARD(char *, trusts
->entries
[i
].name
.string
);
6667 * get each single domain's sid (do we _really_ need this ?):
6668 * 1) connect to domain's pdc
6669 * 2) query the pdc for domain's sid
6672 /* get rid of '$' tail */
6673 ascii_dom_name_len
= strlen(str
);
6674 if (ascii_dom_name_len
&& ascii_dom_name_len
< FSTRING_LEN
)
6675 str
[ascii_dom_name_len
- 1] = '\0';
6677 /* calculate padding space for d_printf to look nicer */
6678 pad_len
= col_len
- strlen(str
);
6679 padding
[pad_len
] = 0;
6680 do padding
[--pad_len
] = ' '; while (pad_len
);
6682 /* set opt_* variables to remote domain */
6684 c
->opt_workgroup
= talloc_strdup(mem_ctx
, str
);
6685 c
->opt_target_workgroup
= c
->opt_workgroup
;
6687 d_printf("%s%s", str
, padding
);
6689 /* connect to remote domain controller */
6690 nt_status
= net_make_ipc_connection(c
,
6691 NET_FLAGS_PDC
| NET_FLAGS_ANONYMOUS
,
6693 if (NT_STATUS_IS_OK(nt_status
)) {
6694 /* query for domain's sid */
6695 if (run_rpc_command(c
, remote_cli
, PI_LSARPC
, 0,
6696 rpc_query_domain_sid
, argc
,
6698 d_fprintf(stderr
, "couldn't get domain's sid\n");
6700 cli_shutdown(remote_cli
);
6703 d_fprintf(stderr
, "domain controller is not "
6705 nt_errstr(nt_status
));
6709 if (!num_domains
) d_printf("none\n");
6711 } while (NT_STATUS_EQUAL(nt_status
, STATUS_MORE_ENTRIES
));
6713 /* close opened samr and domain policy handles */
6714 nt_status
= rpccli_samr_Close(pipe_hnd
, mem_ctx
, &domain_hnd
);
6715 if (!NT_STATUS_IS_OK(nt_status
)) {
6716 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name
));
6719 nt_status
= rpccli_samr_Close(pipe_hnd
, mem_ctx
, &connect_hnd
);
6720 if (!NT_STATUS_IS_OK(nt_status
)) {
6721 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name
));
6724 /* close samr pipe and connection to IPC$ */
6727 talloc_destroy(mem_ctx
);
6732 * Entrypoint for 'net rpc trustdom' code.
6734 * @param argc Standard argc.
6735 * @param argv Standard argv without initial components.
6737 * @return Integer status (0 means success).
6740 static int rpc_trustdom(struct net_context
*c
, int argc
, const char **argv
)
6742 struct functable func
[] = {
6747 "Add trusted domain's account",
6748 "net rpc trustdom add\n"
6749 " Add trusted domain's account"
6755 "Remove trusted domain's account",
6756 "net rpc trustdom del\n"
6757 " Remove trusted domain's account"
6761 rpc_trustdom_establish
,
6763 "Establish trust relationship",
6764 "net rpc trustdom establish\n"
6765 " Establish trust relationship"
6769 rpc_trustdom_revoke
,
6771 "Revoke trust relationship",
6772 "net rpc trustdom revoke\n"
6773 " Revoke trust relationship"
6779 "List domain trusts",
6780 "net rpc trustdom list\n"
6781 " List domain trusts"
6785 rpc_trustdom_vampire
,
6787 "Vampire trusts from remote server",
6788 "net rpc trustdom vampire\n"
6789 " Vampire trusts from remote server"
6791 {NULL
, NULL
, 0, NULL
, NULL
}
6794 return net_run_function(c
, argc
, argv
, "net rpc trustdom", func
);
6798 * Check if a server will take rpc commands
6799 * @param flags Type of server to connect to (PDC, DMB, localhost)
6800 * if the host is not explicitly specified
6801 * @return bool (true means rpc supported)
6803 bool net_rpc_check(struct net_context
*c
, unsigned flags
)
6805 struct cli_state
*cli
;
6807 struct sockaddr_storage server_ss
;
6808 char *server_name
= NULL
;
6811 /* flags (i.e. server type) may depend on command */
6812 if (!net_find_server(c
, NULL
, flags
, &server_ss
, &server_name
))
6815 if ((cli
= cli_initialise()) == NULL
) {
6819 status
= cli_connect(cli
, server_name
, &server_ss
);
6820 if (!NT_STATUS_IS_OK(status
))
6822 if (!attempt_netbios_session_request(&cli
, global_myname(),
6823 server_name
, &server_ss
))
6825 if (!cli_negprot(cli
))
6827 if (cli
->protocol
< PROTOCOL_NT1
)
6836 /* dump sam database via samsync rpc calls */
6837 static int rpc_samdump(struct net_context
*c
, int argc
, const char **argv
) {
6838 if (c
->display_usage
) {
6841 " Dump remote SAM database\n");
6845 return run_rpc_command(c
, NULL
, PI_NETLOGON
, NET_FLAGS_ANONYMOUS
,
6846 rpc_samdump_internals
, argc
, argv
);
6849 /* syncronise sam database via samsync rpc calls */
6850 static int rpc_vampire(struct net_context
*c
, int argc
, const char **argv
)
6852 struct functable func
[] = {
6857 "Dump remote SAM database to ldif",
6858 "net rpc vampire ldif\n"
6859 " Dump remote SAM database to LDIF file or stdout"
6865 "Dump remote SAM database to Kerberos Keytab",
6866 "net rpc vampire keytab\n"
6867 " Dump remote SAM database to Kerberos keytab file"
6870 {NULL
, NULL
, 0, NULL
, NULL
}
6874 if (c
->display_usage
) {
6877 " Vampire remote SAM database\n");
6881 return run_rpc_command(c
, NULL
, PI_NETLOGON
, NET_FLAGS_ANONYMOUS
,
6882 rpc_vampire_internals
,
6886 return net_run_function(c
, argc
, argv
, "net rpc vampire", func
);
6890 * Migrate everything from a print server.
6892 * @param c A net_context structure.
6893 * @param argc Standard main() style argc.
6894 * @param argv Standard main() style argv. Initial components are already
6897 * @return A shell status integer (0 for success).
6899 * The order is important !
6900 * To successfully add drivers the print queues have to exist !
6901 * Applying ACLs should be the last step, because you're easily locked out.
6904 static int rpc_printer_migrate_all(struct net_context
*c
, int argc
,
6909 if (c
->display_usage
) {
6911 "net rpc printer migrate all\n"
6912 " Migrate everything from a print server\n");
6917 d_printf("no server to migrate\n");
6921 ret
= run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6922 rpc_printer_migrate_printers_internals
, argc
,
6927 ret
= run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6928 rpc_printer_migrate_drivers_internals
, argc
,
6933 ret
= run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6934 rpc_printer_migrate_forms_internals
, argc
, argv
);
6938 ret
= run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6939 rpc_printer_migrate_settings_internals
, argc
,
6944 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6945 rpc_printer_migrate_security_internals
, argc
,
6951 * Migrate print drivers from a print server.
6953 * @param c A net_context structure.
6954 * @param argc Standard main() style argc.
6955 * @param argv Standard main() style argv. Initial components are already
6958 * @return A shell status integer (0 for success).
6960 static int rpc_printer_migrate_drivers(struct net_context
*c
, int argc
,
6963 if (c
->display_usage
) {
6965 "net rpc printer migrate drivers\n"
6966 " Migrate print-drivers from a print-server\n");
6971 d_printf("no server to migrate\n");
6975 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
6976 rpc_printer_migrate_drivers_internals
,
6981 * Migrate print-forms from a print-server.
6983 * @param c A net_context structure.
6984 * @param argc Standard main() style argc.
6985 * @param argv Standard main() style argv. Initial components are already
6988 * @return A shell status integer (0 for success).
6990 static int rpc_printer_migrate_forms(struct net_context
*c
, int argc
,
6993 if (c
->display_usage
) {
6995 "net rpc printer migrate forms\n"
6996 " Migrate print-forms from a print-server\n");
7001 d_printf("no server to migrate\n");
7005 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7006 rpc_printer_migrate_forms_internals
,
7011 * Migrate printers from a print-server.
7013 * @param c A net_context structure.
7014 * @param argc Standard main() style argc.
7015 * @param argv Standard main() style argv. Initial components are already
7018 * @return A shell status integer (0 for success).
7020 static int rpc_printer_migrate_printers(struct net_context
*c
, int argc
,
7023 if (c
->display_usage
) {
7025 "net rpc printer migrate printers\n"
7026 " Migrate printers from a print-server\n");
7031 d_printf("no server to migrate\n");
7035 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7036 rpc_printer_migrate_printers_internals
,
7041 * Migrate printer-ACLs from a print-server
7043 * @param c A net_context structure.
7044 * @param argc Standard main() style argc.
7045 * @param argv Standard main() style argv. Initial components are already
7048 * @return A shell status integer (0 for success).
7050 static int rpc_printer_migrate_security(struct net_context
*c
, int argc
,
7053 if (c
->display_usage
) {
7055 "net rpc printer migrate security\n"
7056 " Migrate printer-ACLs from a print-server\n");
7061 d_printf("no server to migrate\n");
7065 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7066 rpc_printer_migrate_security_internals
,
7071 * Migrate printer-settings from a print-server.
7073 * @param c A net_context structure.
7074 * @param argc Standard main() style argc.
7075 * @param argv Standard main() style argv. Initial components are already
7078 * @return A shell status integer (0 for success).
7080 static int rpc_printer_migrate_settings(struct net_context
*c
, int argc
,
7083 if (c
->display_usage
) {
7085 "net rpc printer migrate settings\n"
7086 " Migrate printer-settings from a print-server\n");
7091 d_printf("no server to migrate\n");
7095 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7096 rpc_printer_migrate_settings_internals
,
7101 * 'net rpc printer' entrypoint.
7103 * @param c A net_context structure.
7104 * @param argc Standard main() style argc.
7105 * @param argv Standard main() style argv. Initial components are already
7109 int rpc_printer_migrate(struct net_context
*c
, int argc
, const char **argv
)
7112 /* ouch: when addriver and setdriver are called from within
7113 rpc_printer_migrate_drivers_internals, the printer-queue already
7116 struct functable func
[] = {
7119 rpc_printer_migrate_all
,
7121 "Migrate all from remote to local print server",
7122 "net rpc printer migrate all\n"
7123 " Migrate all from remote to local print server"
7127 rpc_printer_migrate_drivers
,
7129 "Migrate drivers to local server",
7130 "net rpc printer migrate drivers\n"
7131 " Migrate drivers to local server"
7135 rpc_printer_migrate_forms
,
7137 "Migrate froms to local server",
7138 "net rpc printer migrate forms\n"
7139 " Migrate froms to local server"
7143 rpc_printer_migrate_printers
,
7145 "Migrate printers to local server",
7146 "net rpc printer migrate printers\n"
7147 " Migrate printers to local server"
7151 rpc_printer_migrate_security
,
7153 "Mirgate printer ACLs to local server",
7154 "net rpc printer migrate security\n"
7155 " Mirgate printer ACLs to local server"
7159 rpc_printer_migrate_settings
,
7161 "Migrate printer settings to local server",
7162 "net rpc printer migrate settings\n"
7163 " Migrate printer settings to local server"
7165 {NULL
, NULL
, 0, NULL
, NULL
}
7168 return net_run_function(c
, argc
, argv
, "net rpc printer migrate",func
);
7173 * List printers on a remote RPC server.
7175 * @param c A net_context structure.
7176 * @param argc Standard main() style argc.
7177 * @param argv Standard main() style argv. Initial components are already
7180 * @return A shell status integer (0 for success).
7182 static int rpc_printer_list(struct net_context
*c
, int argc
, const char **argv
)
7184 if (c
->display_usage
) {
7186 "net rpc printer list\n"
7187 " List printers on a remote RPC server\n");
7191 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7192 rpc_printer_list_internals
,
7197 * List printer-drivers on a remote RPC server.
7199 * @param c A net_context structure.
7200 * @param argc Standard main() style argc.
7201 * @param argv Standard main() style argv. Initial components are already
7204 * @return A shell status integer (0 for success).
7206 static int rpc_printer_driver_list(struct net_context
*c
, int argc
,
7209 if (c
->display_usage
) {
7211 "net rpc printer driver\n"
7212 " List printer-drivers on a remote RPC server\n");
7216 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7217 rpc_printer_driver_list_internals
,
7222 * Publish printer in ADS via MSRPC.
7224 * @param c A net_context structure.
7225 * @param argc Standard main() style argc.
7226 * @param argv Standard main() style argv. Initial components are already
7229 * @return A shell status integer (0 for success).
7231 static int rpc_printer_publish_publish(struct net_context
*c
, int argc
,
7234 if (c
->display_usage
) {
7236 "net rpc printer publish publish\n"
7237 " Publish printer in ADS via MSRPC\n");
7241 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7242 rpc_printer_publish_publish_internals
,
7247 * Update printer in ADS via MSRPC.
7249 * @param c A net_context structure.
7250 * @param argc Standard main() style argc.
7251 * @param argv Standard main() style argv. Initial components are already
7254 * @return A shell status integer (0 for success).
7256 static int rpc_printer_publish_update(struct net_context
*c
, int argc
, const char **argv
)
7258 if (c
->display_usage
) {
7260 "net rpc printer publish update\n"
7261 " Update printer in ADS via MSRPC\n");
7265 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7266 rpc_printer_publish_update_internals
,
7271 * UnPublish printer in ADS via MSRPC.
7273 * @param c A net_context structure.
7274 * @param argc Standard main() style argc.
7275 * @param argv Standard main() style argv. Initial components are already
7278 * @return A shell status integer (0 for success).
7280 static int rpc_printer_publish_unpublish(struct net_context
*c
, int argc
,
7283 if (c
->display_usage
) {
7285 "net rpc printer publish unpublish\n"
7286 " UnPublish printer in ADS via MSRPC\n");
7290 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7291 rpc_printer_publish_unpublish_internals
,
7296 * List published printers via MSRPC.
7298 * @param c A net_context structure.
7299 * @param argc Standard main() style argc.
7300 * @param argv Standard main() style argv. Initial components are already
7303 * @return A shell status integer (0 for success).
7305 static int rpc_printer_publish_list(struct net_context
*c
, int argc
,
7308 if (c
->display_usage
) {
7310 "net rpc printer publish list\n"
7311 " List published printers via MSRPC\n");
7315 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7316 rpc_printer_publish_list_internals
,
7322 * Publish printer in ADS.
7324 * @param c A net_context structure.
7325 * @param argc Standard main() style argc.
7326 * @param argv Standard main() style argv. Initial components are already
7329 * @return A shell status integer (0 for success).
7331 static int rpc_printer_publish(struct net_context
*c
, int argc
,
7335 struct functable func
[] = {
7338 rpc_printer_publish_publish
,
7340 "Publish printer in AD",
7341 "net rpc printer publish publish\n"
7342 " Publish printer in AD"
7346 rpc_printer_publish_update
,
7348 "Update printer in AD",
7349 "net rpc printer publish update\n"
7350 " Update printer in AD"
7354 rpc_printer_publish_unpublish
,
7356 "Unpublish printer",
7357 "net rpc printer publish unpublish\n"
7358 " Unpublish printer"
7362 rpc_printer_publish_list
,
7364 "List published printers",
7365 "net rpc printer publish list\n"
7366 " List published printers"
7368 {NULL
, NULL
, 0, NULL
, NULL
}
7372 if (c
->display_usage
) {
7373 d_printf("Usage:\n");
7374 d_printf("net rpc printer publish\n"
7375 " List published printers\n"
7376 " Alias of net rpc printer publish list\n");
7377 net_display_usage_from_functable(func
);
7380 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7381 rpc_printer_publish_list_internals
,
7385 return net_run_function(c
, argc
, argv
, "net rpc printer publish",func
);
7391 * Display rpc printer help page.
7393 * @param c A net_context structure.
7394 * @param argc Standard main() style argc.
7395 * @param argv Standard main() style argv. Initial components are already
7398 int rpc_printer_usage(struct net_context
*c
, int argc
, const char **argv
)
7400 d_printf("net rpc printer LIST [printer] [misc. options] [targets]\n"
7401 "\tlists all printers on print-server\n\n");
7402 d_printf("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7403 "\tlists all printer-drivers on print-server\n\n");
7404 d_printf("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7405 "\tpublishes printer settings in Active Directory\n"
7406 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n");
7407 d_printf("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7408 "\n\tmigrates printers from remote to local server\n\n");
7409 d_printf("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7410 "\n\tmigrates printer-settings from remote to local server\n\n");
7411 d_printf("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7412 "\n\tmigrates printer-drivers from remote to local server\n\n");
7413 d_printf("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7414 "\n\tmigrates printer-forms from remote to local server\n\n");
7415 d_printf("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7416 "\n\tmigrates printer-ACLs from remote to local server\n\n");
7417 d_printf("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7418 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7419 "\tremote to local print-server\n\n");
7420 net_common_methods_usage(c
, argc
, argv
);
7421 net_common_flags_usage(c
, argc
, argv
);
7423 "\t-v or --verbose\t\t\tgive verbose output\n"
7424 "\t --destination\t\tmigration target server (default: localhost)\n");
7430 * 'net rpc printer' entrypoint.
7432 * @param c A net_context structure.
7433 * @param argc Standard main() style argc.
7434 * @param argv Standard main() style argv. Initial components are already
7437 int net_rpc_printer(struct net_context
*c
, int argc
, const char **argv
)
7439 struct functable func
[] = {
7444 "List all printers on print server",
7445 "net rpc printer list\n"
7446 " List all printers on print server"
7450 rpc_printer_migrate
,
7452 "Migrate printer to local server",
7453 "net rpc printer migrate\n"
7454 " Migrate printer to local server"
7458 rpc_printer_driver_list
,
7460 "List printer drivers",
7461 "net rpc printer driver\n"
7462 " List printer drivers"
7466 rpc_printer_publish
,
7468 "Publish printer in AD",
7469 "net rpc printer publish\n"
7470 " Publish printer in AD"
7472 {NULL
, NULL
, 0, NULL
, NULL
}
7476 if (c
->display_usage
) {
7477 d_printf("Usage:\n");
7478 d_printf("net rpc printer\n"
7479 " List printers\n");
7480 net_display_usage_from_functable(func
);
7483 return run_rpc_command(c
, NULL
, PI_SPOOLSS
, 0,
7484 rpc_printer_list_internals
,
7488 return net_run_function(c
, argc
, argv
, "net rpc printer", func
);
7492 * 'net rpc' entrypoint.
7494 * @param c A net_context structure.
7495 * @param argc Standard main() style argc.
7496 * @param argv Standard main() style argv. Initial components are already
7500 int net_rpc(struct net_context
*c
, int argc
, const char **argv
)
7502 struct functable func
[] = {
7507 "Modify global audit settings",
7509 " Modify global audit settings"
7515 "Show basic info about a domain",
7517 " Show basic info about a domain"
7531 "Join a domain created in server manager",
7533 " Join a domain created in server manager"
7539 "Test that a join is valid",
7540 "net rpc testjoin\n"
7541 " Test that a join is valid"
7547 "List/modify users",
7549 " List/modify users"
7555 "Change a user password",
7556 "net rpc password\n"
7557 " Change a user password\n"
7558 " Alias for net rpc user password"
7564 "List/modify groups",
7566 " List/modify groups"
7572 "List/modify shares",
7574 " List/modify shares"
7588 "List/modify printers",
7590 " List/modify printers"
7594 net_rpc_changetrustpw
,
7596 "Change trust account password",
7597 "net rpc changetrustpw\n"
7598 " Change trust account password"
7604 "Modify domain trusts",
7605 "net rpc trustdom\n"
7606 " Modify domain trusts"
7612 "Abort a remote shutdown",
7613 "net rpc abortshutdown\n"
7614 " Abort a remote shutdown"
7620 "Shutdown a remote server",
7621 "net rpc shutdown\n"
7622 " Shutdown a remote server"
7628 "Dump SAM data of remote NT PDC",
7630 " Dump SAM data of remote NT PDC"
7636 "Sync a remote NT PDC's data into local passdb",
7638 " Sync a remote NT PDC's data into local passdb"
7644 "Fetch the domain sid into local secrets.tdb",
7646 " Fetch the domain sid into local secrets.tdb"
7652 "Manage privileges assigned to SID",
7654 " Manage privileges assigned to SID"
7660 "Start/stop/query remote services",
7662 " Start/stop/query remote services"
7668 "Manage registry hives",
7669 "net rpc registry\n"
7670 " Manage registry hives"
7676 "Open interactive shell on remote server",
7678 " Open interactive shell on remote server"
7680 {NULL
, NULL
, 0, NULL
, NULL
}
7682 return net_run_function(c
, argc
, argv
, "net rpc", func
);