2001-12-03 07:39:23 +03:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Copyright ( C ) 2001 Andrew Bartlett ( abartlet @ samba . org )
2002-07-15 14:35:28 +04:00
Copyright ( C ) 2002 Jim McDonough ( jmcd @ us . ibm . com )
2008-02-27 21:38:48 +03:00
Copyright ( C ) 2004 , 2008 Guenther Deschner ( gd @ samba . org )
2005-09-30 21:13:37 +04:00
Copyright ( C ) 2005 Jeremy Allison ( jra @ samba . org )
2006-09-22 03:57:32 +04:00
Copyright ( C ) 2006 Jelmer Vernooij ( jelmer @ samba . org )
2001-12-03 07:39:23 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-12-03 07:39:23 +03:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>. */
2001-12-03 07:39:23 +03:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2001-12-03 07:39:23 +03:00
2005-06-24 03:23:16 +04:00
static int net_mode_share ;
2007-12-05 03:35:24 +03:00
static bool sync_files ( struct copy_clistate * cp_clistate , const char * mask ) ;
2005-06-24 03:23:16 +04:00
2001-12-30 13:54:58 +03:00
/**
* @ file net_rpc . c
*
* @ brief RPC based subcommands for the ' net ' utility .
*
* This file should contain much of the functionality that used to
* be found in rpcclient , execpt that the commands should change
* less often , and the fucntionality should be sane ( the user is not
* expected to know a rid / sid before they conduct an operation etc . )
*
* @ todo Perhaps eventually these should be split out into a number
* of files , as this could get quite big .
* */
/**
* Many of the RPC functions need the domain sid . This function gets
* it at the start of every run
*
* @ param cli A cli_state already connected to the remote machine
*
* @ return The Domain SID of the remote machine .
2001-12-31 16:00:59 +03:00
* */
2001-12-05 03:26:36 +03:00
2006-02-04 01:19:41 +03:00
NTSTATUS net_get_remote_domain_sid ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2008-01-15 18:40:02 +03:00
DOM_SID * * domain_sid ,
const char * * domain_name )
2001-12-05 03:26:36 +03:00
{
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * lsa_pipe ;
2001-12-05 03:26:36 +03:00
POLICY_HND pol ;
NTSTATUS result = NT_STATUS_OK ;
2008-02-08 04:12:30 +03:00
union lsa_PolicyInformation * info = NULL ;
2005-09-30 21:13:37 +04:00
lsa_pipe = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & result ) ;
if ( ! lsa_pipe ) {
2006-02-04 01:19:41 +03:00
d_fprintf ( stderr , " Could not initialise lsa pipe \n " ) ;
return result ;
2001-12-05 03:26:36 +03:00
}
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_open_policy ( lsa_pipe , mem_ctx , False ,
2001-12-05 03:26:36 +03:00
SEC_RIGHTS_MAXIMUM_ALLOWED ,
& pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-02-04 01:19:41 +03:00
d_fprintf ( stderr , " open_policy failed: %s \n " ,
nt_errstr ( result ) ) ;
return result ;
2001-12-05 03:26:36 +03:00
}
2008-02-08 04:12:30 +03:00
result = rpccli_lsa_QueryInfoPolicy ( lsa_pipe , mem_ctx ,
& pol ,
LSA_POLICY_INFO_ACCOUNT_DOMAIN ,
& info ) ;
2001-12-05 03:26:36 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-02-04 01:19:41 +03:00
d_fprintf ( stderr , " lsaquery failed: %s \n " ,
nt_errstr ( result ) ) ;
return result ;
2001-12-05 03:26:36 +03:00
}
2008-02-08 04:12:30 +03:00
* domain_name = info - > account_domain . name . string ;
* domain_sid = info - > account_domain . sid ;
2006-09-21 02:49:02 +04:00
rpccli_lsa_Close ( lsa_pipe , mem_ctx , & pol ) ;
2006-02-04 01:19:41 +03:00
cli_rpc_pipe_close ( lsa_pipe ) ;
2001-12-05 03:26:36 +03:00
2006-02-04 01:19:41 +03:00
return NT_STATUS_OK ;
2001-12-05 03:26:36 +03:00
}
2001-12-30 13:54:58 +03:00
/**
* Run a single RPC command , from start to finish .
*
* @ param pipe_name the pipe to connect to ( usually a PIPE_ constant )
* @ param conn_flag a NET_FLAG_ combination . Passed to
* net_make_ipc_connection .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* @ return A shell status integer ( 0 for success )
*/
2001-12-05 03:26:36 +03:00
2005-09-30 21:13:37 +04:00
int run_rpc_command ( struct cli_state * cli_arg ,
const int pipe_idx ,
int conn_flags ,
rpc_command_fn fn ,
int argc ,
const char * * argv )
2001-12-05 03:26:36 +03:00
{
2002-08-17 18:45:04 +04:00
struct cli_state * cli = NULL ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2001-12-05 03:26:36 +03:00
TALLOC_CTX * mem_ctx ;
NTSTATUS nt_status ;
2001-12-30 13:54:58 +03:00
DOM_SID * domain_sid ;
2008-01-15 18:40:02 +03:00
const char * domain_name ;
2001-12-30 13:54:58 +03:00
2002-08-17 18:45:04 +04:00
/* make use of cli_state handed over as an argument, if possible */
2005-09-30 21:13:37 +04:00
if ( ! cli_arg ) {
2007-09-17 19:11:20 +04:00
nt_status = net_make_ipc_connection ( conn_flags , & cli ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 1 , ( " failed to make ipc connection: %s \n " ,
nt_errstr ( nt_status ) ) ) ;
return - 1 ;
}
2005-09-30 21:13:37 +04:00
} else {
2002-08-17 18:45:04 +04:00
cli = cli_arg ;
2005-09-30 21:13:37 +04:00
}
2002-08-17 18:45:04 +04:00
2001-12-30 13:54:58 +03:00
if ( ! cli ) {
return - 1 ;
}
2001-12-05 03:26:36 +03:00
/* Create mem_ctx */
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " run_rpc_command " ) ) ) {
2001-12-05 03:26:36 +03:00
DEBUG ( 0 , ( " talloc_init() failed \n " ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
2006-02-04 01:19:41 +03:00
nt_status = net_get_remote_domain_sid ( cli , mem_ctx , & domain_sid ,
& domain_name ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
cli_shutdown ( cli ) ;
return - 1 ;
}
2004-01-16 18:07:28 +03:00
2004-02-08 13:59:09 +03:00
if ( ! ( conn_flags & NET_FLAGS_NO_PIPE ) ) {
2005-09-30 21:13:37 +04:00
if ( lp_client_schannel ( ) & & ( pipe_idx = = PI_NETLOGON ) ) {
/* Always try and create an schannel netlogon pipe. */
pipe_hnd = cli_rpc_pipe_open_schannel ( cli , pipe_idx ,
PIPE_AUTH_LEVEL_PRIVACY ,
domain_name ,
& nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise schannel netlogon pipe. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
} else {
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , pipe_idx , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise pipe %s. Error was %s \n " ,
cli_get_pipe_name ( pipe_idx ) ,
nt_errstr ( nt_status ) ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
2004-02-08 13:59:09 +03:00
}
2001-12-05 03:26:36 +03:00
}
2005-09-30 21:13:37 +04:00
nt_status = fn ( domain_sid , domain_name , cli , pipe_hnd , mem_ctx , argc , argv ) ;
2001-12-05 03:26:36 +03:00
2001-12-31 16:00:59 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 1 , ( " rpc command function failed! (%s) \n " , nt_errstr ( nt_status ) ) ) ;
2001-12-31 16:00:59 +03:00
} else {
DEBUG ( 5 , ( " rpc command function succedded \n " ) ) ;
}
2004-02-08 13:59:09 +03:00
if ( ! ( conn_flags & NET_FLAGS_NO_PIPE ) ) {
2005-09-30 21:13:37 +04:00
if ( pipe_hnd ) {
cli_rpc_pipe_close ( pipe_hnd ) ;
}
2004-02-08 13:59:09 +03:00
}
2002-08-17 18:45:04 +04:00
/* close the connection only if it was opened here */
2005-09-30 21:13:37 +04:00
if ( ! cli_arg ) {
2002-08-17 18:45:04 +04:00
cli_shutdown ( cli ) ;
2005-09-30 21:13:37 +04:00
}
2002-08-17 18:45:04 +04:00
2001-12-05 03:26:36 +03:00
talloc_destroy ( mem_ctx ) ;
return ( ! NT_STATUS_IS_OK ( nt_status ) ) ;
}
2001-12-30 13:54:58 +03:00
/**
* Force a change of the trust acccount password .
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2001-12-30 13:54:58 +03:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2001-12-05 03:26:36 +03:00
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_changetrustpw_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2001-12-05 14:00:26 +03:00
2005-09-30 21:13:37 +04:00
return trust_pw_find_change_and_store_it ( pipe_hnd , mem_ctx , opt_target_workgroup ) ;
2001-12-05 14:00:26 +03:00
}
2001-12-30 13:54:58 +03:00
/**
* Force a change of the trust acccount password .
*
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
2003-04-15 02:27:09 +04:00
int net_rpc_changetrustpw ( int argc , const char * * argv )
2001-12-05 14:00:26 +03:00
{
2004-02-08 13:59:09 +03:00
return run_rpc_command ( NULL , PI_NETLOGON , NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC ,
rpc_changetrustpw_internals ,
2001-12-05 14:00:26 +03:00
argc , argv ) ;
}
2001-12-30 13:54:58 +03:00
/**
* Join a domain , the old way .
*
* This uses ' machinename ' as the inital password , and changes it .
*
2003-04-14 08:00:15 +04:00
* The password should be created with ' server manager ' or equiv first .
2001-12-30 13:54:58 +03:00
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2001-12-30 13:54:58 +03:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_oldjoin_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2001-12-05 14:00:26 +03:00
fstring trust_passwd ;
unsigned char orig_trust_passwd_hash [ 16 ] ;
2002-09-25 19:19:00 +04:00
NTSTATUS result ;
2003-05-01 06:51:49 +04:00
uint32 sec_channel_type ;
2001-12-05 14:00:26 +03:00
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_NETLOGON , & result ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
" error was %s \n " ,
cli - > desthost ,
nt_errstr ( result ) ) ) ;
return result ;
}
2003-05-01 06:51:49 +04:00
/*
check what type of join - if the user want ' s to join as
a BDC , the server must agree that we are a BDC .
*/
if ( argc > = 0 ) {
sec_channel_type = get_sec_channel_type ( argv [ 0 ] ) ;
} else {
sec_channel_type = get_sec_channel_type ( NULL ) ;
}
2002-11-13 02:20:50 +03:00
fstrcpy ( trust_passwd , global_myname ( ) ) ;
2003-07-03 23:11:31 +04:00
strlower_m ( trust_passwd ) ;
2002-07-15 14:35:28 +04:00
/*
* Machine names can be 15 characters , but the max length on
* a password is 14. - - jerry
*/
trust_passwd [ 14 ] = ' \0 ' ;
2002-08-17 18:45:04 +04:00
E_md4hash ( trust_passwd , orig_trust_passwd_hash ) ;
2001-12-05 14:00:26 +03:00
2005-09-30 21:13:37 +04:00
result = trust_pw_change_and_store_it ( pipe_hnd , mem_ctx , opt_target_workgroup ,
2003-04-21 18:09:03 +04:00
orig_trust_passwd_hash ,
2003-05-01 06:51:49 +04:00
sec_channel_type ) ;
2002-09-25 19:19:00 +04:00
if ( NT_STATUS_IS_OK ( result ) )
2003-04-21 18:09:03 +04:00
printf ( " Joined domain %s. \n " , opt_target_workgroup ) ;
if ( ! secrets_store_domain_sid ( opt_target_workgroup , domain_sid ) ) {
DEBUG ( 0 , ( " error storing domain sid for %s \n " , opt_target_workgroup ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
}
2002-09-25 19:19:00 +04:00
return result ;
2001-12-05 14:00:26 +03:00
}
2003-04-21 18:09:03 +04:00
/**
* Join a domain , the old way .
*
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
2004-01-16 18:07:28 +03:00
static int net_rpc_perform_oldjoin ( int argc , const char * * argv )
2003-04-21 18:09:03 +04:00
{
return run_rpc_command ( NULL , PI_NETLOGON ,
2005-09-30 21:13:37 +04:00
NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC ,
2003-05-01 06:51:49 +04:00
rpc_oldjoin_internals ,
2001-12-05 14:00:26 +03:00
argc , argv ) ;
}
2004-01-16 18:07:28 +03:00
/**
* Join a domain , the old way . This function exists to allow
* the message to be displayed when oldjoin was explicitly
* requested , but not when it was implied by " net rpc join "
*
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int net_rpc_oldjoin ( int argc , const char * * argv )
{
int rc = net_rpc_perform_oldjoin ( argc , argv ) ;
if ( rc ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Failed to join domain \n " ) ;
2004-01-16 18:07:28 +03:00
}
2004-01-21 17:48:02 +03:00
return rc ;
2004-01-16 18:07:28 +03:00
}
2001-12-30 13:54:58 +03:00
/**
* Basic usage function for ' net rpc join '
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2001-12-05 14:00:26 +03:00
static int rpc_join_usage ( int argc , const char * * argv )
{
2003-04-21 18:09:03 +04:00
d_printf ( " net rpc join -U <username>[%%password] <type>[options] \n " \
2002-03-16 01:09:18 +03:00
" \t to join a domain with admin username & password \n " \
2003-04-21 18:09:03 +04:00
" \t \t password will be prompted if needed and none is specified \n " \
" \t <type> can be (default MEMBER) \n " \
" \t \t BDC - Join as a BDC \n " \
" \t \t PDC - Join as a PDC \n " \
" \t \t MEMBER - Join as a MEMBER server \n " ) ;
2002-03-16 01:09:18 +03:00
net_common_flags_usage ( argc , argv ) ;
2001-12-05 14:00:26 +03:00
return - 1 ;
}
2001-12-30 13:54:58 +03:00
/**
* ' net rpc join ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
2008-02-08 15:48:23 +03:00
* Main ' net_rpc_join ( ) ' ( where the admin username / password is used ) is
2001-12-30 13:54:58 +03:00
* in net_rpc_join . c
2003-05-01 06:51:49 +04:00
* Try to just change the password , but if that doesn ' t work , use / prompt
* for a username / password .
2001-12-30 13:54:58 +03:00
* */
2002-03-16 01:09:18 +03:00
int net_rpc_join ( int argc , const char * * argv )
2001-12-05 14:00:26 +03:00
{
2006-04-24 14:09:45 +04:00
if ( lp_server_role ( ) = = ROLE_STANDALONE ) {
d_printf ( " cannot join as standalone machine \n " ) ;
2006-04-18 17:22:14 +04:00
return - 1 ;
}
2006-04-19 19:43:48 +04:00
if ( strlen ( global_myname ( ) ) > 15 ) {
2006-05-06 17:33:14 +04:00
d_printf ( " Our netbios name can be at most 15 chars long, "
2006-06-16 05:47:02 +04:00
" \" %s \" is %u chars long \n " ,
global_myname ( ) , ( unsigned int ) strlen ( global_myname ( ) ) ) ;
2006-04-19 19:43:48 +04:00
return - 1 ;
}
2004-01-16 18:07:28 +03:00
if ( ( net_rpc_perform_oldjoin ( argc , argv ) = = 0 ) )
2003-04-21 18:09:03 +04:00
return 0 ;
return net_rpc_join_newstyle ( argc , argv ) ;
2001-12-05 14:00:26 +03:00
}
2002-07-15 14:35:28 +04:00
/**
* display info about a rpc domain
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2003-04-14 08:00:15 +04:00
* argc , argv which are passed through .
2002-07-15 14:35:28 +04:00
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2006-02-04 01:19:41 +03:00
NTSTATUS rpc_info_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-05 17:55:11 +03:00
union samr_DomainInfo * info = NULL ;
2002-09-25 19:19:00 +04:00
fstring sid_str ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_str , domain_sid ) ;
2002-07-15 14:35:28 +04:00
2008-02-04 21:43:07 +03:00
/* Get sam policy handle */
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-07-15 14:35:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-04-09 21:01:59 +04:00
d_fprintf ( stderr , " Could not connect to SAM: %s \n " , nt_errstr ( result ) ) ;
2002-07-15 14:35:28 +04:00
goto done ;
}
2008-02-01 13:12:05 +03:00
2002-07-15 14:35:28 +04:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-07-15 14:35:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-04-09 21:01:59 +04:00
d_fprintf ( stderr , " Could not open domain: %s \n " , nt_errstr ( result ) ) ;
2002-07-15 14:35:28 +04:00
goto done ;
}
2008-02-05 17:55:11 +03:00
result = rpccli_samr_QueryDomainInfo ( pipe_hnd , mem_ctx ,
& domain_pol ,
2 ,
& info ) ;
2002-07-15 14:35:28 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
2008-02-05 17:55:11 +03:00
d_printf ( " Domain Name: %s \n " , info - > info2 . domain_name . string ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " Domain SID: %s \n " , sid_str ) ;
2008-02-05 17:55:11 +03:00
d_printf ( " Sequence number: %llu \n " ,
( unsigned long long ) info - > info2 . sequence_num ) ;
d_printf ( " Num users: %u \n " , info - > info2 . num_users ) ;
d_printf ( " Num domain groups: %u \n " , info - > info2 . num_groups ) ;
d_printf ( " Num local groups: %u \n " , info - > info2 . num_aliases ) ;
2002-07-15 14:35:28 +04:00
}
done :
return result ;
}
/**
* ' net rpc info ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2005-09-30 21:13:37 +04:00
2002-07-15 14:35:28 +04:00
int net_rpc_info ( int argc , const char * * argv )
{
2006-04-09 21:01:59 +04:00
return run_rpc_command ( NULL , PI_SAMR , NET_FLAGS_PDC ,
2002-07-15 14:35:28 +04:00
rpc_info_internals ,
argc , argv ) ;
}
2002-09-25 19:19:00 +04:00
/**
* Fetch domain SID into the local secrets . tdb
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_getsid_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-09-25 19:19:00 +04:00
{
fstring sid_str ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_str , domain_sid ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " Storing SID %s for Domain %s in secrets.tdb \n " ,
2004-02-08 13:59:09 +03:00
sid_str , domain_name ) ;
2002-09-25 19:19:00 +04:00
2004-02-08 13:59:09 +03:00
if ( ! secrets_store_domain_sid ( domain_name , domain_sid ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " Can't store domain SID \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
}
/**
* ' net rpc getsid ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2005-09-30 21:13:37 +04:00
2002-09-25 19:19:00 +04:00
int net_rpc_getsid ( int argc , const char * * argv )
{
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC ,
2002-09-25 19:19:00 +04:00
rpc_getsid_internals ,
argc , argv ) ;
}
2002-07-15 14:35:28 +04:00
2001-12-30 13:54:58 +03:00
/****************************************************************************/
2002-04-05 05:36:28 +04:00
/**
* Basic usage function for ' net rpc user '
* @ param argc Standard main ( ) style argc .
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped .
* */
static int rpc_user_usage ( int argc , const char * * argv )
{
return net_help_user ( argc , argv ) ;
}
2001-12-30 13:54:58 +03:00
/**
* Add a new user to a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2001-12-30 13:54:58 +03:00
* argc , argv which are passes through .
*
2002-03-01 05:56:35 +03:00
* @ param domain_sid The domain sid acquired from the remote server
2001-12-30 13:54:58 +03:00
* @ param cli A cli_state connected to the server .
2002-03-01 05:56:35 +03:00
* @ param mem_ctx Talloc context , destoyed on completion of the function .
2001-12-30 13:54:58 +03:00
* @ param argc Standard main ( ) style argc
2002-04-05 05:36:28 +04:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-30 13:54:58 +03:00
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_user_add_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
2001-12-30 13:54:58 +03:00
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
const char * acct_name ;
2008-02-01 16:21:54 +03:00
struct lsa_String lsa_acct_name ;
2006-02-27 13:32:45 +03:00
uint32 acb_info ;
2008-01-24 00:54:02 +03:00
uint32 acct_flags , user_rid ;
2008-02-01 16:21:54 +03:00
uint32_t access_granted = 0 ;
2008-02-08 16:50:04 +03:00
struct samr_Ids user_rids , name_types ;
2001-12-30 13:54:58 +03:00
2006-06-19 13:54:00 +04:00
if ( argc < 1 ) {
2002-04-05 05:36:28 +04:00
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
2001-12-30 13:54:58 +03:00
return NT_STATUS_OK ;
}
acct_name = argv [ 0 ] ;
2008-02-01 16:21:54 +03:00
init_lsa_String ( & lsa_acct_name , acct_name ) ;
2001-12-30 13:54:58 +03:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2001-12-30 13:54:58 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2001-12-30 13:54:58 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Create domain user */
acb_info = ACB_NORMAL ;
2008-01-25 03:00:51 +03:00
acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
SEC_STD_WRITE_DAC | SEC_STD_DELETE |
SAMR_USER_ACCESS_SET_PASSWORD |
SAMR_USER_ACCESS_GET_ATTRIBUTES |
SAMR_USER_ACCESS_SET_ATTRIBUTES ;
2001-12-30 13:54:58 +03:00
2008-02-01 16:21:54 +03:00
result = rpccli_samr_CreateUser2 ( pipe_hnd , mem_ctx ,
& domain_pol ,
& lsa_acct_name ,
acb_info ,
acct_flags ,
& user_pol ,
& access_granted ,
& user_rid ) ;
2001-12-30 13:54:58 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2006-06-19 13:54:00 +04:00
if ( argc = = 2 ) {
2008-02-12 22:01:36 +03:00
union samr_UserInfo info ;
2006-06-19 13:54:00 +04:00
uchar pwbuf [ 516 ] ;
2008-02-08 16:50:04 +03:00
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& user_rids ,
& name_types ) ;
2006-06-19 13:54:00 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
user_rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2006-06-19 13:54:00 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Set password on account */
encode_pw_buffer ( pwbuf , argv [ 1 ] , STR_UNICODE ) ;
2008-02-12 22:01:36 +03:00
init_samr_user_info24 ( & info . info24 , pwbuf , 24 ) ;
2006-06-19 13:54:00 +04:00
2008-02-12 22:01:36 +03:00
SamOEMhashBlob ( info . info24 . password . data , 516 ,
& cli - > user_session_key ) ;
2006-06-19 13:54:00 +04:00
2008-02-12 22:01:36 +03:00
result = rpccli_samr_SetUserInfo2 ( pipe_hnd , mem_ctx ,
& user_pol ,
24 ,
& info ) ;
2006-06-19 13:54:00 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_fprintf ( stderr , " Failed to set password for user %s - %s \n " ,
acct_name , nt_errstr ( result ) ) ;
2008-02-01 03:26:36 +03:00
result = rpccli_samr_DeleteUser ( pipe_hnd , mem_ctx ,
& user_pol ) ;
2006-06-19 13:54:00 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_fprintf ( stderr , " Failed to delete user %s - %s \n " ,
acct_name , nt_errstr ( result ) ) ;
return result ;
}
}
}
2001-12-30 13:54:58 +03:00
done :
2002-03-15 12:23:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2007-12-27 16:08:40 +03:00
d_fprintf ( stderr , " Failed to add user '%s' with %s. \n " ,
acct_name , nt_errstr ( result ) ) ;
2002-03-15 12:23:24 +03:00
} else {
2007-12-27 16:08:40 +03:00
d_printf ( " Added user '%s'. \n " , acct_name ) ;
2002-03-15 12:23:24 +03:00
}
2001-12-30 13:54:58 +03:00
return result ;
}
/**
* Add a new user to a remote RPC server
*
* @ param argc Standard main ( ) style argc
2002-04-05 05:36:28 +04:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-30 13:54:58 +03:00
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
2001-12-05 03:26:36 +03:00
static int rpc_user_add ( int argc , const char * * argv )
{
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_user_add_internals ,
2001-12-05 03:26:36 +03:00
argc , argv ) ;
}
2001-12-30 13:54:58 +03:00
/**
2002-04-05 05:36:28 +04:00
* Delete a user from a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-04-05 05:36:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
2001-12-30 13:54:58 +03:00
* @ param argc Standard main ( ) style argc
2002-04-05 05:36:28 +04:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-30 13:54:58 +03:00
* stripped
2002-04-05 05:36:28 +04:00
*
* @ return Normal NTSTATUS return .
2001-12-30 13:54:58 +03:00
* */
2002-04-05 05:36:28 +04:00
static NTSTATUS rpc_user_del_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2001-12-05 03:26:36 +03:00
{
2002-04-05 05:36:28 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
POLICY_HND connect_pol , domain_pol , user_pol ;
2007-12-27 16:08:40 +03:00
const char * acct_name ;
2002-04-05 05:36:28 +04:00
if ( argc < 1 ) {
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
2007-12-27 16:08:40 +03:00
acct_name = argv [ 0 ] ;
2002-04-05 05:36:28 +04:00
/* Get sam policy and domain handles */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get handle on user */
{
2008-02-08 16:50:04 +03:00
struct samr_Ids user_rids , name_types ;
struct lsa_String lsa_acct_name ;
2002-04-05 05:36:28 +04:00
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , acct_name ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& user_rids ,
& name_types ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
user_rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
}
/* Delete user */
2008-02-01 03:26:36 +03:00
result = rpccli_samr_DeleteUser ( pipe_hnd , mem_ctx ,
& user_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2007-12-27 16:08:40 +03:00
done :
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2007-12-27 16:08:40 +03:00
d_fprintf ( stderr , " Failed to delete user '%s' with %s. \n " ,
acct_name , nt_errstr ( result ) ) ;
} else {
d_printf ( " Deleted user '%s'. \n " , acct_name ) ;
}
2002-04-05 05:36:28 +04:00
return result ;
2005-09-30 21:13:37 +04:00
}
2002-04-05 05:36:28 +04:00
2005-01-20 19:51:24 +03:00
/**
* Rename a user on a remote RPC server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_user_rename_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2005-01-20 19:51:24 +03:00
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 info_level = 7 ;
const char * old_name , * new_name ;
2008-02-08 16:50:04 +03:00
struct samr_Ids user_rids , name_types ;
struct lsa_String lsa_acct_name ;
2008-02-12 20:13:30 +03:00
union samr_UserInfo * info = NULL ;
2005-01-20 19:51:24 +03:00
if ( argc ! = 2 ) {
2005-06-16 13:36:53 +04:00
d_printf ( " Old and new username must be specified \n " ) ;
2005-01-20 19:51:24 +03:00
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
old_name = argv [ 0 ] ;
new_name = argv [ 1 ] ;
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , old_name ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& user_rids ,
& name_types ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Open domain user */
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
user_rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Query user info */
2008-02-12 20:13:30 +03:00
result = rpccli_samr_QueryUserInfo ( pipe_hnd , mem_ctx ,
& user_pol ,
info_level ,
& info ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-12 22:01:36 +03:00
init_samr_user_info7 ( & info - > info7 , new_name ) ;
2005-01-20 19:51:24 +03:00
/* Set new name */
2008-02-12 22:01:36 +03:00
result = rpccli_samr_SetUserInfo2 ( pipe_hnd , mem_ctx ,
& user_pol ,
info_level ,
info ) ;
2005-01-20 19:51:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
done :
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Failed to rename user from %s to %s - %s \n " , old_name , new_name ,
2005-01-20 19:51:24 +03:00
nt_errstr ( result ) ) ;
} else {
d_printf ( " Renamed user from %s to %s \n " , old_name , new_name ) ;
}
return result ;
}
/**
* Rename a user on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_user_rename ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_user_rename_internals ,
argc , argv ) ;
}
2002-04-05 05:36:28 +04:00
/**
* Delete a user from a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_user_delete ( int argc , const char * * argv )
{
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_user_del_internals ,
2002-04-05 05:36:28 +04:00
argc , argv ) ;
}
2004-02-07 06:54:39 +03:00
/**
* Set a password for a user on a remote RPC server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
static NTSTATUS rpc_user_password_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-07 06:54:39 +03:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
POLICY_HND connect_pol , domain_pol , user_pol ;
uchar pwbuf [ 516 ] ;
const char * user ;
const char * new_password ;
char * prompt = NULL ;
2008-02-12 22:01:36 +03:00
union samr_UserInfo info ;
2004-02-07 06:54:39 +03:00
if ( argc < 1 ) {
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
user = argv [ 0 ] ;
if ( argv [ 1 ] ) {
new_password = argv [ 1 ] ;
} else {
asprintf ( & prompt , " Enter new password for %s: " , user ) ;
new_password = getpass ( prompt ) ;
SAFE_FREE ( prompt ) ;
}
/* Get sam policy and domain handles */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-07 06:54:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-02-07 06:54:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get handle on user */
{
2008-02-08 16:50:04 +03:00
struct samr_Ids user_rids , name_types ;
struct lsa_String lsa_acct_name ;
2004-02-07 06:54:39 +03:00
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , user ) ;
2004-02-07 06:54:39 +03:00
2008-02-08 16:50:04 +03:00
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& user_rids ,
& name_types ) ;
2004-02-07 06:54:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
user_rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2004-02-07 06:54:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
}
/* Set password on account */
encode_pw_buffer ( pwbuf , new_password , STR_UNICODE ) ;
2008-02-12 22:01:36 +03:00
init_samr_user_info24 ( & info . info24 , pwbuf , 24 ) ;
2004-02-07 06:54:39 +03:00
2008-02-12 22:01:36 +03:00
SamOEMhashBlob ( info . info24 . password . data , 516 ,
& cli - > user_session_key ) ;
2004-02-07 06:54:39 +03:00
2008-02-12 22:01:36 +03:00
result = rpccli_samr_SetUserInfo2 ( pipe_hnd , mem_ctx ,
& user_pol ,
24 ,
& info ) ;
2004-02-07 06:54:39 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Display results */
done :
return result ;
}
/**
* Set a user ' s password on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_user_password ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_user_password_internals ,
argc , argv ) ;
}
2002-04-05 05:36:28 +04:00
/**
* List user ' s groups on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-04-05 05:36:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_user_info_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
2004-02-08 13:59:09 +03:00
struct cli_state * cli ,
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-04-05 05:36:28 +04:00
{
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
int i ;
2008-02-06 18:19:20 +03:00
struct samr_RidWithAttributeArray * rid_array = NULL ;
2008-02-08 14:05:29 +03:00
struct lsa_Strings names ;
struct samr_Ids types ;
2008-02-08 16:50:04 +03:00
uint32_t * lrids = NULL ;
struct samr_Ids rids , name_types ;
struct lsa_String lsa_acct_name ;
2002-04-05 05:36:28 +04:00
if ( argc < 1 ) {
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get handle on user */
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , argv [ 0 ] ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& name_types ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
2008-02-06 18:19:20 +03:00
result = rpccli_samr_GetGroupsForUser ( pipe_hnd , mem_ctx ,
& user_pol ,
& rid_array ) ;
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
/* Look up rids */
2002-04-05 05:36:28 +04:00
2008-02-08 16:50:04 +03:00
if ( rid_array - > count ) {
if ( ( lrids = TALLOC_ARRAY ( mem_ctx , uint32 , rid_array - > count ) ) = = NULL ) {
2006-06-19 23:07:39 +04:00
result = NT_STATUS_NO_MEMORY ;
goto done ;
}
2002-04-05 05:36:28 +04:00
2008-02-08 16:50:04 +03:00
for ( i = 0 ; i < rid_array - > count ; i + + )
lrids [ i ] = rid_array - > rids [ i ] . rid ;
2002-04-05 05:36:28 +04:00
2008-02-08 14:05:29 +03:00
result = rpccli_samr_LookupRids ( pipe_hnd , mem_ctx ,
& domain_pol ,
2008-02-08 16:50:04 +03:00
rid_array - > count ,
lrids ,
2008-02-08 14:05:29 +03:00
& names ,
& types ) ;
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
/* Display results */
2002-04-05 05:36:28 +04:00
2008-02-08 16:50:04 +03:00
for ( i = 0 ; i < names . count ; i + + )
2008-02-08 14:05:29 +03:00
printf ( " %s \n " , names . names [ i ] . string ) ;
2005-02-10 21:27:23 +03:00
}
2002-04-05 05:36:28 +04:00
done :
return result ;
}
/**
* List a user ' s groups from a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_user_info ( int argc , const char * * argv )
{
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_user_info_internals ,
2002-04-05 05:36:28 +04:00
argc , argv ) ;
}
/**
* List users on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-04-05 05:36:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_user_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-04-05 05:36:28 +04:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2003-01-29 23:15:35 +03:00
uint32 start_idx = 0 , num_entries , i , loop_count = 0 ;
2002-04-05 05:36:28 +04:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-04-05 05:36:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Query domain users */
if ( opt_long_list_entries )
d_printf ( " \n User name Comment " \
" \n ----------------------------- \n " ) ;
do {
2008-02-07 22:46:02 +03:00
const char * user = NULL ;
const char * desc = NULL ;
2003-01-29 23:15:35 +03:00
uint32 max_entries , max_size ;
2008-02-07 22:46:02 +03:00
uint32_t total_size , returned_size ;
union samr_DispInfo info ;
2003-01-29 23:15:35 +03:00
get_query_dispinfo_params (
loop_count , & max_entries , & max_size ) ;
2008-02-07 22:46:02 +03:00
result = rpccli_samr_QueryDisplayInfo ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
start_idx ,
max_entries ,
max_size ,
& total_size ,
& returned_size ,
& info ) ;
2003-01-29 23:15:35 +03:00
loop_count + + ;
2008-02-07 22:46:02 +03:00
start_idx + = info . info1 . count ;
num_entries = info . info1 . count ;
2003-01-29 23:15:35 +03:00
2002-04-05 05:36:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2008-02-07 22:46:02 +03:00
user = info . info1 . entries [ i ] . account_name . string ;
if ( opt_long_list_entries )
desc = info . info1 . entries [ i ] . description . string ;
2002-04-05 05:36:28 +04:00
if ( opt_long_list_entries )
2003-04-29 19:09:54 +04:00
printf ( " %-21.21s %s \n " , user , desc ) ;
2002-04-05 05:36:28 +04:00
else
2002-07-15 14:35:28 +04:00
printf ( " %s \n " , user ) ;
2002-04-05 05:36:28 +04:00
}
2003-05-08 02:56:02 +04:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-04-05 05:36:28 +04:00
done :
return result ;
2001-12-05 03:26:36 +03:00
}
2001-12-30 13:54:58 +03:00
/**
* ' net rpc user ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2002-04-05 05:36:28 +04:00
int net_rpc_user ( int argc , const char * * argv )
2001-12-05 03:26:36 +03:00
{
struct functable func [ ] = {
{ " add " , rpc_user_add } ,
2002-04-05 05:36:28 +04:00
{ " info " , rpc_user_info } ,
{ " delete " , rpc_user_delete } ,
2004-02-07 06:54:39 +03:00
{ " password " , rpc_user_password } ,
2005-01-20 19:51:24 +03:00
{ " rename " , rpc_user_rename } ,
2001-12-05 03:26:36 +03:00
{ NULL , NULL }
} ;
if ( argc = = 0 ) {
2005-06-16 13:36:53 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_user_list_internals ,
argc , argv ) ;
2001-12-05 03:26:36 +03:00
}
return net_run_function ( argc , argv , func , rpc_user_usage ) ;
}
2006-02-04 01:19:41 +03:00
static NTSTATUS rpc_sh_user_list ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_user_list_internals ( ctx - > domain_sid , ctx - > domain_name ,
ctx - > cli , pipe_hnd , mem_ctx ,
argc , argv ) ;
}
static NTSTATUS rpc_sh_user_info ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_user_info_internals ( ctx - > domain_sid , ctx - > domain_name ,
ctx - > cli , pipe_hnd , mem_ctx ,
argc , argv ) ;
}
static NTSTATUS rpc_sh_handle_user ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv ,
NTSTATUS ( * fn ) (
TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-13 16:10:10 +03:00
POLICY_HND * user_hnd ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv ) )
{
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
DOM_SID sid ;
uint32 rid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2006-02-04 01:19:41 +03:00
if ( argc = = 0 ) {
d_fprintf ( stderr , " usage: %s <username> \n " , ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
ZERO_STRUCT ( connect_pol ) ;
ZERO_STRUCT ( domain_pol ) ;
ZERO_STRUCT ( user_pol ) ;
result = net_rpc_lookup_name ( mem_ctx , pipe_hnd - > cli , argv [ 0 ] ,
NULL , NULL , & sid , & type ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_fprintf ( stderr , " Could not lookup %s: %s \n " , argv [ 0 ] ,
nt_errstr ( result ) ) ;
goto done ;
}
if ( type ! = SID_NAME_USER ) {
d_fprintf ( stderr , " %s is a %s, not a user \n " , argv [ 0 ] ,
sid_type_lookup ( type ) ) ;
result = NT_STATUS_NO_SUCH_USER ;
goto done ;
}
if ( ! sid_peek_check_rid ( ctx - > domain_sid , & sid , & rid ) ) {
d_fprintf ( stderr , " %s is not in our domain \n " , argv [ 0 ] ) ;
result = NT_STATUS_NO_SUCH_USER ;
goto done ;
}
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
ctx - > domain_sid ,
& domain_pol ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
rid ,
& user_pol ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = fn ( mem_ctx , ctx , pipe_hnd , & user_pol , argc - 1 , argv + 1 ) ;
done :
if ( is_valid_policy_hnd ( & user_pol ) ) {
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & user_pol ) ;
2006-02-04 01:19:41 +03:00
}
if ( is_valid_policy_hnd ( & domain_pol ) ) {
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & domain_pol ) ;
2006-02-04 01:19:41 +03:00
}
if ( is_valid_policy_hnd ( & connect_pol ) ) {
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2006-02-04 01:19:41 +03:00
}
return result ;
}
static NTSTATUS rpc_sh_user_show_internals ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-13 16:10:10 +03:00
POLICY_HND * user_hnd ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv )
{
NTSTATUS result ;
2008-02-12 20:13:30 +03:00
union samr_UserInfo * info = NULL ;
2006-02-04 01:19:41 +03:00
if ( argc ! = 0 ) {
d_fprintf ( stderr , " usage: %s show <username> \n " , ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2008-02-12 20:13:30 +03:00
result = rpccli_samr_QueryUserInfo ( pipe_hnd , mem_ctx ,
2008-02-13 16:10:10 +03:00
user_hnd ,
2008-02-12 20:13:30 +03:00
21 ,
& info ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
2008-02-12 20:13:30 +03:00
d_printf ( " user rid: %d, group rid: %d \n " ,
info - > info21 . rid ,
info - > info21 . primary_gid ) ;
2006-02-04 01:19:41 +03:00
return result ;
}
static NTSTATUS rpc_sh_user_show ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_sh_handle_user ( mem_ctx , ctx , pipe_hnd , argc , argv ,
rpc_sh_user_show_internals ) ;
}
# define FETCHSTR(name, rec) \
do { if ( strequal ( ctx - > thiscmd , name ) ) { \
2008-02-12 20:13:30 +03:00
oldval = talloc_strdup ( mem_ctx , info - > info21 . rec . string ) ; } \
2006-02-04 01:19:41 +03:00
} while ( 0 ) ;
# define SETSTR(name, rec, flag) \
do { if ( strequal ( ctx - > thiscmd , name ) ) { \
2008-02-12 02:51:51 +03:00
init_lsa_String ( & ( info - > info21 . rec ) , argv [ 0 ] ) ; \
info - > info21 . fields_present | = SAMR_FIELD_ # # flag ; } \
2006-02-04 01:19:41 +03:00
} while ( 0 ) ;
static NTSTATUS rpc_sh_user_str_edit_internals ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-13 16:10:10 +03:00
POLICY_HND * user_hnd ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv )
{
NTSTATUS result ;
const char * username ;
const char * oldval = " " ;
2008-02-12 20:13:30 +03:00
union samr_UserInfo * info = NULL ;
2006-02-04 01:19:41 +03:00
if ( argc > 1 ) {
d_fprintf ( stderr , " usage: %s <username> [new value|NULL] \n " ,
ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2008-02-12 20:13:30 +03:00
result = rpccli_samr_QueryUserInfo ( pipe_hnd , mem_ctx ,
2008-02-13 16:10:10 +03:00
user_hnd ,
2008-02-12 20:13:30 +03:00
21 ,
& info ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
2008-02-12 20:13:30 +03:00
username = talloc_strdup ( mem_ctx , info - > info21 . account_name . string ) ;
2006-02-04 01:19:41 +03:00
FETCHSTR ( " fullname " , full_name ) ;
2008-02-12 20:13:30 +03:00
FETCHSTR ( " homedir " , home_directory ) ;
FETCHSTR ( " homedrive " , home_drive ) ;
2006-02-04 01:19:41 +03:00
FETCHSTR ( " logonscript " , logon_script ) ;
FETCHSTR ( " profilepath " , profile_path ) ;
2008-02-12 20:13:30 +03:00
FETCHSTR ( " description " , description ) ;
2006-02-04 01:19:41 +03:00
if ( argc = = 0 ) {
d_printf ( " %s's %s: [%s] \n " , username , ctx - > thiscmd , oldval ) ;
goto done ;
}
if ( strcmp ( argv [ 0 ] , " NULL " ) = = 0 ) {
argv [ 0 ] = " " ;
}
2008-02-12 02:51:51 +03:00
ZERO_STRUCT ( info - > info21 ) ;
2006-02-04 01:19:41 +03:00
SETSTR ( " fullname " , full_name , FULL_NAME ) ;
2008-02-12 02:51:51 +03:00
SETSTR ( " homedir " , home_directory , HOME_DIRECTORY ) ;
SETSTR ( " homedrive " , home_drive , HOME_DRIVE ) ;
2006-02-04 01:19:41 +03:00
SETSTR ( " logonscript " , logon_script , LOGON_SCRIPT ) ;
2008-02-12 02:07:41 +03:00
SETSTR ( " profilepath " , profile_path , PROFILE_PATH ) ;
2008-02-12 02:51:51 +03:00
SETSTR ( " description " , description , DESCRIPTION ) ;
2006-02-04 01:19:41 +03:00
2008-02-12 02:51:51 +03:00
result = rpccli_samr_SetUserInfo ( pipe_hnd , mem_ctx ,
2008-02-13 16:10:10 +03:00
user_hnd ,
2008-02-12 02:51:51 +03:00
21 ,
info ) ;
2006-02-04 01:19:41 +03:00
d_printf ( " Set %s's %s from [%s] to [%s] \n " , username ,
ctx - > thiscmd , oldval , argv [ 0 ] ) ;
done :
return result ;
}
# define HANDLEFLG(name, rec) \
do { if ( strequal ( ctx - > thiscmd , name ) ) { \
oldval = ( oldflags & ACB_ # # rec ) ? " yes " : " no " ; \
if ( newval ) { \
newflags = oldflags | ACB_ # # rec ; \
} else { \
newflags = oldflags & ~ ACB_ # # rec ; \
} } } while ( 0 ) ;
static NTSTATUS rpc_sh_user_str_edit ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_sh_handle_user ( mem_ctx , ctx , pipe_hnd , argc , argv ,
rpc_sh_user_str_edit_internals ) ;
}
static NTSTATUS rpc_sh_user_flag_edit_internals ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-13 16:10:10 +03:00
POLICY_HND * user_hnd ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv )
{
NTSTATUS result ;
const char * username ;
const char * oldval = " unknown " ;
uint32 oldflags , newflags ;
2007-10-19 04:40:25 +04:00
bool newval ;
2008-02-12 20:13:30 +03:00
union samr_UserInfo * info = NULL ;
2006-02-04 01:19:41 +03:00
if ( ( argc > 1 ) | |
( ( argc = = 1 ) & & ! strequal ( argv [ 0 ] , " yes " ) & &
! strequal ( argv [ 0 ] , " no " ) ) ) {
d_fprintf ( stderr , " usage: %s <username> [yes|no] \n " ,
ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
newval = strequal ( argv [ 0 ] , " yes " ) ;
2008-02-12 20:13:30 +03:00
result = rpccli_samr_QueryUserInfo ( pipe_hnd , mem_ctx ,
2008-02-13 16:10:10 +03:00
user_hnd ,
2008-02-12 20:13:30 +03:00
21 ,
& info ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
2008-02-12 20:13:30 +03:00
username = talloc_strdup ( mem_ctx , info - > info21 . account_name . string ) ;
oldflags = info - > info21 . acct_flags ;
newflags = info - > info21 . acct_flags ;
2006-02-04 01:19:41 +03:00
HANDLEFLG ( " disabled " , DISABLED ) ;
HANDLEFLG ( " pwnotreq " , PWNOTREQ ) ;
HANDLEFLG ( " autolock " , AUTOLOCK ) ;
HANDLEFLG ( " pwnoexp " , PWNOEXP ) ;
if ( argc = = 0 ) {
d_printf ( " %s's %s flag: %s \n " , username , ctx - > thiscmd , oldval ) ;
goto done ;
}
2008-02-12 02:51:51 +03:00
ZERO_STRUCT ( info - > info21 ) ;
2006-02-04 01:19:41 +03:00
2008-02-12 02:51:51 +03:00
info - > info21 . acct_flags = newflags ;
info - > info21 . fields_present = SAMR_FIELD_ACCT_FLAGS ;
2006-02-04 01:19:41 +03:00
2008-02-12 02:51:51 +03:00
result = rpccli_samr_SetUserInfo ( pipe_hnd , mem_ctx ,
2008-02-13 16:10:10 +03:00
user_hnd ,
2008-02-12 02:51:51 +03:00
21 ,
info ) ;
2006-02-04 01:19:41 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Set %s's %s flag from [%s] to [%s] \n " , username ,
ctx - > thiscmd , oldval , argv [ 0 ] ) ;
}
done :
return result ;
}
static NTSTATUS rpc_sh_user_flag_edit ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_sh_handle_user ( mem_ctx , ctx , pipe_hnd , argc , argv ,
rpc_sh_user_flag_edit_internals ) ;
}
struct rpc_sh_cmd * net_rpc_user_edit_cmds ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx )
{
static struct rpc_sh_cmd cmds [ ] = {
{ " fullname " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's full name " } ,
{ " homedir " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's home directory " } ,
{ " homedrive " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's home drive " } ,
{ " logonscript " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's logon script " } ,
{ " profilepath " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's profile path " } ,
{ " description " , NULL , PI_SAMR , rpc_sh_user_str_edit ,
" Show/Set a user's description " } ,
{ " disabled " , NULL , PI_SAMR , rpc_sh_user_flag_edit ,
" Show/Set whether a user is disabled " } ,
{ " autolock " , NULL , PI_SAMR , rpc_sh_user_flag_edit ,
" Show/Set whether a user locked out " } ,
{ " pwnotreq " , NULL , PI_SAMR , rpc_sh_user_flag_edit ,
" Show/Set whether a user does not need a password " } ,
{ " pwnoexp " , NULL , PI_SAMR , rpc_sh_user_flag_edit ,
" Show/Set whether a user's password does not expire " } ,
{ NULL , NULL , 0 , NULL , NULL }
} ;
return cmds ;
}
struct rpc_sh_cmd * net_rpc_user_cmds ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx )
{
static struct rpc_sh_cmd cmds [ ] = {
{ " list " , NULL , PI_SAMR , rpc_sh_user_list ,
" List available users " } ,
{ " info " , NULL , PI_SAMR , rpc_sh_user_info ,
" List the domain groups a user is member of " } ,
{ " show " , NULL , PI_SAMR , rpc_sh_user_show ,
" Show info about a user " } ,
{ " edit " , net_rpc_user_edit_cmds , 0 , NULL ,
" Show/Modify a user's fields " } ,
{ NULL , NULL , 0 , NULL , NULL }
} ;
return cmds ;
2006-05-17 15:14:26 +04:00
}
2006-02-04 01:19:41 +03:00
2001-12-31 16:00:59 +03:00
/****************************************************************************/
2002-07-15 14:35:28 +04:00
/**
* Basic usage function for ' net rpc group '
* @ param argc Standard main ( ) style argc .
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped .
* */
2001-12-31 16:00:59 +03:00
2002-07-15 14:35:28 +04:00
static int rpc_group_usage ( int argc , const char * * argv )
{
return net_help_group ( argc , argv ) ;
}
2001-12-31 16:00:59 +03:00
2004-04-19 00:22:31 +04:00
/**
* Delete group on a remote RPC server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
static NTSTATUS rpc_group_delete_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-04-19 00:22:31 +04:00
{
POLICY_HND connect_pol , domain_pol , group_pol , user_pol ;
2007-10-19 04:40:25 +04:00
bool group_is_primary = False ;
2004-04-19 00:22:31 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-08 16:50:04 +03:00
uint32_t group_rid ;
2008-02-05 12:58:37 +03:00
struct samr_RidTypeArray * rids = NULL ;
2004-04-19 00:22:31 +04:00
/* char **names; */
int i ;
/* DOM_GID *user_gids; */
2008-02-08 16:50:04 +03:00
struct samr_Ids group_rids , name_types ;
struct lsa_String lsa_acct_name ;
2008-02-12 20:13:30 +03:00
union samr_UserInfo * info = NULL ;
2008-02-08 16:50:04 +03:00
2004-04-19 00:22:31 +04:00
if ( argc < 1 ) {
d_printf ( " specify group \n " ) ;
rpc_group_usage ( argc , argv ) ;
return NT_STATUS_OK ; /* ok? */
}
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2008-02-04 21:43:07 +03:00
d_fprintf ( stderr , " Request samr_Connect2 failed \n " ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Request open_domain failed \n " ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , argv [ 0 ] ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& group_rids ,
& name_types ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Lookup of '%s' failed \n " , argv [ 0 ] ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-08 16:50:04 +03:00
switch ( name_types . ids [ 0 ] )
2004-04-19 00:22:31 +04:00
{
case SID_NAME_DOM_GRP :
2008-02-01 13:24:01 +03:00
result = rpccli_samr_OpenGroup ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
group_rids . ids [ 0 ] ,
2008-02-01 13:24:01 +03:00
& group_pol ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Request open_group failed " ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-08 16:50:04 +03:00
group_rid = group_rids . ids [ 0 ] ;
2008-02-05 12:58:37 +03:00
result = rpccli_samr_QueryGroupMember ( pipe_hnd , mem_ctx ,
& group_pol ,
& rids ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unable to query group members of %s " , argv [ 0 ] ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
if ( opt_verbose ) {
d_printf ( " Domain Group %s (rid: %d) has %d members \n " ,
2008-02-05 12:58:37 +03:00
argv [ 0 ] , group_rid , rids - > count ) ;
2004-04-19 00:22:31 +04:00
}
/* Check if group is anyone's primary group */
2008-02-05 12:58:37 +03:00
for ( i = 0 ; i < rids - > count ; i + + )
2004-04-19 00:22:31 +04:00
{
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-05 12:58:37 +03:00
rids - > rids [ i ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2008-02-05 12:58:37 +03:00
d_fprintf ( stderr , " Unable to open group member %d \n " ,
rids - > rids [ i ] ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-12 20:13:30 +03:00
result = rpccli_samr_QueryUserInfo ( pipe_hnd , mem_ctx ,
& user_pol ,
21 ,
& info ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2008-02-05 12:58:37 +03:00
d_fprintf ( stderr , " Unable to lookup userinfo for group member %d \n " ,
rids - > rids [ i ] ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-12 20:13:30 +03:00
if ( info - > info21 . primary_gid = = group_rid ) {
if ( opt_verbose ) {
d_printf ( " Group is primary group of %s \n " ,
info - > info21 . account_name . string ) ;
}
2004-04-19 00:22:31 +04:00
group_is_primary = True ;
}
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & user_pol ) ;
2004-04-19 00:22:31 +04:00
}
if ( group_is_primary ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unable to delete group because some "
" of it's members have it as primary group \n " ) ;
2004-04-19 00:22:31 +04:00
result = NT_STATUS_MEMBERS_PRIMARY_GROUP ;
goto done ;
}
/* remove all group members */
2008-02-05 12:58:37 +03:00
for ( i = 0 ; i < rids - > count ; i + + )
2004-04-19 00:22:31 +04:00
{
if ( opt_verbose )
2008-02-05 12:58:37 +03:00
d_printf ( " Remove group member %d... " ,
rids - > rids [ i ] ) ;
2008-02-04 20:13:07 +03:00
result = rpccli_samr_DeleteGroupMember ( pipe_hnd , mem_ctx ,
& group_pol ,
2008-02-05 12:58:37 +03:00
rids - > rids [ i ] ) ;
2004-04-19 00:22:31 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
if ( opt_verbose )
d_printf ( " ok \n " ) ;
} else {
if ( opt_verbose )
d_printf ( " failed \n " ) ;
goto done ;
}
}
2008-02-01 03:17:22 +03:00
result = rpccli_samr_DeleteDomainGroup ( pipe_hnd , mem_ctx ,
& group_pol ) ;
2004-04-19 00:22:31 +04:00
break ;
/* removing a local group is easier... */
case SID_NAME_ALIAS :
2008-02-01 13:38:29 +03:00
result = rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
group_rids . ids [ 0 ] ,
2008-02-01 13:38:29 +03:00
& group_pol ) ;
2004-04-19 00:22:31 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Request open_alias failed \n " ) ;
2004-04-19 00:22:31 +04:00
goto done ;
}
2008-02-01 03:22:22 +03:00
result = rpccli_samr_DeleteDomAlias ( pipe_hnd , mem_ctx ,
& group_pol ) ;
2004-04-19 00:22:31 +04:00
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " %s is of type %s. This command is only for deleting local or global groups \n " ,
2008-02-08 16:50:04 +03:00
argv [ 0 ] , sid_type_lookup ( name_types . ids [ 0 ] ) ) ;
2004-04-19 00:22:31 +04:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( NT_STATUS_IS_OK ( result ) ) {
if ( opt_verbose )
2008-02-08 16:50:04 +03:00
d_printf ( " Deleted %s '%s' \n " , sid_type_lookup ( name_types . ids [ 0 ] ) , argv [ 0 ] ) ;
2004-04-19 00:22:31 +04:00
} else {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Deleting of %s failed: %s \n " , argv [ 0 ] ,
2004-04-19 00:22:31 +04:00
get_friendly_nt_error_msg ( result ) ) ;
}
done :
return result ;
}
static int rpc_group_delete ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_group_delete_internals ,
argc , argv ) ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_add_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-24 21:00:41 +03:00
{
POLICY_HND connect_pol , domain_pol , group_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-06 15:06:31 +03:00
union samr_GroupInfo group_info ;
2008-02-01 15:42:28 +03:00
struct lsa_String grp_name ;
uint32_t rid = 0 ;
2004-02-24 21:00:41 +03:00
if ( argc ! = 1 ) {
d_printf ( " Group name must be specified \n " ) ;
rpc_group_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
2008-02-01 15:42:28 +03:00
init_lsa_String ( & grp_name , argv [ 0 ] ) ;
2004-02-24 21:00:41 +03:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-24 21:00:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-02-24 21:00:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Create the group */
2008-02-01 15:42:28 +03:00
result = rpccli_samr_CreateDomainGroup ( pipe_hnd , mem_ctx ,
& domain_pol ,
& grp_name ,
MAXIMUM_ALLOWED_ACCESS ,
& group_pol ,
& rid ) ;
2004-02-24 21:00:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
if ( strlen ( opt_comment ) = = 0 ) goto done ;
/* We've got a comment to set */
2008-02-06 15:06:31 +03:00
init_lsa_String ( & group_info . description , opt_comment ) ;
2004-02-24 21:00:41 +03:00
2008-02-06 15:06:31 +03:00
result = rpccli_samr_SetGroupInfo ( pipe_hnd , mem_ctx ,
& group_pol ,
4 ,
& group_info ) ;
2004-02-24 21:00:41 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
done :
if ( NT_STATUS_IS_OK ( result ) )
DEBUG ( 5 , ( " add group succeeded \n " ) ) ;
else
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " add group failed: %s \n " , nt_errstr ( result ) ) ;
2004-02-24 21:00:41 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_alias_add_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-28 21:41:16 +03:00
{
POLICY_HND connect_pol , domain_pol , alias_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-06 15:16:04 +03:00
union samr_AliasInfo alias_info ;
2008-02-01 15:48:19 +03:00
struct lsa_String alias_name ;
uint32_t rid = 0 ;
2004-02-28 21:41:16 +03:00
if ( argc ! = 1 ) {
2005-01-25 04:19:02 +03:00
d_printf ( " Alias name must be specified \n " ) ;
2004-02-28 21:41:16 +03:00
rpc_group_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
2008-02-01 15:48:19 +03:00
init_lsa_String ( & alias_name , argv [ 0 ] ) ;
2004-02-28 21:41:16 +03:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Create the group */
2008-02-01 15:48:19 +03:00
result = rpccli_samr_CreateDomAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
& alias_name ,
MAXIMUM_ALLOWED_ACCESS ,
& alias_pol ,
& rid ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
if ( strlen ( opt_comment ) = = 0 ) goto done ;
/* We've got a comment to set */
2008-02-06 15:16:04 +03:00
init_lsa_String ( & alias_info . description , opt_comment ) ;
result = rpccli_samr_SetAliasInfo ( pipe_hnd , mem_ctx ,
& alias_pol ,
3 ,
& alias_info ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
done :
if ( NT_STATUS_IS_OK ( result ) )
2005-01-25 04:19:02 +03:00
DEBUG ( 5 , ( " add alias succeeded \n " ) ) ;
2004-02-28 21:41:16 +03:00
else
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " add alias failed: %s \n " , nt_errstr ( result ) ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2004-02-24 21:00:41 +03:00
static int rpc_group_add ( int argc , const char * * argv )
{
2004-02-28 21:41:16 +03:00
if ( opt_localgroup )
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_alias_add_internals ,
argc , argv ) ;
2004-02-24 21:00:41 +03:00
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_add_internals ,
argc , argv ) ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS get_sid_from_name ( struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
const char * name ,
DOM_SID * sid ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType * type )
2004-02-28 21:41:16 +03:00
{
DOM_SID * sids = NULL ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types = NULL ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd ;
2004-02-28 21:41:16 +03:00
POLICY_HND lsa_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & result ) ;
if ( ! pipe_hnd ) {
goto done ;
2004-02-28 21:41:16 +03:00
}
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_open_policy ( pipe_hnd , mem_ctx , False ,
2004-02-28 21:41:16 +03:00
SEC_RIGHTS_MAXIMUM_ALLOWED , & lsa_pol ) ;
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
goto done ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_lookup_names ( pipe_hnd , mem_ctx , & lsa_pol , 1 ,
2007-06-27 15:42:17 +04:00
& name , NULL , 1 , & sids , & types ) ;
2004-02-28 21:41:16 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
sid_copy ( sid , & sids [ 0 ] ) ;
* type = types [ 0 ] ;
}
2006-09-21 02:49:02 +04:00
rpccli_lsa_Close ( pipe_hnd , mem_ctx , & lsa_pol ) ;
2004-02-28 21:41:16 +03:00
done :
2005-09-30 21:13:37 +04:00
if ( pipe_hnd ) {
cli_rpc_pipe_close ( pipe_hnd ) ;
2004-02-28 21:41:16 +03:00
}
if ( ! NT_STATUS_IS_OK ( result ) & & ( StrnCaseCmp ( name , " S- " , 2 ) = = 0 ) ) {
/* Try as S-1-5-whatever */
DOM_SID tmp_sid ;
if ( string_to_sid ( & tmp_sid , name ) ) {
sid_copy ( sid , & tmp_sid ) ;
* type = SID_NAME_UNKNOWN ;
result = NT_STATUS_OK ;
}
}
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_add_groupmem ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * group_sid ,
const char * member )
2004-02-28 21:41:16 +03:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 group_rid ;
POLICY_HND group_pol ;
2008-02-08 16:50:04 +03:00
struct samr_Ids rids , rid_types ;
struct lsa_String lsa_acct_name ;
2004-02-28 21:41:16 +03:00
DOM_SID sid ;
sid_copy ( & sid , group_sid ) ;
2005-09-30 21:13:37 +04:00
if ( ! sid_split_rid ( & sid , & group_rid ) ) {
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2008-02-04 21:43:07 +03:00
/* Get sam policy handle */
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
return result ;
2005-09-30 21:13:37 +04:00
}
2008-02-01 13:12:05 +03:00
2004-02-28 21:41:16 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid ,
& domain_pol ) ;
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
return result ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , member ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& rid_types ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup up group member %s \n " , member ) ;
2004-02-28 21:41:16 +03:00
goto done ;
}
2008-02-01 13:24:01 +03:00
result = rpccli_samr_OpenGroup ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rid ,
& group_pol ) ;
2004-02-28 21:41:16 +03:00
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
goto done ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2008-02-04 20:45:07 +03:00
result = rpccli_samr_AddGroupMember ( pipe_hnd , mem_ctx ,
& group_pol ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ,
2008-02-04 20:45:07 +03:00
0x0005 ) ; /* unknown flags */
2004-02-28 21:41:16 +03:00
done :
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_add_aliasmem ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * alias_sid ,
const char * member )
2004-02-28 21:41:16 +03:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 alias_rid ;
POLICY_HND alias_pol ;
DOM_SID member_sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType member_type ;
2004-02-28 21:41:16 +03:00
DOM_SID sid ;
sid_copy ( & sid , alias_sid ) ;
2005-09-30 21:13:37 +04:00
if ( ! sid_split_rid ( & sid , & alias_rid ) ) {
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2005-09-30 21:13:37 +04:00
result = get_sid_from_name ( pipe_hnd - > cli , mem_ctx , member ,
2004-02-28 21:41:16 +03:00
& member_sid , & member_type ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup up group member %s \n " , member ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2008-02-04 21:43:07 +03:00
/* Get sam policy handle */
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
2004-02-28 21:41:16 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid ,
& domain_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:38:29 +03:00
result = rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
alias_rid ,
& alias_pol ) ;
2004-02-28 21:41:16 +03:00
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
return result ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
2008-02-05 01:42:05 +03:00
result = rpccli_samr_AddAliasMember ( pipe_hnd , mem_ctx ,
& alias_pol ,
& member_sid ) ;
2004-02-28 21:41:16 +03:00
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-02-28 21:41:16 +03:00
return result ;
2005-09-30 21:13:37 +04:00
}
2004-02-28 21:41:16 +03:00
done :
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_addmem_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-28 21:41:16 +03:00
{
DOM_SID group_sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType group_type ;
2004-02-28 21:41:16 +03:00
if ( argc ! = 2 ) {
d_printf ( " Usage: 'net rpc group addmem <group> <member> \n " ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( ! NT_STATUS_IS_OK ( get_sid_from_name ( cli , mem_ctx , argv [ 0 ] ,
& group_sid , & group_type ) ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup group name %s \n " , argv [ 0 ] ) ;
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
if ( group_type = = SID_NAME_DOM_GRP ) {
2005-09-30 21:13:37 +04:00
NTSTATUS result = rpc_add_groupmem ( pipe_hnd , mem_ctx ,
2004-02-28 21:41:16 +03:00
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not add %s to %s: %s \n " ,
2004-02-28 21:41:16 +03:00
argv [ 1 ] , argv [ 0 ] , nt_errstr ( result ) ) ;
}
2004-02-29 19:34:33 +03:00
return result ;
2004-02-28 21:41:16 +03:00
}
if ( group_type = = SID_NAME_ALIAS ) {
2005-09-30 21:13:37 +04:00
NTSTATUS result = rpc_add_aliasmem ( pipe_hnd , mem_ctx ,
2004-02-28 21:41:16 +03:00
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not add %s to %s: %s \n " ,
2004-02-28 21:41:16 +03:00
argv [ 1 ] , argv [ 0 ] , nt_errstr ( result ) ) ;
}
2004-02-29 19:34:33 +03:00
return result ;
2004-02-28 21:41:16 +03:00
}
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Can only add members to global or local groups "
" which %s is not \n " , argv [ 0 ] ) ;
2004-02-29 15:47:45 +03:00
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
static int rpc_group_addmem ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_addmem_internals ,
argc , argv ) ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_del_groupmem ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * group_sid ,
const char * member )
2004-02-28 21:41:16 +03:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 group_rid ;
POLICY_HND group_pol ;
2008-02-08 16:50:04 +03:00
struct samr_Ids rids , rid_types ;
struct lsa_String lsa_acct_name ;
2004-02-28 21:41:16 +03:00
DOM_SID sid ;
sid_copy ( & sid , group_sid ) ;
if ( ! sid_split_rid ( & sid , & group_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
2008-02-04 21:43:07 +03:00
/* Get sam policy handle */
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-01 13:12:05 +03:00
2004-02-28 21:41:16 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid ,
& domain_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , member ) ;
2004-02-28 21:41:16 +03:00
2008-02-08 16:50:04 +03:00
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& rid_types ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup up group member %s \n " , member ) ;
2004-02-28 21:41:16 +03:00
goto done ;
}
2008-02-01 13:24:01 +03:00
result = rpccli_samr_OpenGroup ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rid ,
& group_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2008-02-04 20:13:07 +03:00
result = rpccli_samr_DeleteGroupMember ( pipe_hnd , mem_ctx ,
& group_pol ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ) ;
2004-02-28 21:41:16 +03:00
done :
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_del_aliasmem ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * alias_sid ,
const char * member )
2004-02-28 21:41:16 +03:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 alias_rid ;
POLICY_HND alias_pol ;
DOM_SID member_sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType member_type ;
2004-02-28 21:41:16 +03:00
DOM_SID sid ;
sid_copy ( & sid , alias_sid ) ;
if ( ! sid_split_rid ( & sid , & alias_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
2005-09-30 21:13:37 +04:00
result = get_sid_from_name ( pipe_hnd - > cli , mem_ctx , member ,
2004-02-28 21:41:16 +03:00
& member_sid , & member_type ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup up group member %s \n " , member ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2008-02-04 21:43:07 +03:00
/* Get sam policy handle */
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
2004-02-28 21:41:16 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid ,
& domain_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:38:29 +03:00
result = rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
alias_rid ,
& alias_pol ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-05 01:28:38 +03:00
result = rpccli_samr_DeleteAliasMember ( pipe_hnd , mem_ctx ,
& alias_pol ,
& member_sid ) ;
2004-02-28 21:41:16 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
done :
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2004-02-28 21:41:16 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_delmem_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-28 21:41:16 +03:00
{
DOM_SID group_sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType group_type ;
2004-02-28 21:41:16 +03:00
if ( argc ! = 2 ) {
d_printf ( " Usage: 'net rpc group delmem <group> <member> \n " ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( ! NT_STATUS_IS_OK ( get_sid_from_name ( cli , mem_ctx , argv [ 0 ] ,
& group_sid , & group_type ) ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not lookup group name %s \n " , argv [ 0 ] ) ;
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
if ( group_type = = SID_NAME_DOM_GRP ) {
2005-09-30 21:13:37 +04:00
NTSTATUS result = rpc_del_groupmem ( pipe_hnd , mem_ctx ,
2004-02-28 21:41:16 +03:00
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not del %s from %s: %s \n " ,
2004-02-28 21:41:16 +03:00
argv [ 1 ] , argv [ 0 ] , nt_errstr ( result ) ) ;
}
2004-02-29 19:34:33 +03:00
return result ;
2004-02-28 21:41:16 +03:00
}
if ( group_type = = SID_NAME_ALIAS ) {
2005-09-30 21:13:37 +04:00
NTSTATUS result = rpc_del_aliasmem ( pipe_hnd , mem_ctx ,
2004-02-28 21:41:16 +03:00
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not del %s from %s: %s \n " ,
2004-02-28 21:41:16 +03:00
argv [ 1 ] , argv [ 0 ] , nt_errstr ( result ) ) ;
}
2004-02-29 19:34:33 +03:00
return result ;
2004-02-28 21:41:16 +03:00
}
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Can only delete members from global or local groups "
" which %s is not \n " , argv [ 0 ] ) ;
2004-02-29 15:47:45 +03:00
2004-02-28 21:41:16 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
static int rpc_group_delmem ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_delmem_internals ,
argc , argv ) ;
}
2001-12-30 13:54:58 +03:00
/**
2002-07-15 14:35:28 +04:00
* List groups on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2003-06-12 20:21:22 +04:00
uint32 start_idx = 0 , max_entries = 250 , num_entries , i , loop_count = 0 ;
2008-02-12 13:09:23 +03:00
struct samr_SamArray * groups = NULL ;
2007-10-19 04:40:25 +04:00
bool global = False ;
bool local = False ;
bool builtin = False ;
2003-11-28 18:10:00 +03:00
if ( argc = = 0 ) {
global = True ;
local = True ;
builtin = True ;
}
for ( i = 0 ; i < argc ; i + + ) {
if ( strequal ( argv [ i ] , " global " ) )
global = True ;
if ( strequal ( argv [ i ] , " local " ) )
local = True ;
if ( strequal ( argv [ i ] , " builtin " ) )
builtin = True ;
}
2002-07-15 14:35:28 +04:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-07-15 14:35:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-07-15 14:35:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Query domain groups */
if ( opt_long_list_entries )
d_printf ( " \n Group name Comment " \
" \n ----------------------------- \n " ) ;
do {
2008-02-07 22:46:02 +03:00
uint32_t max_size , total_size , returned_size ;
union samr_DispInfo info ;
2003-06-12 20:21:22 +04:00
2003-11-28 18:10:00 +03:00
if ( ! global ) break ;
2003-06-12 20:21:22 +04:00
get_query_dispinfo_params (
loop_count , & max_entries , & max_size ) ;
2008-02-07 22:46:02 +03:00
result = rpccli_samr_QueryDisplayInfo ( pipe_hnd , mem_ctx ,
& domain_pol ,
3 ,
start_idx ,
max_entries ,
max_size ,
& total_size ,
& returned_size ,
& info ) ;
num_entries = info . info3 . count ;
start_idx + = info . info3 . count ;
2004-02-17 18:24:28 +03:00
2004-02-28 11:18:09 +03:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) )
2004-02-17 18:24:28 +03:00
break ;
2008-02-07 22:46:02 +03:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
2008-02-07 22:46:02 +03:00
const char * group = NULL ;
const char * desc = NULL ;
group = info . info3 . entries [ i ] . account_name . string ;
desc = info . info3 . entries [ i ] . description . string ;
2003-06-12 20:21:22 +04:00
2002-07-15 14:35:28 +04:00
if ( opt_long_list_entries )
2003-06-12 20:21:22 +04:00
printf ( " %-21.21s %-50.50s \n " ,
group , desc ) ;
2002-07-15 14:35:28 +04:00
else
2003-12-01 17:12:26 +03:00
printf ( " %s \n " , group ) ;
2002-07-15 14:35:28 +04:00
}
2003-05-08 02:56:02 +04:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-07-15 14:35:28 +04:00
/* query domain aliases */
2003-06-12 19:37:06 +04:00
start_idx = 0 ;
2002-07-15 14:35:28 +04:00
do {
2003-11-28 18:10:00 +03:00
if ( ! local ) break ;
2008-02-12 13:09:23 +03:00
result = rpccli_samr_EnumDomainAliases ( pipe_hnd , mem_ctx ,
& domain_pol ,
& start_idx ,
& groups ,
0xffff ,
& num_entries ) ;
2004-02-28 11:18:09 +03:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) )
2004-02-17 18:24:28 +03:00
break ;
2008-02-12 13:09:23 +03:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
2008-02-07 15:07:07 +03:00
const char * description = NULL ;
2003-06-12 20:21:22 +04:00
if ( opt_long_list_entries ) {
POLICY_HND alias_pol ;
2008-02-07 15:07:07 +03:00
union samr_AliasInfo * info = NULL ;
2003-06-12 20:21:22 +04:00
2008-02-01 13:38:29 +03:00
if ( ( NT_STATUS_IS_OK ( rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
0x8 ,
2008-02-12 13:09:23 +03:00
groups - > entries [ i ] . idx ,
2008-02-01 13:38:29 +03:00
& alias_pol ) ) ) & &
2008-02-07 15:07:07 +03:00
( NT_STATUS_IS_OK ( rpccli_samr_QueryAliasInfo ( pipe_hnd , mem_ctx ,
& alias_pol ,
3 ,
& info ) ) ) & &
2008-01-30 14:39:20 +03:00
( NT_STATUS_IS_OK ( rpccli_samr_Close ( pipe_hnd , mem_ctx ,
2003-06-12 20:21:22 +04:00
& alias_pol ) ) ) ) {
2008-02-07 15:07:07 +03:00
description = info - > description . string ;
2003-06-12 20:21:22 +04:00
}
}
2008-02-12 13:09:23 +03:00
2003-06-12 20:21:22 +04:00
if ( description ! = NULL ) {
2008-02-12 13:09:23 +03:00
printf ( " %-21.21s %-50.50s \n " ,
groups - > entries [ i ] . name . string ,
2003-06-12 20:21:22 +04:00
description ) ;
} else {
2008-02-12 13:09:23 +03:00
printf ( " %s \n " , groups - > entries [ i ] . name . string ) ;
2003-06-12 20:21:22 +04:00
}
2002-07-15 14:35:28 +04:00
}
2003-05-08 02:56:02 +04:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & domain_pol ) ;
2002-07-15 14:35:28 +04:00
/* Get builtin policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , & global_sid_Builtin ) ,
& domain_pol ) ;
2002-07-15 14:35:28 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* query builtin aliases */
2003-06-12 19:37:06 +04:00
start_idx = 0 ;
2002-07-15 14:35:28 +04:00
do {
2003-11-28 18:10:00 +03:00
if ( ! builtin ) break ;
2008-02-12 13:09:23 +03:00
result = rpccli_samr_EnumDomainAliases ( pipe_hnd , mem_ctx ,
& domain_pol ,
& start_idx ,
& groups ,
max_entries ,
& num_entries ) ;
2004-02-28 11:18:09 +03:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) )
2004-02-17 18:24:28 +03:00
break ;
2008-02-12 13:09:23 +03:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
2008-02-07 15:07:07 +03:00
const char * description = NULL ;
2003-06-12 20:21:22 +04:00
if ( opt_long_list_entries ) {
POLICY_HND alias_pol ;
2008-02-07 15:07:07 +03:00
union samr_AliasInfo * info = NULL ;
2003-06-12 20:21:22 +04:00
2008-02-01 13:38:29 +03:00
if ( ( NT_STATUS_IS_OK ( rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
0x8 ,
2008-02-12 13:09:23 +03:00
groups - > entries [ i ] . idx ,
2008-02-01 13:38:29 +03:00
& alias_pol ) ) ) & &
2008-02-07 15:07:07 +03:00
( NT_STATUS_IS_OK ( rpccli_samr_QueryAliasInfo ( pipe_hnd , mem_ctx ,
& alias_pol ,
3 ,
& info ) ) ) & &
2008-01-30 14:39:20 +03:00
( NT_STATUS_IS_OK ( rpccli_samr_Close ( pipe_hnd , mem_ctx ,
2003-06-12 20:21:22 +04:00
& alias_pol ) ) ) ) {
2008-02-07 15:07:07 +03:00
description = info - > description . string ;
2003-06-12 20:21:22 +04:00
}
}
2008-02-12 13:09:23 +03:00
2003-06-12 20:21:22 +04:00
if ( description ! = NULL ) {
2008-02-12 13:09:23 +03:00
printf ( " %-21.21s %-50.50s \n " ,
groups - > entries [ i ] . name . string ,
2003-06-12 20:21:22 +04:00
description ) ;
} else {
2008-02-12 13:09:23 +03:00
printf ( " %s \n " , groups - > entries [ i ] . name . string ) ;
2003-06-12 20:21:22 +04:00
}
2002-07-15 14:35:28 +04:00
}
2003-05-08 02:56:02 +04:00
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-07-15 14:35:28 +04:00
done :
return result ;
}
2003-11-28 18:10:00 +03:00
static int rpc_group_list ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_list_internals ,
argc , argv ) ;
}
2004-02-09 21:19:25 +03:00
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_list_group_members ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const char * domain_name ,
const DOM_SID * domain_sid ,
POLICY_HND * domain_pol ,
uint32 rid )
2003-11-26 13:07:07 +03:00
{
NTSTATUS result ;
2004-02-09 21:19:25 +03:00
POLICY_HND group_pol ;
2008-02-05 12:58:37 +03:00
uint32 num_members , * group_rids ;
2003-11-26 13:07:07 +03:00
int i ;
2008-02-05 12:58:37 +03:00
struct samr_RidTypeArray * rids = NULL ;
2008-02-08 14:05:29 +03:00
struct lsa_Strings names ;
struct samr_Ids types ;
2003-11-26 13:07:07 +03:00
2004-02-09 21:19:25 +03:00
fstring sid_str ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_str , domain_sid ) ;
2003-11-26 13:07:07 +03:00
2008-02-01 13:24:01 +03:00
result = rpccli_samr_OpenGroup ( pipe_hnd , mem_ctx ,
domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
rid ,
& group_pol ) ;
2003-11-26 13:07:07 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2004-02-09 21:19:25 +03:00
return result ;
2003-11-26 13:07:07 +03:00
2008-02-05 12:58:37 +03:00
result = rpccli_samr_QueryGroupMember ( pipe_hnd , mem_ctx ,
& group_pol ,
& rids ) ;
2003-11-26 13:07:07 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2004-02-09 21:19:25 +03:00
return result ;
2003-11-26 13:07:07 +03:00
2008-02-05 12:58:37 +03:00
num_members = rids - > count ;
group_rids = rids - > rids ;
2004-01-02 08:32:07 +03:00
while ( num_members > 0 ) {
2003-11-27 20:31:18 +03:00
int this_time = 512 ;
2003-11-26 13:07:07 +03:00
2003-11-27 20:31:18 +03:00
if ( num_members < this_time )
this_time = num_members ;
2003-11-26 13:07:07 +03:00
2008-02-08 14:05:29 +03:00
result = rpccli_samr_LookupRids ( pipe_hnd , mem_ctx ,
domain_pol ,
this_time ,
group_rids ,
& names ,
& types ) ;
2003-11-27 20:31:18 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
2004-02-09 21:19:25 +03:00
return result ;
/* We only have users as members, but make the output
the same as the output of alias members */
2003-11-27 20:31:18 +03:00
for ( i = 0 ; i < this_time ; i + + ) {
2004-02-09 21:19:25 +03:00
if ( opt_long_list_entries ) {
printf ( " %s-%d %s \\ %s %d \n " , sid_str ,
2008-02-08 14:05:29 +03:00
group_rids [ i ] , domain_name ,
names . names [ i ] . string ,
2004-02-09 21:19:25 +03:00
SID_NAME_USER ) ;
} else {
2008-02-08 14:05:29 +03:00
printf ( " %s \\ %s \n " , domain_name ,
names . names [ i ] . string ) ;
2004-02-09 21:19:25 +03:00
}
2003-11-27 20:31:18 +03:00
}
num_members - = this_time ;
group_rids + = 512 ;
2004-01-02 08:32:07 +03:00
}
2003-11-26 13:07:07 +03:00
2004-02-09 21:19:25 +03:00
return NT_STATUS_OK ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_list_alias_members ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
POLICY_HND * domain_pol ,
uint32 rid )
2004-02-09 21:19:25 +03:00
{
NTSTATUS result ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * lsa_pipe ;
2004-02-09 21:19:25 +03:00
POLICY_HND alias_pol , lsa_pol ;
uint32 num_members ;
DOM_SID * alias_sids ;
char * * domains ;
char * * names ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types ;
2004-02-09 21:19:25 +03:00
int i ;
2008-02-05 03:18:56 +03:00
struct lsa_SidArray sid_array ;
2004-02-09 21:19:25 +03:00
2008-02-01 13:38:29 +03:00
result = rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
rid ,
& alias_pol ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-05 03:18:56 +03:00
result = rpccli_samr_GetMembersInAlias ( pipe_hnd , mem_ctx ,
& alias_pol ,
& sid_array ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't list alias members \n " ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
2008-02-05 03:18:56 +03:00
num_members = sid_array . num_sids ;
2004-02-17 13:08:18 +03:00
if ( num_members = = 0 ) {
return NT_STATUS_OK ;
}
2005-09-30 21:13:37 +04:00
lsa_pipe = cli_rpc_pipe_open_noauth ( pipe_hnd - > cli , PI_LSARPC , & result ) ;
if ( ! lsa_pipe ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't open LSA pipe. Error was %s \n " ,
2005-09-30 21:13:37 +04:00
nt_errstr ( result ) ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_open_policy ( lsa_pipe , mem_ctx , True ,
2004-02-09 21:19:25 +03:00
SEC_RIGHTS_MAXIMUM_ALLOWED , & lsa_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't open LSA policy handle \n " ) ;
2005-09-30 21:13:37 +04:00
cli_rpc_pipe_close ( lsa_pipe ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
2008-02-05 03:18:56 +03:00
alias_sids = TALLOC_ZERO_ARRAY ( mem_ctx , DOM_SID , num_members ) ;
if ( ! alias_sids ) {
d_fprintf ( stderr , " Out of memory \n " ) ;
cli_rpc_pipe_close ( lsa_pipe ) ;
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_members ; i + + ) {
sid_copy ( & alias_sids [ i ] , sid_array . sids [ i ] . sid ) ;
}
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_lookup_sids ( lsa_pipe , mem_ctx , & lsa_pol , num_members ,
2004-02-09 21:19:25 +03:00
alias_sids ,
& domains , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't lookup SIDs \n " ) ;
2005-09-30 21:13:37 +04:00
cli_rpc_pipe_close ( lsa_pipe ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
for ( i = 0 ; i < num_members ; i + + ) {
fstring sid_str ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_str , & alias_sids [ i ] ) ;
2004-02-09 21:19:25 +03:00
if ( opt_long_list_entries ) {
printf ( " %s %s \\ %s %d \n " , sid_str ,
domains [ i ] ? domains [ i ] : " *unknown* " ,
names [ i ] ? names [ i ] : " *unknown* " , types [ i ] ) ;
} else {
if ( domains [ i ] )
printf ( " %s \\ %s \n " , domains [ i ] , names [ i ] ) ;
else
printf ( " %s \n " , sid_str ) ;
}
}
2005-09-30 21:13:37 +04:00
cli_rpc_pipe_close ( lsa_pipe ) ;
2004-02-09 21:19:25 +03:00
return NT_STATUS_OK ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_members_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-02-09 21:19:25 +03:00
{
NTSTATUS result ;
POLICY_HND connect_pol , domain_pol ;
2008-02-08 16:50:04 +03:00
struct samr_Ids rids , rid_types ;
struct lsa_String lsa_acct_name ;
2004-02-09 21:19:25 +03:00
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , argv [ 0 ] ) ; /* sure? */
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& rid_types ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
/* Ok, did not find it in the global sam, try with builtin */
DOM_SID sid_Builtin ;
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & domain_pol ) ;
2004-02-09 21:19:25 +03:00
string_to_sid ( & sid_Builtin , " S-1-5-32 " ) ;
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid_Builtin ,
& domain_pol ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't find group %s \n " , argv [ 0 ] ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
2008-02-08 16:50:04 +03:00
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& rid_types ) ;
2004-02-09 21:19:25 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't find group %s \n " , argv [ 0 ] ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
}
2008-02-08 16:50:04 +03:00
if ( rids . count ! = 1 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't find group %s \n " , argv [ 0 ] ) ;
2004-02-09 21:19:25 +03:00
return result ;
}
2008-02-08 16:50:04 +03:00
if ( rid_types . ids [ 0 ] = = SID_NAME_DOM_GRP ) {
2005-09-30 21:13:37 +04:00
return rpc_list_group_members ( pipe_hnd , mem_ctx , domain_name ,
2004-02-09 21:19:25 +03:00
domain_sid , & domain_pol ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ) ;
2004-02-09 21:19:25 +03:00
}
2008-02-08 16:50:04 +03:00
if ( rid_types . ids [ 0 ] = = SID_NAME_ALIAS ) {
2005-09-30 21:13:37 +04:00
return rpc_list_alias_members ( pipe_hnd , mem_ctx , & domain_pol ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ) ;
2004-02-09 21:19:25 +03:00
}
return NT_STATUS_NO_SUCH_GROUP ;
2003-11-26 13:07:07 +03:00
}
static int rpc_group_members ( int argc , const char * * argv )
{
if ( argc ! = 1 ) {
return rpc_group_usage ( argc , argv ) ;
}
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_members_internals ,
argc , argv ) ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_group_rename_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-06-02 18:25:29 +04:00
{
NTSTATUS result ;
POLICY_HND connect_pol , domain_pol , group_pol ;
2008-02-06 15:06:31 +03:00
union samr_GroupInfo group_info ;
2008-02-08 16:50:04 +03:00
struct samr_Ids rids , rid_types ;
struct lsa_String lsa_acct_name ;
2004-06-02 18:25:29 +04:00
if ( argc ! = 2 ) {
d_printf ( " Usage: 'net rpc group rename group newname' \n " ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* Get sam policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-06-02 18:25:29 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-06-02 18:25:29 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , argv [ 0 ] ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& rids ,
& rid_types ) ;
2004-06-02 18:25:29 +04:00
2008-02-08 16:50:04 +03:00
if ( rids . count ! = 1 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't find group %s \n " , argv [ 0 ] ) ;
2004-06-02 18:25:29 +04:00
return result ;
}
2008-02-08 16:50:04 +03:00
if ( rid_types . ids [ 0 ] ! = SID_NAME_DOM_GRP ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Can only rename domain groups \n " ) ;
2004-06-02 18:25:29 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2008-02-01 13:24:01 +03:00
result = rpccli_samr_OpenGroup ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
rids . ids [ 0 ] ,
2008-02-01 13:24:01 +03:00
& group_pol ) ;
2004-06-02 18:25:29 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
2008-02-06 15:06:31 +03:00
init_lsa_String ( & group_info . name , argv [ 1 ] ) ;
2004-06-02 18:25:29 +04:00
2008-02-06 15:06:31 +03:00
result = rpccli_samr_SetGroupInfo ( pipe_hnd , mem_ctx ,
& group_pol ,
2 ,
& group_info ) ;
2004-06-02 18:25:29 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
return NT_STATUS_NO_SUCH_GROUP ;
}
static int rpc_group_rename ( int argc , const char * * argv )
{
if ( argc ! = 2 ) {
return rpc_group_usage ( argc , argv ) ;
}
return run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_group_rename_internals ,
argc , argv ) ;
}
2002-07-15 14:35:28 +04:00
/**
* ' net rpc group ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
int net_rpc_group ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " add " , rpc_group_add } ,
2004-04-19 00:22:31 +04:00
{ " delete " , rpc_group_delete } ,
2004-02-28 21:41:16 +03:00
{ " addmem " , rpc_group_addmem } ,
{ " delmem " , rpc_group_delmem } ,
2003-11-28 18:10:00 +03:00
{ " list " , rpc_group_list } ,
2003-11-26 13:07:07 +03:00
{ " members " , rpc_group_members } ,
2004-06-02 18:25:29 +04:00
{ " rename " , rpc_group_rename } ,
2002-07-15 14:35:28 +04:00
{ NULL , NULL }
} ;
if ( argc = = 0 ) {
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 ,
2002-07-15 14:35:28 +04:00
rpc_group_list_internals ,
argc , argv ) ;
}
return net_run_function ( argc , argv , func , rpc_group_usage ) ;
}
/****************************************************************************/
static int rpc_share_usage ( int argc , const char * * argv )
{
return net_help_share ( argc , argv ) ;
}
/**
* Add a share on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_add_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx , int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2006-06-19 23:07:39 +04:00
char * sharename ;
2002-07-15 14:35:28 +04:00
char * path ;
2005-06-16 13:36:53 +04:00
uint32 type = STYPE_DISKTREE ; /* only allow disk shares to be added */
2002-07-15 14:35:28 +04:00
uint32 num_users = 0 , perms = 0 ;
char * password = NULL ; /* don't allow a share password */
2006-11-19 21:57:52 +03:00
uint32 level = 2 ;
2002-07-15 14:35:28 +04:00
2006-06-19 23:07:39 +04:00
if ( ( sharename = talloc_strdup ( mem_ctx , argv [ 0 ] ) ) = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2002-07-15 14:35:28 +04:00
path = strchr ( sharename , ' = ' ) ;
if ( ! path )
return NT_STATUS_UNSUCCESSFUL ;
* path + + = ' \0 ' ;
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_add ( pipe_hnd , mem_ctx , sharename , type ,
opt_comment , perms , opt_maxusers ,
num_users , path , password ,
level , NULL ) ;
return werror_to_ntstatus ( result ) ;
2002-07-15 14:35:28 +04:00
}
static int rpc_share_add ( int argc , const char * * argv )
{
if ( ( argc < 1 ) | | ! strchr ( argv [ 0 ] , ' = ' ) ) {
DEBUG ( 1 , ( " Sharename or path not specified on add \n " ) ) ;
return rpc_share_usage ( argc , argv ) ;
}
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_share_add_internals ,
argc , argv ) ;
}
/**
* Delete a share on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_del_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
result = rpccli_srvsvc_net_share_del ( pipe_hnd , mem_ctx , argv [ 0 ] ) ;
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
}
/**
* Delete a share on a remote RPC server
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_share_delete ( int argc , const char * * argv )
{
if ( argc < 1 ) {
DEBUG ( 1 , ( " Sharename not specified on delete \n " ) ) ;
return rpc_share_usage ( argc , argv ) ;
}
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_share_del_internals ,
argc , argv ) ;
}
/**
* Formatted print of share info
*
2007-10-11 00:34:30 +04:00
* @ param info1 pointer to SRV_SHARE_INFO_1 to format
2002-07-15 14:35:28 +04:00
* */
2007-10-11 00:34:30 +04:00
static void display_share_info_1 ( SRV_SHARE_INFO_1 * info1 )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
fstring netname = " " , remark = " " ;
rpcstr_pull_unistr2_fstring ( netname , & info1 - > info_1_str . uni_netname ) ;
rpcstr_pull_unistr2_fstring ( remark , & info1 - > info_1_str . uni_remark ) ;
2002-07-15 14:35:28 +04:00
if ( opt_long_list_entries ) {
2004-02-11 17:59:08 +03:00
d_printf ( " %-12s %-8.8s %-50s \n " ,
2007-10-11 00:34:30 +04:00
netname , share_type [ info1 - > info_1 . type & ~ ( STYPE_TEMPORARY | STYPE_HIDDEN ) ] , remark ) ;
2002-07-15 14:35:28 +04:00
} else {
2007-10-11 00:34:30 +04:00
d_printf ( " %s \n " , netname ) ;
2002-07-15 14:35:28 +04:00
}
}
2007-10-11 00:34:30 +04:00
static WERROR get_share_info ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
uint32 level ,
int argc ,
const char * * argv ,
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO_CTR * ctr )
2005-06-16 13:36:53 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
SRV_SHARE_INFO info ;
2005-06-16 13:36:53 +04:00
/* no specific share requested, enumerate all */
if ( argc = = 0 ) {
2007-10-11 00:34:30 +04:00
ENUM_HND hnd ;
uint32 preferred_len = 0xffffffff ;
init_enum_hnd ( & hnd , 0 ) ;
return rpccli_srvsvc_net_share_enum ( pipe_hnd , mem_ctx , level , ctr ,
preferred_len , & hnd ) ;
2005-06-16 13:36:53 +04:00
}
/* request just one share */
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_get_info ( pipe_hnd , mem_ctx , argv [ 0 ] , level , & info ) ;
2006-10-21 20:27:38 +04:00
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
goto done ;
/* construct ctr */
ZERO_STRUCTP ( ctr ) ;
ctr - > info_level = ctr - > switch_value = level ;
ctr - > ptr_share_info = ctr - > ptr_entries = 1 ;
ctr - > num_entries = ctr - > num_entries2 = 1 ;
2006-10-21 20:27:38 +04:00
2007-10-11 00:34:30 +04:00
switch ( level ) {
2006-10-21 20:27:38 +04:00
case 1 :
2007-10-11 00:34:30 +04:00
{
char * s ;
SRV_SHARE_INFO_1 * info1 ;
ctr - > share . info1 = TALLOC_ARRAY ( mem_ctx , SRV_SHARE_INFO_1 , 1 ) ;
if ( ctr - > share . info1 = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info1 = ctr - > share . info1 ;
memset ( ctr - > share . info1 , 0 , sizeof ( SRV_SHARE_INFO_1 ) ) ;
/* Copy pointer crap */
memcpy ( & info1 - > info_1 , & info . share . info1 . info_1 , sizeof ( SH_INFO_1 ) ) ;
/* Duplicate strings */
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info1 . info_1_str . uni_netname ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info1 - > info_1_str . uni_netname , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info1 . info_1_str . uni_remark ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info1 - > info_1_str . uni_remark , s , UNI_STR_TERMINATE ) ;
}
case 2 :
{
char * s ;
SRV_SHARE_INFO_2 * info2 ;
ctr - > share . info2 = TALLOC_ARRAY ( mem_ctx , SRV_SHARE_INFO_2 , 1 ) ;
if ( ctr - > share . info2 = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2 = ctr - > share . info2 ;
memset ( ctr - > share . info2 , 0 , sizeof ( SRV_SHARE_INFO_2 ) ) ;
/* Copy pointer crap */
memcpy ( & info2 - > info_2 , & info . share . info2 . info_2 , sizeof ( SH_INFO_2 ) ) ;
/* Duplicate strings */
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info2 . info_2_str . uni_netname ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info2 - > info_2_str . uni_netname , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info2 . info_2_str . uni_remark ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info2 - > info_2_str . uni_remark , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info2 . info_2_str . uni_path ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info2 - > info_2_str . uni_path , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info2 . info_2_str . uni_passwd ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info2 - > info_2_str . uni_passwd , s , UNI_STR_TERMINATE ) ;
}
2006-10-21 20:27:38 +04:00
case 502 :
2007-10-11 00:34:30 +04:00
{
char * s ;
SRV_SHARE_INFO_502 * info502 ;
ctr - > share . info502 = TALLOC_ARRAY ( mem_ctx , SRV_SHARE_INFO_502 , 1 ) ;
if ( ctr - > share . info502 = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info502 = ctr - > share . info502 ;
memset ( ctr - > share . info502 , 0 , sizeof ( SRV_SHARE_INFO_502 ) ) ;
/* Copy pointer crap */
memcpy ( & info502 - > info_502 , & info . share . info502 . info_502 , sizeof ( SH_INFO_502 ) ) ;
/* Duplicate strings */
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info502 . info_502_str . uni_netname ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info502 - > info_502_str . uni_netname , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info502 . info_502_str . uni_remark ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info502 - > info_502_str . uni_remark , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info502 . info_502_str . uni_path ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info502 - > info_502_str . uni_path , s , UNI_STR_TERMINATE ) ;
2007-11-28 01:35:30 +03:00
s = unistr2_to_ascii_talloc ( mem_ctx , & info . share . info502 . info_502_str . uni_passwd ) ;
2007-10-11 00:34:30 +04:00
if ( s )
init_unistr2 ( & info502 - > info_502_str . uni_passwd , s , UNI_STR_TERMINATE ) ;
info502 - > info_502_str . sd = dup_sec_desc ( mem_ctx , info . share . info502 . info_502_str . sd ) ;
2006-10-21 20:27:38 +04:00
}
2007-10-11 00:34:30 +04:00
} /* switch */
done :
return result ;
2005-06-16 13:36:53 +04:00
}
2002-07-15 14:35:28 +04:00
/**
* List shares on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO_CTR ctr ;
WERROR result ;
2005-06-16 13:36:53 +04:00
uint32 i , level = 1 ;
2002-07-15 14:35:28 +04:00
2007-10-11 00:34:30 +04:00
result = get_share_info ( pipe_hnd , mem_ctx , level , argc , argv , & ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) )
2002-07-15 14:35:28 +04:00
goto done ;
/* Display results */
if ( opt_long_list_entries ) {
d_printf (
" \n Enumerating shared resources (exports) on remote server: \n \n " \
" \n Share name Type Description \n " \
" ---------- ---- ----------- \n " ) ;
}
2007-10-11 00:34:30 +04:00
for ( i = 0 ; i < ctr . num_entries ; i + + )
display_share_info_1 ( & ctr . share . info1 [ i ] ) ;
2002-07-15 14:35:28 +04:00
done :
2007-10-11 00:34:30 +04:00
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
}
2005-06-16 13:36:53 +04:00
/***
* ' net rpc share list ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
static int rpc_share_list ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_list_internals , argc , argv ) ;
}
2007-10-19 04:40:25 +04:00
static bool check_share_availability ( struct cli_state * cli , const char * netname )
2005-06-16 13:36:53 +04:00
{
if ( ! cli_send_tconX ( cli , netname , " A: " , " " , 0 ) ) {
d_printf ( " skipping [%s]: not a file share. \n " , netname ) ;
return False ;
}
if ( ! cli_tdis ( cli ) )
return False ;
return True ;
}
2007-10-19 04:40:25 +04:00
static bool check_share_sanity ( struct cli_state * cli , fstring netname , uint32 type )
2005-06-16 13:36:53 +04:00
{
/* only support disk shares */
if ( ! ( type = = STYPE_DISKTREE | | type = = ( STYPE_DISKTREE | STYPE_HIDDEN ) ) ) {
printf ( " share [%s] is not a diskshare (type: %x) \n " , netname , type ) ;
return False ;
}
/* skip builtin shares */
/* FIXME: should print$ be added too ? */
if ( strequal ( netname , " IPC$ " ) | | strequal ( netname , " ADMIN$ " ) | |
strequal ( netname , " global " ) )
return False ;
if ( opt_exclude & & in_list ( netname , opt_exclude , False ) ) {
printf ( " excluding [%s] \n " , netname ) ;
return False ;
}
return check_share_availability ( cli , netname ) ;
}
2004-08-10 18:27:17 +04:00
/**
2008-02-26 12:26:10 +03:00
* Migrate shares from a remote RPC server to the local RPC server
2004-08-10 18:27:17 +04:00
*
* All parameters are provided by the run_rpc_command function , except for
2008-02-26 12:26:10 +03:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
2008-02-26 12:26:10 +03:00
* @ param mem_ctx Talloc context , destroyed on completion of the function .
2004-08-10 18:27:17 +04:00
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_migrate_shares_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2004-08-10 18:27:17 +04:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO_CTR ctr_src ;
uint32 type = STYPE_DISKTREE ; /* only allow disk shares to be added */
char * password = NULL ; /* don't allow a share password */
2005-06-16 13:36:53 +04:00
uint32 i ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * srvsvc_pipe = NULL ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
uint32 level = 502 ; /* includes secdesc */
2007-10-11 00:34:30 +04:00
result = get_share_info ( pipe_hnd , mem_ctx , level , argc , argv , & ctr_src ) ;
if ( ! W_ERROR_IS_OK ( result ) )
2004-08-10 18:27:17 +04:00
goto done ;
2005-06-16 13:36:53 +04:00
/* connect destination PI_SRVSVC */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & srvsvc_pipe , PI_SRVSVC ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2007-10-11 00:34:30 +04:00
for ( i = 0 ; i < ctr_src . num_entries ; i + + ) {
2004-08-10 18:27:17 +04:00
2007-10-11 00:34:30 +04:00
fstring netname = " " , remark = " " , path = " " ;
2004-08-10 18:27:17 +04:00
/* reset error-code */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-10-11 00:34:30 +04:00
rpcstr_pull_unistr2_fstring (
netname , & ctr_src . share . info502 [ i ] . info_502_str . uni_netname ) ;
rpcstr_pull_unistr2_fstring (
remark , & ctr_src . share . info502 [ i ] . info_502_str . uni_remark ) ;
rpcstr_pull_unistr2_fstring (
path , & ctr_src . share . info502 [ i ] . info_502_str . uni_path ) ;
if ( ! check_share_sanity ( cli , netname , ctr_src . share . info502 [ i ] . info_502 . type ) )
2005-03-22 18:45:38 +03:00
continue ;
2004-08-10 18:27:17 +04:00
2005-06-16 13:36:53 +04:00
/* finally add the share on the dst server */
2004-08-10 18:27:17 +04:00
2005-06-24 18:15:31 +04:00
printf ( " migrating: [%s], path: %s, comment: %s, without share-ACLs \n " ,
2007-10-11 00:34:30 +04:00
netname , path , remark ) ;
result = rpccli_srvsvc_net_share_add ( srvsvc_pipe , mem_ctx , netname , type , remark ,
ctr_src . share . info502 [ i ] . info_502 . perms ,
ctr_src . share . info502 [ i ] . info_502 . max_uses ,
ctr_src . share . info502 [ i ] . info_502 . num_uses ,
path , password , level ,
NULL ) ;
2004-08-10 18:27:17 +04:00
2007-10-11 00:34:30 +04:00
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ALREADY_EXISTS ) ) {
printf ( " [%s] does already exist \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
2004-08-21 00:13:05 +04:00
}
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot add share: %s \n " , dos_errstr ( result ) ) ;
2004-08-10 18:27:17 +04:00
goto done ;
}
}
nt_status = NT_STATUS_OK ;
done :
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}
/**
* Migrate shares from a rpc - server to another
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_share_migrate_shares ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
rpc_share_migrate_shares_internals ,
argc , argv ) ;
}
/**
* Copy a file / dir
*
* @ param f file_info
* @ param mask current search mask
* @ param state arg - pointer
*
* */
2005-03-02 06:24:40 +03:00
static void copy_fn ( const char * mnt , file_info * f , const char * mask , void * state )
2004-08-10 18:27:17 +04:00
{
2005-06-13 01:18:16 +04:00
static NTSTATUS nt_status ;
static struct copy_clistate * local_state ;
static fstring filename , new_mask ;
fstring dir ;
char * old_dir ;
local_state = ( struct copy_clistate * ) state ;
nt_status = NT_STATUS_UNSUCCESSFUL ;
2005-06-15 18:24:11 +04:00
if ( strequal ( f - > name , " . " ) | | strequal ( f - > name , " .. " ) )
2004-08-10 18:27:17 +04:00
return ;
DEBUG ( 3 , ( " got mask: %s, name: %s \n " , mask , f - > name ) ) ;
/* DIRECTORY */
if ( f - > mode & aDIR ) {
DEBUG ( 3 , ( " got dir: %s \n " , f - > name ) ) ;
fstrcpy ( dir , local_state - > cwd ) ;
fstrcat ( dir , " \\ " ) ;
fstrcat ( dir , f - > name ) ;
2005-06-24 03:23:16 +04:00
switch ( net_mode_share )
2005-06-13 01:18:16 +04:00
{
case NET_MODE_SHARE_MIGRATE :
/* create that directory */
nt_status = net_copy_file ( local_state - > mem_ctx ,
local_state - > cli_share_src ,
local_state - > cli_share_dst ,
dir , dir ,
opt_acls ? True : False ,
opt_attrs ? True : False ,
opt_timestamps ? True : False ,
False ) ;
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unsupported mode %d \n " , net_mode_share ) ;
2005-06-13 01:18:16 +04:00
return ;
}
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
2005-06-13 01:18:16 +04:00
printf ( " could not handle dir %s: %s \n " ,
2004-08-10 18:27:17 +04:00
dir , nt_errstr ( nt_status ) ) ;
2005-06-15 18:24:11 +04:00
/* search below that directory */
fstrcpy ( new_mask , dir ) ;
fstrcat ( new_mask , " \\ * " ) ;
old_dir = local_state - > cwd ;
local_state - > cwd = dir ;
if ( ! sync_files ( local_state , new_mask ) )
printf ( " could not handle files \n " ) ;
local_state - > cwd = old_dir ;
2004-08-10 18:27:17 +04:00
return ;
}
/* FILE */
fstrcpy ( filename , local_state - > cwd ) ;
fstrcat ( filename , " \\ " ) ;
fstrcat ( filename , f - > name ) ;
DEBUG ( 3 , ( " got file: %s \n " , filename ) ) ;
2005-06-24 03:23:16 +04:00
switch ( net_mode_share )
2005-06-13 01:18:16 +04:00
{
case NET_MODE_SHARE_MIGRATE :
nt_status = net_copy_file ( local_state - > mem_ctx ,
local_state - > cli_share_src ,
local_state - > cli_share_dst ,
filename , filename ,
opt_acls ? True : False ,
opt_attrs ? True : False ,
opt_timestamps ? True : False ,
True ) ;
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unsupported file mode %d \n " , net_mode_share ) ;
2005-06-13 01:18:16 +04:00
return ;
}
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
2005-06-13 01:18:16 +04:00
printf ( " could not handle file %s: %s \n " ,
2004-08-10 18:27:17 +04:00
filename , nt_errstr ( nt_status ) ) ;
}
/**
* sync files , can be called recursivly to list files
* and then call copy_fn for each file
*
2005-06-13 01:18:16 +04:00
* @ param cp_clistate pointer to the copy_clistate we work with
2004-08-10 18:27:17 +04:00
* @ param mask the current search mask
*
* @ return Boolean result
* */
2007-12-05 03:35:24 +03:00
static bool sync_files ( struct copy_clistate * cp_clistate , const char * mask )
2004-08-10 18:27:17 +04:00
{
2007-03-09 02:54:57 +03:00
struct cli_state * targetcli ;
2007-11-30 04:25:41 +03:00
char * targetpath = NULL ;
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " calling cli_list with mask: %s \n " , mask ) ) ;
2007-11-30 04:25:41 +03:00
if ( ! cli_resolve_path ( talloc_tos ( ) , " " , cp_clistate - > cli_share_src ,
mask , & targetcli , & targetpath ) ) {
2007-03-09 02:54:57 +03:00
d_fprintf ( stderr , " cli_resolve_path %s failed with error: %s \n " ,
2005-06-13 01:18:16 +04:00
mask , cli_errstr ( cp_clistate - > cli_share_src ) ) ;
2004-08-10 18:27:17 +04:00
return False ;
}
2007-03-09 02:54:57 +03:00
if ( cli_list ( targetcli , targetpath , cp_clistate - > attribute , copy_fn , cp_clistate ) = = - 1 ) {
d_fprintf ( stderr , " listing %s failed with error: %s \n " ,
mask , cli_errstr ( targetcli ) ) ;
return False ;
}
2004-08-10 18:27:17 +04:00
return True ;
}
2005-06-15 18:24:11 +04:00
/**
* Set the top level directory permissions before we do any further copies .
* Should set up ACL inheritance .
* */
2007-10-19 04:40:25 +04:00
bool copy_top_level_perms ( struct copy_clistate * cp_clistate ,
2005-06-15 18:24:11 +04:00
const char * sharename )
{
2005-09-30 21:13:37 +04:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2005-06-15 18:24:11 +04:00
2005-06-24 03:23:16 +04:00
switch ( net_mode_share ) {
2005-06-15 18:24:11 +04:00
case NET_MODE_SHARE_MIGRATE :
DEBUG ( 3 , ( " calling net_copy_fileattr for '.' directory in share %s \n " , sharename ) ) ;
nt_status = net_copy_fileattr ( cp_clistate - > mem_ctx ,
cp_clistate - > cli_share_src ,
cp_clistate - > cli_share_dst ,
" \\ " , " \\ " ,
opt_acls ? True : False ,
opt_attrs ? True : False ,
opt_timestamps ? True : False ,
False ) ;
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unsupported mode %d \n " , net_mode_share ) ;
2005-06-15 18:24:11 +04:00
break ;
}
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
printf ( " Could handle directory attributes for top level directory of share %s. Error %s \n " ,
sharename , nt_errstr ( nt_status ) ) ;
return False ;
}
return True ;
}
2004-08-10 18:27:17 +04:00
/**
* Sync all files inside a remote share to another share ( over smb )
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_migrate_files_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2004-08-10 18:27:17 +04:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO_CTR ctr_src ;
2005-06-16 13:36:53 +04:00
uint32 i ;
uint32 level = 502 ;
2005-06-13 01:18:16 +04:00
struct copy_clistate cp_clistate ;
2007-10-19 04:40:25 +04:00
bool got_src_share = False ;
bool got_dst_share = False ;
2007-12-05 03:35:24 +03:00
const char * mask = " \\ * " ;
2004-08-27 01:37:20 +04:00
char * dst = NULL ;
2004-12-07 21:25:53 +03:00
dst = SMB_STRDUP ( opt_destination ? opt_destination : " 127.0.0.1 " ) ;
2004-08-10 18:27:17 +04:00
2007-10-11 00:34:30 +04:00
result = get_share_info ( pipe_hnd , mem_ctx , level , argc , argv , & ctr_src ) ;
2004-08-10 18:27:17 +04:00
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
2004-08-10 18:27:17 +04:00
goto done ;
2007-10-11 00:34:30 +04:00
for ( i = 0 ; i < ctr_src . num_entries ; i + + ) {
fstring netname = " " ;
rpcstr_pull_unistr2_fstring (
netname , & ctr_src . share . info502 [ i ] . info_502_str . uni_netname ) ;
if ( ! check_share_sanity ( cli , netname , ctr_src . share . info502 [ i ] . info_502 . type ) )
2004-08-10 18:27:17 +04:00
continue ;
2005-06-16 13:36:53 +04:00
/* one might not want to mirror whole discs :) */
2007-10-11 00:34:30 +04:00
if ( strequal ( netname , " print$ " ) | | netname [ 1 ] = = ' $ ' ) {
d_printf ( " skipping [%s]: builtin/hidden share \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
2005-06-24 03:23:16 +04:00
switch ( net_mode_share )
2005-06-13 01:18:16 +04:00
{
case NET_MODE_SHARE_MIGRATE :
printf ( " syncing " ) ;
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unsupported mode %d \n " , net_mode_share ) ;
2005-06-13 01:18:16 +04:00
break ;
}
printf ( " [%s] files and directories %s ACLs, %s DOS Attributes %s \n " ,
2007-10-11 00:34:30 +04:00
netname ,
2004-08-21 00:13:05 +04:00
opt_acls ? " including " : " without " ,
opt_attrs ? " including " : " without " ,
opt_timestamps ? " (preserving timestamps) " : " " ) ;
2004-08-10 18:27:17 +04:00
2005-06-13 01:18:16 +04:00
cp_clistate . mem_ctx = mem_ctx ;
cp_clistate . cli_share_src = NULL ;
cp_clistate . cli_share_dst = NULL ;
cp_clistate . cwd = NULL ;
cp_clistate . attribute = aSYSTEM | aHIDDEN | aDIR ;
2004-08-10 18:27:17 +04:00
/* open share source */
2005-06-13 01:18:16 +04:00
nt_status = connect_to_service ( & cp_clistate . cli_share_src ,
2007-10-25 01:16:54 +04:00
& cli - > dest_ss , cli - > desthost ,
2007-10-11 00:34:30 +04:00
netname , " A: " ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
got_src_share = True ;
2005-06-24 03:23:16 +04:00
if ( net_mode_share = = NET_MODE_SHARE_MIGRATE ) {
2005-06-13 01:18:16 +04:00
/* open share destination */
nt_status = connect_to_service ( & cp_clistate . cli_share_dst ,
2007-10-11 00:34:30 +04:00
NULL , dst , netname , " A: " ) ;
2005-06-13 01:18:16 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
2004-08-10 18:27:17 +04:00
2005-06-13 01:18:16 +04:00
got_dst_share = True ;
}
2004-08-10 18:27:17 +04:00
2007-10-11 00:34:30 +04:00
if ( ! copy_top_level_perms ( & cp_clistate , netname ) ) {
d_fprintf ( stderr , " Could not handle the top level directory permissions for the share: %s \n " , netname ) ;
2005-06-15 18:24:11 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-08-10 18:27:17 +04:00
2005-06-13 01:18:16 +04:00
if ( ! sync_files ( & cp_clistate , mask ) ) {
2007-10-11 00:34:30 +04:00
d_fprintf ( stderr , " could not handle files for share: %s \n " , netname ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_src_share )
2005-06-13 01:18:16 +04:00
cli_shutdown ( cp_clistate . cli_share_src ) ;
2004-08-10 18:27:17 +04:00
if ( got_dst_share )
2005-06-13 01:18:16 +04:00
cli_shutdown ( cp_clistate . cli_share_dst ) ;
2004-08-10 18:27:17 +04:00
return nt_status ;
}
static int rpc_share_migrate_files ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
rpc_share_migrate_files_internals ,
argc , argv ) ;
}
2005-06-16 13:36:53 +04:00
/**
* Migrate share - ACLs from a remote RPC server to the local RPC srever
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_migrate_security_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2005-06-16 13:36:53 +04:00
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2005-06-16 13:36:53 +04:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO_CTR ctr_src ;
SRV_SHARE_INFO info ;
2005-06-16 13:36:53 +04:00
uint32 i ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * srvsvc_pipe = NULL ;
2005-06-16 13:36:53 +04:00
struct cli_state * cli_dst = NULL ;
uint32 level = 502 ; /* includes secdesc */
2007-10-11 00:34:30 +04:00
result = get_share_info ( pipe_hnd , mem_ctx , level , argc , argv , & ctr_src ) ;
2005-06-16 13:36:53 +04:00
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
2005-06-16 13:36:53 +04:00
goto done ;
/* connect destination PI_SRVSVC */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & srvsvc_pipe , PI_SRVSVC ) ;
2005-06-16 13:36:53 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2007-10-11 00:34:30 +04:00
for ( i = 0 ; i < ctr_src . num_entries ; i + + ) {
fstring netname = " " , remark = " " , path = " " ;
2005-06-16 13:36:53 +04:00
/* reset error-code */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-10-11 00:34:30 +04:00
rpcstr_pull_unistr2_fstring (
netname , & ctr_src . share . info502 [ i ] . info_502_str . uni_netname ) ;
rpcstr_pull_unistr2_fstring (
remark , & ctr_src . share . info502 [ i ] . info_502_str . uni_remark ) ;
rpcstr_pull_unistr2_fstring (
path , & ctr_src . share . info502 [ i ] . info_502_str . uni_path ) ;
if ( ! check_share_sanity ( cli , netname , ctr_src . share . info502 [ i ] . info_502 . type ) )
2005-06-16 13:36:53 +04:00
continue ;
printf ( " migrating: [%s], path: %s, comment: %s, including share-ACLs \n " ,
2007-10-11 00:34:30 +04:00
netname , path , remark ) ;
2005-06-16 13:36:53 +04:00
if ( opt_verbose )
2007-10-11 00:34:30 +04:00
display_sec_desc ( ctr_src . share . info502 [ i ] . info_502_str . sd ) ;
2005-06-16 13:36:53 +04:00
/* init info */
ZERO_STRUCT ( info ) ;
2007-10-11 00:34:30 +04:00
info . switch_value = level ;
info . ptr_share_ctr = 1 ;
/* FIXME: shouldn't we be able to just set the security descriptor ? */
info . share . info502 = ctr_src . share . info502 [ i ] ;
2005-06-16 13:36:53 +04:00
/* finally modify the share on the dst server */
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_set_info ( srvsvc_pipe , mem_ctx , netname , level , & info ) ;
2005-06-16 13:36:53 +04:00
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot set share-acl: %s \n " , dos_errstr ( result ) ) ;
2005-06-16 13:36:53 +04:00
goto done ;
}
}
nt_status = NT_STATUS_OK ;
done :
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2005-06-16 13:36:53 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}
/**
* Migrate share - acls from a rpc - server to another
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_share_migrate_security ( int argc , const char * * argv )
{
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
rpc_share_migrate_security_internals ,
argc , argv ) ;
}
2004-08-10 18:27:17 +04:00
/**
2004-08-21 00:13:05 +04:00
* Migrate shares ( including share - definitions , share - acls and files with acls / attrs )
2004-08-10 18:27:17 +04:00
* from one server to another
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
*
* */
static int rpc_share_migrate_all ( int argc , const char * * argv )
{
int ret ;
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2005-06-16 13:36:53 +04:00
/* order is important. we don't want to be locked out by the share-acl
* before copying files - gd */
2004-08-10 18:27:17 +04:00
ret = run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_migrate_shares_internals , argc , argv ) ;
if ( ret )
return ret ;
2005-06-16 13:36:53 +04:00
ret = run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_migrate_files_internals , argc , argv ) ;
2004-08-10 18:27:17 +04:00
if ( ret )
return ret ;
2005-06-16 13:36:53 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_migrate_security_internals , argc , argv ) ;
2004-08-10 18:27:17 +04:00
}
/**
* ' net rpc share migrate ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
static int rpc_share_migrate ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " all " , rpc_share_migrate_all } ,
{ " files " , rpc_share_migrate_files } ,
2004-08-21 00:13:05 +04:00
{ " help " , rpc_share_usage } ,
2005-06-16 13:36:53 +04:00
{ " security " , rpc_share_migrate_security } ,
2004-08-10 18:27:17 +04:00
{ " shares " , rpc_share_migrate_shares } ,
{ NULL , NULL }
} ;
2005-06-24 03:23:16 +04:00
net_mode_share = NET_MODE_SHARE_MIGRATE ;
2005-06-13 01:18:16 +04:00
2004-08-10 18:27:17 +04:00
return net_run_function ( argc , argv , func , rpc_share_usage ) ;
}
2004-10-12 15:58:01 +04:00
struct full_alias {
DOM_SID sid ;
2005-06-16 13:36:53 +04:00
uint32 num_members ;
2004-10-12 15:58:01 +04:00
DOM_SID * members ;
} ;
static int num_server_aliases ;
static struct full_alias * server_aliases ;
/*
* Add an alias to the static list .
*/
static void push_alias ( TALLOC_CTX * mem_ctx , struct full_alias * alias )
{
if ( server_aliases = = NULL )
2004-12-07 21:25:53 +03:00
server_aliases = SMB_MALLOC_ARRAY ( struct full_alias , 100 ) ;
2004-10-12 15:58:01 +04:00
server_aliases [ num_server_aliases ] = * alias ;
num_server_aliases + = 1 ;
}
/*
* For a specific domain on the server , fetch all the aliases
* and their members . Add all of them to the server_aliases .
*/
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_fetch_domain_aliases ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
POLICY_HND * connect_pol ,
const DOM_SID * domain_sid )
2004-10-12 15:58:01 +04:00
{
uint32 start_idx , max_entries , num_entries , i ;
2008-02-12 13:09:23 +03:00
struct samr_SamArray * groups = NULL ;
2004-10-12 15:58:01 +04:00
NTSTATUS result ;
POLICY_HND domain_pol ;
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2004-10-12 15:58:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
start_idx = 0 ;
max_entries = 250 ;
do {
2008-02-12 13:09:23 +03:00
result = rpccli_samr_EnumDomainAliases ( pipe_hnd , mem_ctx ,
& domain_pol ,
& start_idx ,
& groups ,
max_entries ,
& num_entries ) ;
2004-10-12 15:58:01 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
POLICY_HND alias_pol ;
struct full_alias alias ;
2008-02-05 03:18:56 +03:00
struct lsa_SidArray sid_array ;
2004-10-12 15:58:01 +04:00
int j ;
2008-02-01 13:38:29 +03:00
result = rpccli_samr_OpenAlias ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-12 13:09:23 +03:00
groups - > entries [ i ] . idx ,
2008-02-01 13:38:29 +03:00
& alias_pol ) ;
2004-10-12 15:58:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2008-02-05 03:18:56 +03:00
result = rpccli_samr_GetMembersInAlias ( pipe_hnd , mem_ctx ,
& alias_pol ,
& sid_array ) ;
2004-10-12 15:58:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2008-02-05 03:18:56 +03:00
alias . num_members = sid_array . num_sids ;
2008-01-30 14:39:20 +03:00
result = rpccli_samr_Close ( pipe_hnd , mem_ctx , & alias_pol ) ;
2004-10-12 15:58:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
alias . members = NULL ;
if ( alias . num_members > 0 ) {
2004-12-07 21:25:53 +03:00
alias . members = SMB_MALLOC_ARRAY ( DOM_SID , alias . num_members ) ;
2004-10-12 15:58:01 +04:00
for ( j = 0 ; j < alias . num_members ; j + + )
sid_copy ( & alias . members [ j ] ,
2008-02-05 03:18:56 +03:00
sid_array . sids [ j ] . sid ) ;
2004-10-12 15:58:01 +04:00
}
sid_copy ( & alias . sid , domain_sid ) ;
2008-02-12 13:09:23 +03:00
sid_append_rid ( & alias . sid , groups - > entries [ i ] . idx ) ;
2004-10-12 15:58:01 +04:00
push_alias ( mem_ctx , & alias ) ;
}
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
result = NT_STATUS_OK ;
done :
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & domain_pol ) ;
2004-10-12 15:58:01 +04:00
return result ;
}
/*
* Dump server_aliases as names for debugging purposes .
*/
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_aliaslist_dump ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-12 15:58:01 +04:00
{
int i ;
NTSTATUS result ;
POLICY_HND lsa_pol ;
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_open_policy ( pipe_hnd , mem_ctx , True ,
2004-10-12 15:58:01 +04:00
SEC_RIGHTS_MAXIMUM_ALLOWED ,
& lsa_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
for ( i = 0 ; i < num_server_aliases ; i + + ) {
char * * names ;
char * * domains ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types ;
2004-10-12 15:58:01 +04:00
int j ;
struct full_alias * alias = & server_aliases [ i ] ;
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_lookup_sids ( pipe_hnd , mem_ctx , & lsa_pol , 1 ,
2004-10-12 15:58:01 +04:00
& alias - > sid ,
& domains , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
continue ;
DEBUG ( 1 , ( " %s \\ %s %d: " , domains [ 0 ] , names [ 0 ] , types [ 0 ] ) ) ;
if ( alias - > num_members = = 0 ) {
DEBUG ( 1 , ( " \n " ) ) ;
continue ;
}
2005-09-30 21:13:37 +04:00
result = rpccli_lsa_lookup_sids ( pipe_hnd , mem_ctx , & lsa_pol ,
2004-10-12 15:58:01 +04:00
alias - > num_members ,
alias - > members ,
& domains , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) )
continue ;
for ( j = 0 ; j < alias - > num_members ; j + + )
DEBUG ( 1 , ( " %s \\ %s (%d); " ,
domains [ j ] ? domains [ j ] : " *unknown* " ,
names [ j ] ? names [ j ] : " *unknown* " , types [ j ] ) ) ;
DEBUG ( 1 , ( " \n " ) ) ;
}
2006-09-21 02:49:02 +04:00
rpccli_lsa_Close ( pipe_hnd , mem_ctx , & lsa_pol ) ;
2004-10-12 15:58:01 +04:00
return NT_STATUS_OK ;
}
/*
* Fetch a list of all server aliases and their members into
* server_aliases .
*/
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_aliaslist_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-12 15:58:01 +04:00
{
NTSTATUS result ;
POLICY_HND connect_pol ;
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2004-10-12 15:58:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2005-09-30 21:13:37 +04:00
result = rpc_fetch_domain_aliases ( pipe_hnd , mem_ctx , & connect_pol ,
2004-10-12 15:58:01 +04:00
& global_sid_Builtin ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2005-09-30 21:13:37 +04:00
result = rpc_fetch_domain_aliases ( pipe_hnd , mem_ctx , & connect_pol ,
2004-10-12 15:58:01 +04:00
domain_sid ) ;
2008-01-30 14:39:20 +03:00
rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_pol ) ;
2004-10-12 15:58:01 +04:00
done :
return result ;
}
static void init_user_token ( NT_USER_TOKEN * token , DOM_SID * user_sid )
{
token - > num_sids = 4 ;
2007-07-09 12:00:50 +04:00
if ( ! ( token - > user_sids = SMB_MALLOC_ARRAY ( DOM_SID , 4 ) ) ) {
d_fprintf ( stderr , " malloc failed \n " ) ;
token - > num_sids = 0 ;
return ;
}
2004-10-12 15:58:01 +04:00
token - > user_sids [ 0 ] = * user_sid ;
sid_copy ( & token - > user_sids [ 1 ] , & global_sid_World ) ;
sid_copy ( & token - > user_sids [ 2 ] , & global_sid_Network ) ;
sid_copy ( & token - > user_sids [ 3 ] , & global_sid_Authenticated_Users ) ;
}
static void free_user_token ( NT_USER_TOKEN * token )
{
SAFE_FREE ( token - > user_sids ) ;
}
2007-10-19 04:40:25 +04:00
static bool is_sid_in_token ( NT_USER_TOKEN * token , DOM_SID * sid )
2004-10-12 15:58:01 +04:00
{
int i ;
for ( i = 0 ; i < token - > num_sids ; i + + ) {
if ( sid_compare ( sid , & token - > user_sids [ i ] ) = = 0 )
return True ;
}
return False ;
}
static void add_sid_to_token ( NT_USER_TOKEN * token , DOM_SID * sid )
{
if ( is_sid_in_token ( token , sid ) )
return ;
2004-12-07 21:25:53 +03:00
token - > user_sids = SMB_REALLOC_ARRAY ( token - > user_sids , DOM_SID , token - > num_sids + 1 ) ;
r13915: Fixed a very interesting class of realloc() bugs found by Coverity.
realloc can return NULL in one of two cases - (1) the realloc failed,
(2) realloc succeeded but the new size requested was zero, in which
case this is identical to a free() call.
The error paths dealing with these two cases should be different,
but mostly weren't. Secondly the standard idiom for dealing with
realloc when you know the new size is non-zero is the following :
tmp = realloc(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
However, there were *many* *many* places in Samba where we were
using the old (broken) idiom of :
p = realloc(p, size)
if (!p) {
return error;
}
which will leak the memory pointed to by p on realloc fail.
This commit (hopefully) fixes all these cases by moving to
a standard idiom of :
p = SMB_REALLOC(p, size)
if (!p) {
return error;
}
Where if the realloc returns null due to the realloc failing
or size == 0 we *guarentee* that the storage pointed to by p
has been freed. This allows me to remove a lot of code that
was dealing with the standard (more verbose) method that required
a tmp pointer. This is almost always what you want. When a
realloc fails you never usually want the old memory, you
want to free it and get into your error processing asap.
For the 11 remaining cases where we really do need to keep the
old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR,
which can be used as follows :
tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the
pointer p, even on size == 0 or realloc fail. All this is
done by a hidden extra argument to Realloc(), BOOL free_old_on_error
which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR
macros (and their array counterparts).
It remains to be seen what this will do to our Coverity bug count :-).
Jeremy.
(This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0)
2006-03-07 09:31:04 +03:00
if ( ! token - > user_sids ) {
return ;
}
2004-10-12 15:58:01 +04:00
sid_copy ( & token - > user_sids [ token - > num_sids ] , sid ) ;
token - > num_sids + = 1 ;
}
struct user_token {
fstring name ;
NT_USER_TOKEN token ;
} ;
static void dump_user_token ( struct user_token * token )
{
int i ;
d_printf ( " %s \n " , token - > name ) ;
for ( i = 0 ; i < token - > token . num_sids ; i + + ) {
2007-12-15 23:53:26 +03:00
d_printf ( " %s \n " , sid_string_tos ( & token - > token . user_sids [ i ] ) ) ;
2004-10-12 15:58:01 +04:00
}
}
2007-10-19 04:40:25 +04:00
static bool is_alias_member ( DOM_SID * sid , struct full_alias * alias )
2004-10-12 15:58:01 +04:00
{
int i ;
for ( i = 0 ; i < alias - > num_members ; i + + ) {
if ( sid_compare ( sid , & alias - > members [ i ] ) = = 0 )
return True ;
}
return False ;
}
static void collect_sid_memberships ( NT_USER_TOKEN * token , DOM_SID sid )
{
int i ;
for ( i = 0 ; i < num_server_aliases ; i + + ) {
if ( is_alias_member ( & sid , & server_aliases [ i ] ) )
add_sid_to_token ( token , & server_aliases [ i ] . sid ) ;
}
}
/*
* We got a user token with all the SIDs we can know about without asking the
* server directly . These are the user and domain group sids . All of these can
* be members of aliases . So scan the list of aliases for each of the SIDs and
* add them to the token .
*/
static void collect_alias_memberships ( NT_USER_TOKEN * token )
{
int num_global_sids = token - > num_sids ;
int i ;
for ( i = 0 ; i < num_global_sids ; i + + ) {
collect_sid_memberships ( token , token - > user_sids [ i ] ) ;
}
}
2007-10-19 04:40:25 +04:00
static bool get_user_sids ( const char * domain , const char * user , NT_USER_TOKEN * token )
2004-10-12 15:58:01 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
fstring full_name ;
NSS_STATUS result ;
DOM_SID user_sid ;
int i ;
fstr_sprintf ( full_name , " %s%c%s " ,
domain , * lp_winbind_separator ( ) , user ) ;
/* First let's find out the user sid */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
fstrcpy ( request . data . name . dom_name , domain ) ;
fstrcpy ( request . data . name . name , user ) ;
2005-06-25 00:25:18 +04:00
result = winbindd_request_response ( WINBINDD_LOOKUPNAME , & request , & response ) ;
2004-10-12 15:58:01 +04:00
if ( result ! = NSS_STATUS_SUCCESS ) {
DEBUG ( 1 , ( " winbind could not find %s \n " , full_name ) ) ;
return False ;
}
if ( response . data . sid . type ! = SID_NAME_USER ) {
DEBUG ( 1 , ( " %s is not a user \n " , full_name ) ) ;
return False ;
}
string_to_sid ( & user_sid , response . data . sid . sid ) ;
init_user_token ( token , & user_sid ) ;
/* And now the groups winbind knows about */
ZERO_STRUCT ( response ) ;
fstrcpy ( request . data . username , full_name ) ;
2005-06-25 00:25:18 +04:00
result = winbindd_request_response ( WINBINDD_GETGROUPS , & request , & response ) ;
2004-10-12 15:58:01 +04:00
if ( result ! = NSS_STATUS_SUCCESS ) {
DEBUG ( 1 , ( " winbind could not get groups of %s \n " , full_name ) ) ;
return False ;
}
for ( i = 0 ; i < response . data . num_entries ; i + + ) {
2006-04-12 18:10:39 +04:00
gid_t gid = ( ( gid_t * ) response . extra_data . data ) [ i ] ;
2004-10-12 15:58:01 +04:00
DOM_SID sid ;
struct winbindd_request sidrequest ;
struct winbindd_response sidresponse ;
ZERO_STRUCT ( sidrequest ) ;
ZERO_STRUCT ( sidresponse ) ;
sidrequest . data . gid = gid ;
2005-06-25 00:25:18 +04:00
result = winbindd_request_response ( WINBINDD_GID_TO_SID ,
2004-10-12 15:58:01 +04:00
& sidrequest , & sidresponse ) ;
if ( result ! = NSS_STATUS_SUCCESS ) {
DEBUG ( 1 , ( " winbind could not find SID of gid %d \n " ,
gid ) ) ;
return False ;
}
DEBUG ( 3 , ( " %s \n " , sidresponse . data . sid . sid ) ) ;
string_to_sid ( & sid , sidresponse . data . sid . sid ) ;
add_sid_to_token ( token , & sid ) ;
}
2006-04-12 18:10:39 +04:00
SAFE_FREE ( response . extra_data . data ) ;
2004-10-12 15:58:01 +04:00
return True ;
}
/**
* Get a list of all user tokens we want to look at
* */
2005-09-30 21:13:37 +04:00
2007-10-19 04:40:25 +04:00
static bool get_user_tokens ( int * num_tokens , struct user_token * * user_tokens )
2004-10-12 15:58:01 +04:00
{
struct winbindd_request request ;
struct winbindd_response response ;
const char * extra_data ;
2007-12-08 04:32:32 +03:00
char * name ;
2004-10-12 15:58:01 +04:00
int i ;
struct user_token * result ;
2007-12-08 04:32:32 +03:00
TALLOC_CTX * frame = NULL ;
2004-10-12 15:58:01 +04:00
2005-05-18 15:57:53 +04:00
if ( lp_winbind_use_default_domain ( ) & &
( opt_target_workgroup = = NULL ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " winbind use default domain = yes set, "
" please specify a workgroup \n " ) ;
2005-05-18 15:57:53 +04:00
return False ;
}
2004-10-12 15:58:01 +04:00
/* Send request to winbind daemon */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
2007-12-08 04:32:32 +03:00
2005-06-25 00:25:18 +04:00
if ( winbindd_request_response ( WINBINDD_LIST_USERS , & request , & response ) ! =
2004-10-12 15:58:01 +04:00
NSS_STATUS_SUCCESS )
return False ;
/* Look through extra data */
2006-04-12 18:10:39 +04:00
if ( ! response . extra_data . data )
2004-10-12 15:58:01 +04:00
return False ;
2006-04-12 18:10:39 +04:00
extra_data = ( const char * ) response . extra_data . data ;
2004-10-12 15:58:01 +04:00
* num_tokens = 0 ;
2007-12-08 04:32:32 +03:00
frame = talloc_stackframe ( ) ;
while ( next_token_talloc ( frame , & extra_data , & name , " , " ) ) {
2004-10-12 15:58:01 +04:00
* num_tokens + = 1 ;
}
2004-12-07 21:25:53 +03:00
result = SMB_MALLOC_ARRAY ( struct user_token , * num_tokens ) ;
2004-10-12 15:58:01 +04:00
if ( result = = NULL ) {
DEBUG ( 1 , ( " Could not malloc sid array \n " ) ) ;
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
2004-10-12 15:58:01 +04:00
return False ;
}
2006-04-12 18:10:39 +04:00
extra_data = ( const char * ) response . extra_data . data ;
2004-10-12 15:58:01 +04:00
i = 0 ;
2007-12-08 04:32:32 +03:00
while ( next_token_talloc ( frame , & extra_data , & name , " , " ) ) {
2004-10-12 15:58:01 +04:00
fstring domain , user ;
char * p ;
fstrcpy ( result [ i ] . name , name ) ;
p = strchr ( name , * lp_winbind_separator ( ) ) ;
DEBUG ( 3 , ( " %s \n " , name ) ) ;
2005-05-18 15:57:53 +04:00
if ( p = = NULL ) {
fstrcpy ( domain , opt_target_workgroup ) ;
fstrcpy ( user , name ) ;
} else {
* p + + = ' \0 ' ;
fstrcpy ( domain , name ) ;
strupper_m ( domain ) ;
fstrcpy ( user , p ) ;
}
2004-10-12 15:58:01 +04:00
get_user_sids ( domain , user , & ( result [ i ] . token ) ) ;
i + = 1 ;
}
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
2006-04-12 18:10:39 +04:00
SAFE_FREE ( response . extra_data . data ) ;
2004-10-12 15:58:01 +04:00
* user_tokens = result ;
return True ;
}
2007-10-19 04:40:25 +04:00
static bool get_user_tokens_from_file ( FILE * f ,
2004-10-12 15:58:01 +04:00
int * num_tokens ,
struct user_token * * tokens )
{
struct user_token * token = NULL ;
while ( ! feof ( f ) ) {
fstring line ;
if ( fgets ( line , sizeof ( line ) - 1 , f ) = = NULL ) {
return True ;
}
if ( line [ strlen ( line ) - 1 ] = = ' \n ' )
line [ strlen ( line ) - 1 ] = ' \0 ' ;
if ( line [ 0 ] = = ' ' ) {
/* We have a SID */
DOM_SID sid ;
string_to_sid ( & sid , & line [ 1 ] ) ;
if ( token = = NULL ) {
DEBUG ( 0 , ( " File does not begin with username " ) ) ;
return False ;
}
add_sid_to_token ( & token - > token , & sid ) ;
continue ;
}
/* And a new user... */
* num_tokens + = 1 ;
2004-12-07 21:25:53 +03:00
* tokens = SMB_REALLOC_ARRAY ( * tokens , struct user_token , * num_tokens ) ;
2004-10-12 15:58:01 +04:00
if ( * tokens = = NULL ) {
DEBUG ( 0 , ( " Could not realloc tokens \n " ) ) ;
return False ;
}
token = & ( ( * tokens ) [ * num_tokens - 1 ] ) ;
fstrcpy ( token - > name , line ) ;
token - > token . num_sids = 0 ;
token - > token . user_sids = NULL ;
continue ;
}
return False ;
}
/*
* Show the list of all users that have access to a share
*/
2005-09-30 21:13:37 +04:00
static void show_userlist ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
const char * netname ,
int num_tokens ,
struct user_token * tokens )
2004-10-12 15:58:01 +04:00
{
int fnum ;
SEC_DESC * share_sd = NULL ;
SEC_DESC * root_sd = NULL ;
2005-09-30 21:13:37 +04:00
struct cli_state * cli = pipe_hnd - > cli ;
2004-10-12 15:58:01 +04:00
int i ;
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO info ;
WERROR result ;
2004-10-12 15:58:01 +04:00
uint16 cnum ;
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_get_info ( pipe_hnd , mem_ctx , netname ,
2004-10-12 15:58:01 +04:00
502 , & info ) ;
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2004-10-12 15:58:01 +04:00
DEBUG ( 1 , ( " Coult not query secdesc for share %s \n " ,
netname ) ) ;
return ;
}
2007-10-11 00:34:30 +04:00
share_sd = info . share . info502 . info_502_str . sd ;
2004-10-12 15:58:01 +04:00
if ( share_sd = = NULL ) {
DEBUG ( 1 , ( " Got no secdesc for share %s \n " ,
netname ) ) ;
}
cnum = cli - > cnum ;
if ( ! cli_send_tconX ( cli , netname , " A: " , " " , 0 ) ) {
return ;
}
fnum = cli_nt_create ( cli , " \\ " , READ_CONTROL_ACCESS ) ;
if ( fnum ! = - 1 ) {
root_sd = cli_query_secdesc ( cli , fnum , mem_ctx ) ;
}
for ( i = 0 ; i < num_tokens ; i + + ) {
uint32 acc_granted ;
NTSTATUS status ;
if ( share_sd ! = NULL ) {
if ( ! se_access_check ( share_sd , & tokens [ i ] . token ,
1 , & acc_granted , & status ) ) {
DEBUG ( 1 , ( " Could not check share_sd for "
" user %s \n " ,
tokens [ i ] . name ) ) ;
continue ;
}
if ( ! NT_STATUS_IS_OK ( status ) )
continue ;
}
if ( root_sd = = NULL ) {
d_printf ( " %s \n " , tokens [ i ] . name ) ;
continue ;
}
if ( ! se_access_check ( root_sd , & tokens [ i ] . token ,
1 , & acc_granted , & status ) ) {
DEBUG ( 1 , ( " Could not check root_sd for user %s \n " ,
tokens [ i ] . name ) ) ;
continue ;
}
if ( ! NT_STATUS_IS_OK ( status ) )
continue ;
d_printf ( " %s \n " , tokens [ i ] . name ) ;
}
if ( fnum ! = - 1 )
cli_close ( cli , fnum ) ;
cli_tdis ( cli ) ;
cli - > cnum = cnum ;
return ;
}
struct share_list {
int num_shares ;
char * * shares ;
} ;
static void collect_share ( const char * name , uint32 m ,
const char * comment , void * state )
{
struct share_list * share_list = ( struct share_list * ) state ;
if ( m ! = STYPE_DISKTREE )
return ;
share_list - > num_shares + = 1 ;
2004-12-07 21:25:53 +03:00
share_list - > shares = SMB_REALLOC_ARRAY ( share_list - > shares , char * , share_list - > num_shares ) ;
r13915: Fixed a very interesting class of realloc() bugs found by Coverity.
realloc can return NULL in one of two cases - (1) the realloc failed,
(2) realloc succeeded but the new size requested was zero, in which
case this is identical to a free() call.
The error paths dealing with these two cases should be different,
but mostly weren't. Secondly the standard idiom for dealing with
realloc when you know the new size is non-zero is the following :
tmp = realloc(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
However, there were *many* *many* places in Samba where we were
using the old (broken) idiom of :
p = realloc(p, size)
if (!p) {
return error;
}
which will leak the memory pointed to by p on realloc fail.
This commit (hopefully) fixes all these cases by moving to
a standard idiom of :
p = SMB_REALLOC(p, size)
if (!p) {
return error;
}
Where if the realloc returns null due to the realloc failing
or size == 0 we *guarentee* that the storage pointed to by p
has been freed. This allows me to remove a lot of code that
was dealing with the standard (more verbose) method that required
a tmp pointer. This is almost always what you want. When a
realloc fails you never usually want the old memory, you
want to free it and get into your error processing asap.
For the 11 remaining cases where we really do need to keep the
old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR,
which can be used as follows :
tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the
pointer p, even on size == 0 or realloc fail. All this is
done by a hidden extra argument to Realloc(), BOOL free_old_on_error
which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR
macros (and their array counterparts).
It remains to be seen what this will do to our Coverity bug count :-).
Jeremy.
(This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0)
2006-03-07 09:31:04 +03:00
if ( ! share_list - > shares ) {
share_list - > num_shares = 0 ;
return ;
}
2004-12-07 21:25:53 +03:00
share_list - > shares [ share_list - > num_shares - 1 ] = SMB_STRDUP ( name ) ;
2004-10-12 15:58:01 +04:00
}
static void rpc_share_userlist_usage ( void )
{
return ;
}
/**
* List shares on a remote RPC server , including the security descriptors
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_share_allowedusers_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-12 15:58:01 +04:00
{
int ret ;
2007-10-19 04:40:25 +04:00
bool r ;
2007-10-11 00:34:30 +04:00
ENUM_HND hnd ;
2004-10-12 15:58:01 +04:00
uint32 i ;
FILE * f ;
struct user_token * tokens = NULL ;
int num_tokens = 0 ;
struct share_list share_list ;
if ( argc > 1 ) {
rpc_share_userlist_usage ( ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( argc = = 0 ) {
f = stdin ;
} else {
f = fopen ( argv [ 0 ] , " r " ) ;
}
if ( f = = NULL ) {
DEBUG ( 0 , ( " Could not open userlist: %s \n " , strerror ( errno ) ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
r = get_user_tokens_from_file ( f , & num_tokens , & tokens ) ;
if ( f ! = stdin )
fclose ( f ) ;
if ( ! r ) {
DEBUG ( 0 , ( " Could not read users from file \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
for ( i = 0 ; i < num_tokens ; i + + )
collect_alias_memberships ( & tokens [ i ] . token ) ;
2007-10-11 00:34:30 +04:00
init_enum_hnd ( & hnd , 0 ) ;
2004-10-12 15:58:01 +04:00
share_list . num_shares = 0 ;
share_list . shares = NULL ;
ret = cli_RNetShareEnum ( cli , collect_share , & share_list ) ;
if ( ret = = - 1 ) {
DEBUG ( 0 , ( " Error returning browse list: %s \n " ,
cli_errstr ( cli ) ) ) ;
goto done ;
}
for ( i = 0 ; i < share_list . num_shares ; i + + ) {
char * netname = share_list . shares [ i ] ;
if ( netname [ strlen ( netname ) - 1 ] = = ' $ ' )
continue ;
d_printf ( " %s \n " , netname ) ;
2005-09-30 21:13:37 +04:00
show_userlist ( pipe_hnd , mem_ctx , netname ,
2004-10-12 15:58:01 +04:00
num_tokens , tokens ) ;
}
done :
for ( i = 0 ; i < num_tokens ; i + + ) {
free_user_token ( & tokens [ i ] . token ) ;
}
SAFE_FREE ( tokens ) ;
SAFE_FREE ( share_list . shares ) ;
return NT_STATUS_OK ;
}
2005-09-30 21:13:37 +04:00
static int rpc_share_allowedusers ( int argc , const char * * argv )
2004-10-12 15:58:01 +04:00
{
int result ;
result = run_rpc_command ( NULL , PI_SAMR , 0 ,
rpc_aliaslist_internals ,
argc , argv ) ;
if ( result ! = 0 )
return result ;
result = run_rpc_command ( NULL , PI_LSARPC , 0 ,
rpc_aliaslist_dump ,
argc , argv ) ;
if ( result ! = 0 )
return result ;
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
rpc_share_allowedusers_internals ,
argc , argv ) ;
}
int net_usersidlist ( int argc , const char * * argv )
{
int num_tokens = 0 ;
struct user_token * tokens = NULL ;
int i ;
if ( argc ! = 0 ) {
net_usersidlist_usage ( argc , argv ) ;
return 0 ;
}
if ( ! get_user_tokens ( & num_tokens , & tokens ) ) {
DEBUG ( 0 , ( " Could not get the user/sid list \n " ) ) ;
return 0 ;
}
for ( i = 0 ; i < num_tokens ; i + + ) {
dump_user_token ( & tokens [ i ] ) ;
free_user_token ( & tokens [ i ] . token ) ;
}
SAFE_FREE ( tokens ) ;
return 1 ;
}
int net_usersidlist_usage ( int argc , const char * * argv )
{
d_printf ( " net usersidlist \n "
" \t prints out a list of all users the running winbind knows \n "
" \t about, together with all their SIDs. This is used as \n "
" \t input to the 'net rpc share allowedusers' command. \n \n " ) ;
net_common_flags_usage ( argc , argv ) ;
return - 1 ;
}
2002-07-15 14:35:28 +04:00
/**
* ' net rpc share ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
int net_rpc_share ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " add " , rpc_share_add } ,
{ " delete " , rpc_share_delete } ,
2004-10-12 15:58:01 +04:00
{ " allowedusers " , rpc_share_allowedusers } ,
2004-08-10 18:27:17 +04:00
{ " migrate " , rpc_share_migrate } ,
2005-06-16 13:36:53 +04:00
{ " list " , rpc_share_list } ,
2002-07-15 14:35:28 +04:00
{ NULL , NULL }
} ;
if ( argc = = 0 )
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_share_list_internals ,
argc , argv ) ;
return net_run_function ( argc , argv , func , rpc_share_usage ) ;
}
2006-02-04 01:19:41 +03:00
static NTSTATUS rpc_sh_share_list ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
return rpc_share_list_internals ( ctx - > domain_sid , ctx - > domain_name ,
ctx - > cli , pipe_hnd , mem_ctx ,
argc , argv ) ;
}
static NTSTATUS rpc_sh_share_add ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2006-02-04 01:19:41 +03:00
if ( ( argc < 2 ) | | ( argc > 3 ) ) {
d_fprintf ( stderr , " usage: %s <share> <path> [comment] \n " ,
ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_add (
pipe_hnd , mem_ctx , argv [ 0 ] , STYPE_DISKTREE ,
( argc = = 3 ) ? argv [ 2 ] : " " ,
0 , 0 , 0 , argv [ 1 ] , NULL , 2 , NULL ) ;
2006-02-04 01:19:41 +03:00
2007-10-11 00:34:30 +04:00
return werror_to_ntstatus ( result ) ;
2006-02-04 01:19:41 +03:00
}
static NTSTATUS rpc_sh_share_delete ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
2007-10-11 00:34:30 +04:00
WERROR result ;
2006-02-04 01:19:41 +03:00
if ( argc ! = 1 ) {
d_fprintf ( stderr , " usage: %s <share> \n " , ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_del ( pipe_hnd , mem_ctx , argv [ 0 ] ) ;
return werror_to_ntstatus ( result ) ;
2006-02-04 01:19:41 +03:00
}
static NTSTATUS rpc_sh_share_info ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx ,
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
2007-10-11 00:34:30 +04:00
SRV_SHARE_INFO info ;
SRV_SHARE_INFO_2 * info2 = & info . share . info2 ;
WERROR result ;
2006-02-04 01:19:41 +03:00
if ( argc ! = 1 ) {
d_fprintf ( stderr , " usage: %s <share> \n " , ctx - > whoami ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_share_get_info (
pipe_hnd , mem_ctx , argv [ 0 ] , 2 , & info ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
2006-02-04 01:19:41 +03:00
goto done ;
}
2007-10-11 00:34:30 +04:00
d_printf ( " Name: %s \n " ,
rpcstr_pull_unistr2_talloc ( mem_ctx ,
& info2 - > info_2_str . uni_netname ) ) ;
d_printf ( " Comment: %s \n " ,
rpcstr_pull_unistr2_talloc ( mem_ctx ,
& info2 - > info_2_str . uni_remark ) ) ;
d_printf ( " Path: %s \n " ,
rpcstr_pull_unistr2_talloc ( mem_ctx ,
& info2 - > info_2_str . uni_path ) ) ;
d_printf ( " Password: %s \n " ,
rpcstr_pull_unistr2_talloc ( mem_ctx ,
& info2 - > info_2_str . uni_passwd ) ) ;
2006-02-04 01:19:41 +03:00
done :
2007-10-11 00:34:30 +04:00
return werror_to_ntstatus ( result ) ;
2006-02-04 01:19:41 +03:00
}
struct rpc_sh_cmd * net_rpc_share_cmds ( TALLOC_CTX * mem_ctx ,
struct rpc_sh_ctx * ctx )
{
static struct rpc_sh_cmd cmds [ ] = {
{ " list " , NULL , PI_SRVSVC , rpc_sh_share_list ,
" List available shares " } ,
{ " add " , NULL , PI_SRVSVC , rpc_sh_share_add ,
" Add a share " } ,
{ " delete " , NULL , PI_SRVSVC , rpc_sh_share_delete ,
" Delete a share " } ,
{ " info " , NULL , PI_SRVSVC , rpc_sh_share_info ,
" Get information about a share " } ,
{ NULL , NULL , 0 , NULL , NULL }
} ;
return cmds ;
2006-05-17 15:14:26 +04:00
}
2006-02-04 01:19:41 +03:00
2002-07-15 14:35:28 +04:00
/****************************************************************************/
static int rpc_file_usage ( int argc , const char * * argv )
{
return net_help_file ( argc , argv ) ;
}
/**
* Close a file on a remote RPC server
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_file_close_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
return rpccli_srvsvc_NetFileClose ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
2007-12-03 20:25:13 +03:00
atoi ( argv [ 0 ] ) , NULL ) ;
2002-07-15 14:35:28 +04:00
}
/**
* Close a file on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_file_close ( int argc , const char * * argv )
{
if ( argc < 1 ) {
DEBUG ( 1 , ( " No fileid given on close \n " ) ) ;
return ( rpc_file_usage ( argc , argv ) ) ;
}
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_file_close_internals ,
argc , argv ) ;
}
/**
* Formatted print of open file info
*
* @ param info3 FILE_INFO_3 contents
* @ param str3 strings for FILE_INFO_3
* */
2007-10-11 00:34:30 +04:00
static void display_file_info_3 ( FILE_INFO_3 * info3 )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
fstring user = " " , path = " " ;
rpcstr_pull_unistr2_fstring ( user , info3 - > user ) ;
rpcstr_pull_unistr2_fstring ( path , info3 - > path ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " %-7.1d %-20.20s 0x%-4.2x %-6.1d %s \n " ,
2007-10-11 00:34:30 +04:00
info3 - > id , user , info3 - > perms , info3 - > num_locks , path ) ;
2002-07-15 14:35:28 +04:00
}
/**
* List open files on a remote RPC server
2001-12-31 16:00:59 +03:00
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2002-07-15 14:35:28 +04:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid acquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_file_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-07-15 14:35:28 +04:00
{
2007-10-11 00:34:30 +04:00
SRV_FILE_INFO_CTR ctr ;
WERROR result ;
ENUM_HND hnd ;
2002-07-15 14:35:28 +04:00
uint32 preferred_len = 0xffffffff , i ;
2002-08-17 18:45:04 +04:00
const char * username = NULL ;
2002-07-15 14:35:28 +04:00
2007-10-11 00:34:30 +04:00
init_enum_hnd ( & hnd , 0 ) ;
2002-07-15 14:35:28 +04:00
/* if argc > 0, must be user command */
if ( argc > 0 )
2002-08-17 18:45:04 +04:00
username = smb_xstrdup ( argv [ 0 ] ) ;
2002-07-15 14:35:28 +04:00
2007-10-11 00:34:30 +04:00
result = rpccli_srvsvc_net_file_enum ( pipe_hnd ,
mem_ctx , 3 , username , & ctr , preferred_len , & hnd ) ;
2002-07-15 14:35:28 +04:00
2007-10-11 00:34:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
2002-07-15 14:35:28 +04:00
goto done ;
/* Display results */
d_printf (
" \n Enumerating open files on remote server: \n \n " \
" \n FileId Opened by Perms Locks Path " \
" \n ------ --------- ----- ----- ---- \n " ) ;
2007-10-11 00:34:30 +04:00
for ( i = 0 ; i < ctr . num_entries ; i + + )
display_file_info_3 ( & ctr . file . info3 [ i ] ) ;
2002-07-15 14:35:28 +04:00
done :
2007-10-11 00:34:30 +04:00
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
}
/**
* List files for a user on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
2005-09-30 21:13:37 +04:00
2002-07-15 14:35:28 +04:00
static int rpc_file_user ( int argc , const char * * argv )
{
if ( argc < 1 ) {
DEBUG ( 1 , ( " No username given \n " ) ) ;
return ( rpc_file_usage ( argc , argv ) ) ;
}
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_file_list_internals ,
argc , argv ) ;
}
/**
* ' net rpc file ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
int net_rpc_file ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " close " , rpc_file_close } ,
{ " user " , rpc_file_user } ,
#if 0
{ " info " , rpc_file_info } ,
# endif
{ NULL , NULL }
} ;
if ( argc = = 0 )
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SRVSVC , 0 ,
2002-07-15 14:35:28 +04:00
rpc_file_list_internals ,
argc , argv ) ;
return net_run_function ( argc , argv , func , rpc_file_usage ) ;
}
/**
2003-10-24 18:03:18 +04:00
* ABORT the shutdown of a remote RPC Server over , initshutdown pipe
2002-07-15 14:35:28 +04:00
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2001-12-31 16:00:59 +03:00
* argc , argv which are passed through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
2002-07-15 14:35:28 +04:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-31 16:00:59 +03:00
* stripped
*
* @ return Normal NTSTATUS return .
* */
2003-10-24 18:03:18 +04:00
static NTSTATUS rpc_shutdown_abort_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2001-12-31 16:00:59 +03:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2007-12-03 20:40:36 +03:00
result = rpccli_initshutdown_Abort ( pipe_hnd , mem_ctx , NULL , NULL ) ;
2003-10-24 18:03:18 +04:00
2004-11-15 23:57:27 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
d_printf ( " \n Shutdown successfully aborted \n " ) ;
2003-10-24 18:03:18 +04:00
DEBUG ( 5 , ( " cmd_shutdown_abort: query succeeded \n " ) ) ;
2004-11-15 23:57:27 +03:00
} else
2003-10-24 18:03:18 +04:00
DEBUG ( 5 , ( " cmd_shutdown_abort: query failed \n " ) ) ;
return result ;
}
/**
* ABORT the shutdown of a remote RPC Server , over winreg pipe
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passed through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
static NTSTATUS rpc_reg_shutdown_abort_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2003-10-24 18:03:18 +04:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2007-12-03 20:40:36 +03:00
result = rpccli_winreg_AbortSystemShutdown ( pipe_hnd , mem_ctx , NULL , NULL ) ;
2001-12-31 16:00:59 +03:00
2004-11-15 23:57:27 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
d_printf ( " \n Shutdown successfully aborted \n " ) ;
2001-12-31 16:00:59 +03:00
DEBUG ( 5 , ( " cmd_reg_abort_shutdown: query succeeded \n " ) ) ;
2004-11-15 23:57:27 +03:00
} else
2001-12-31 16:00:59 +03:00
DEBUG ( 5 , ( " cmd_reg_abort_shutdown: query failed \n " ) ) ;
return result ;
}
/**
* ABORT the Shut down of a remote RPC server
*
* @ param argc Standard main ( ) style argc
2002-07-15 14:35:28 +04:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-31 16:00:59 +03:00
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_shutdown_abort ( int argc , const char * * argv )
{
2006-09-15 22:32:43 +04:00
int rc = run_rpc_command ( NULL , PI_INITSHUTDOWN , 0 ,
2003-10-24 18:03:18 +04:00
rpc_shutdown_abort_internals ,
argc , argv ) ;
if ( rc = = 0 )
return rc ;
DEBUG ( 1 , ( " initshutdown pipe didn't work, trying winreg pipe \n " ) ) ;
return run_rpc_command ( NULL , PI_WINREG , 0 ,
rpc_reg_shutdown_abort_internals ,
2001-12-31 16:00:59 +03:00
argc , argv ) ;
}
/**
2004-11-15 23:57:27 +03:00
* Shut down a remote RPC Server via initshutdown pipe
2001-12-31 16:00:59 +03:00
*
2002-09-25 19:19:00 +04:00
* All parameters are provided by the run_rpc_command function , except for
2001-12-31 16:00:59 +03:00
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2007-12-03 13:07:27 +03:00
NTSTATUS rpc_init_shutdown_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-11-15 23:57:27 +03:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
const char * msg = " This machine will be shutdown shortly " ;
uint32 timeout = 20 ;
2006-09-26 19:15:26 +04:00
struct initshutdown_String msg_string ;
struct initshutdown_String_sub s ;
2004-11-15 23:57:27 +03:00
if ( opt_comment ) {
msg = opt_comment ;
}
if ( opt_timeout ) {
timeout = opt_timeout ;
}
2006-09-26 19:15:26 +04:00
s . name = msg ;
msg_string . name = & s ;
2004-11-15 23:57:27 +03:00
/* create an entry */
2006-09-26 19:15:26 +04:00
result = rpccli_initshutdown_Init ( pipe_hnd , mem_ctx , NULL ,
2007-12-03 20:40:36 +03:00
& msg_string , timeout , opt_force , opt_reboot , NULL ) ;
2004-11-15 23:57:27 +03:00
if ( NT_STATUS_IS_OK ( result ) ) {
d_printf ( " \n Shutdown of remote machine succeeded \n " ) ;
DEBUG ( 5 , ( " Shutdown of remote machine succeeded \n " ) ) ;
2005-10-11 22:42:25 +04:00
} else {
DEBUG ( 1 , ( " Shutdown of remote machine failed! \n " ) ) ;
}
2004-11-15 23:57:27 +03:00
return result ;
}
/**
* Shut down a remote RPC Server via winreg pipe
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passes through .
*
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2007-12-03 13:07:27 +03:00
NTSTATUS rpc_reg_shutdown_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2001-12-31 16:00:59 +03:00
{
2003-01-03 11:28:12 +03:00
const char * msg = " This machine will be shutdown shortly " ;
2001-12-31 16:00:59 +03:00
uint32 timeout = 20 ;
2006-09-26 19:15:26 +04:00
struct initshutdown_String msg_string ;
struct initshutdown_String_sub s ;
NTSTATUS result ;
2007-12-03 20:40:36 +03:00
WERROR werr ;
2001-12-31 16:00:59 +03:00
if ( opt_comment ) {
msg = opt_comment ;
}
2006-09-26 19:15:26 +04:00
s . name = msg ;
msg_string . name = & s ;
2001-12-31 16:00:59 +03:00
if ( opt_timeout ) {
timeout = opt_timeout ;
}
/* create an entry */
2006-09-26 19:15:26 +04:00
result = rpccli_winreg_InitiateSystemShutdown ( pipe_hnd , mem_ctx , NULL ,
2007-12-03 20:40:36 +03:00
& msg_string , timeout , opt_force , opt_reboot , & werr ) ;
2001-12-31 16:00:59 +03:00
2006-09-26 19:15:26 +04:00
if ( NT_STATUS_IS_OK ( result ) ) {
2004-11-15 23:57:27 +03:00
d_printf ( " \n Shutdown of remote machine succeeded \n " ) ;
2005-10-11 22:42:25 +04:00
} else {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " \n Shutdown of remote machine failed \n " ) ;
2007-12-03 20:40:36 +03:00
if ( W_ERROR_EQUAL ( werr , WERR_MACHINE_LOCKED ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " \n Machine locked, use -f switch to force \n " ) ;
2005-10-11 22:42:25 +04:00
else
2007-12-03 20:40:36 +03:00
d_fprintf ( stderr , " \n result was: %s \n " , dos_errstr ( werr ) ) ;
2004-11-15 23:57:27 +03:00
}
2001-12-31 16:00:59 +03:00
2006-09-26 19:15:26 +04:00
return result ;
2001-12-31 16:00:59 +03:00
}
/**
* Shut down a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_shutdown ( int argc , const char * * argv )
{
2006-09-15 22:32:43 +04:00
int rc = run_rpc_command ( NULL , PI_INITSHUTDOWN , 0 ,
2004-11-15 23:57:27 +03:00
rpc_init_shutdown_internals ,
argc , argv ) ;
2005-10-11 22:42:25 +04:00
if ( rc ) {
DEBUG ( 1 , ( " initshutdown pipe failed, trying winreg pipe \n " ) ) ;
rc = run_rpc_command ( NULL , PI_WINREG , 0 ,
rpc_reg_shutdown_internals , argc , argv ) ;
}
2004-11-15 23:57:27 +03:00
2005-10-11 22:42:25 +04:00
return rc ;
2001-12-31 16:00:59 +03:00
}
2002-03-01 05:56:35 +03:00
/***************************************************************************
NT Domain trusts code ( i . e . ' net rpc trustdom ' functionality )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* Add interdomain trust account to the RPC server .
* All parameters ( except for argc and argv ) are passed by run_rpc_command
* function .
*
* @ param domain_sid The domain sid acquired from the server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return normal NTSTATUS return code
*/
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_trustdom_add_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2002-03-01 05:56:35 +03:00
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
char * acct_name ;
2008-02-01 16:21:54 +03:00
struct lsa_String lsa_acct_name ;
2006-02-27 13:32:45 +03:00
uint32 acb_info ;
2008-01-24 00:54:02 +03:00
uint32 acct_flags = 0 ;
uint32 user_rid ;
2008-02-01 16:21:54 +03:00
uint32_t access_granted = 0 ;
2008-02-12 22:01:36 +03:00
union samr_UserInfo info ;
2002-03-01 05:56:35 +03:00
2003-05-11 20:59:06 +04:00
if ( argc ! = 2 ) {
d_printf ( " Usage: net rpc trustdom add <domain_name> <pw> \n " ) ;
2002-07-15 14:35:28 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2002-03-01 05:56:35 +03:00
}
/*
* Make valid trusting domain account ( ie . uppercased and with ' $ ' appended )
*/
2008-02-01 16:21:54 +03:00
2002-03-01 05:56:35 +03:00
if ( asprintf ( & acct_name , " %s$ " , argv [ 0 ] ) < 0 ) {
return NT_STATUS_NO_MEMORY ;
}
2003-07-03 23:11:31 +04:00
strupper_m ( acct_name ) ;
2002-03-01 05:56:35 +03:00
2008-02-01 16:21:54 +03:00
init_lsa_String ( & lsa_acct_name , acct_name ) ;
2002-08-17 18:45:04 +04:00
/* Get samr policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2002-03-01 05:56:35 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
2002-03-01 05:56:35 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2002-03-01 05:56:35 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Create trusting domain's account */
2008-01-25 03:00:51 +03:00
acb_info = ACB_NORMAL ;
acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
SEC_STD_WRITE_DAC | SEC_STD_DELETE |
SAMR_USER_ACCESS_SET_PASSWORD |
SAMR_USER_ACCESS_GET_ATTRIBUTES |
SAMR_USER_ACCESS_SET_ATTRIBUTES ;
2002-03-01 05:56:35 +03:00
2008-02-01 16:21:54 +03:00
result = rpccli_samr_CreateUser2 ( pipe_hnd , mem_ctx ,
& domain_pol ,
& lsa_acct_name ,
acb_info ,
acct_flags ,
& user_pol ,
& access_granted ,
& user_rid ) ;
2002-03-01 05:56:35 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2003-05-11 20:59:06 +04:00
{
2005-02-26 18:26:55 +03:00
NTTIME notime ;
2008-02-12 22:01:36 +03:00
struct samr_LogonHours hours ;
const int units_per_week = 168 ;
2003-05-11 20:59:06 +04:00
uchar pwbuf [ 516 ] ;
2005-10-18 07:24:00 +04:00
encode_pw_buffer ( pwbuf , argv [ 1 ] , STR_UNICODE ) ;
2003-05-11 20:59:06 +04:00
2005-02-26 18:26:55 +03:00
ZERO_STRUCT ( notime ) ;
2008-02-12 22:01:36 +03:00
ZERO_STRUCT ( hours ) ;
hours . bits = talloc_array ( mem_ctx , uint8_t , units_per_week ) ;
if ( ! hours . bits ) {
result = NT_STATUS_NO_MEMORY ;
goto done ;
}
hours . units_per_week = units_per_week ;
memset ( hours . bits , 0xFF , units_per_week ) ;
init_samr_user_info23 ( & info . info23 ,
notime , notime , notime ,
notime , notime , notime ,
NULL , NULL , NULL , NULL , NULL ,
NULL , NULL , NULL , NULL , NULL ,
0 , 0 , ACB_DOMTRUST , SAMR_FIELD_ACCT_FLAGS ,
hours ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
pwbuf , 24 ) ;
SamOEMhashBlob ( info . info23 . password . data , 516 ,
& cli - > user_session_key ) ;
result = rpccli_samr_SetUserInfo2 ( pipe_hnd , mem_ctx ,
& user_pol ,
23 ,
& info ) ;
2003-05-11 20:59:06 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2003-05-12 03:49:36 +04:00
DEBUG ( 0 , ( " Could not set trust account password: %s \n " ,
2003-05-11 20:59:06 +04:00
nt_errstr ( result ) ) ) ;
goto done ;
}
}
2002-03-01 05:56:35 +03:00
done :
SAFE_FREE ( acct_name ) ;
return result ;
}
/**
* Create interdomain trust account for a remote domain .
*
* @ param argc standard argc
* @ param argv standard argv without initial components
*
* @ return Integer status ( 0 means success )
* */
static int rpc_trustdom_add ( int argc , const char * * argv )
{
2003-08-16 01:57:59 +04:00
if ( argc > 0 ) {
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_trustdom_add_internals ,
argc , argv ) ;
} else {
d_printf ( " Usage: net rpc trustdom add <domain> \n " ) ;
return - 1 ;
}
2002-03-01 05:56:35 +03:00
}
2005-06-09 02:10:34 +04:00
2005-02-28 13:55:13 +03:00
/**
2005-02-28 14:17:13 +03:00
* Remove interdomain trust account from the RPC server .
2005-02-28 13:55:13 +03:00
* All parameters ( except for argc and argv ) are passed by run_rpc_command
* function .
*
* @ param domain_sid The domain sid acquired from the server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on completion of the function .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return normal NTSTATUS return code
*/
static NTSTATUS rpc_trustdom_del_internals ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2005-02-28 13:55:13 +03:00
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
char * acct_name ;
DOM_SID trust_acct_sid ;
2008-02-08 16:50:04 +03:00
struct samr_Ids user_rids , name_types ;
struct lsa_String lsa_acct_name ;
2005-02-28 13:55:13 +03:00
if ( argc ! = 1 ) {
d_printf ( " Usage: net rpc trustdom del <domain_name> \n " ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
/*
* Make valid trusting domain account ( ie . uppercased and with ' $ ' appended )
*/
2005-03-22 18:45:38 +03:00
acct_name = talloc_asprintf ( mem_ctx , " %s$ " , argv [ 0 ] ) ;
if ( acct_name = = NULL )
2005-02-28 13:55:13 +03:00
return NT_STATUS_NO_MEMORY ;
strupper_m ( acct_name ) ;
/* Get samr policy handle */
2008-02-04 21:43:07 +03:00
result = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:12:05 +03:00
2005-02-28 13:55:13 +03:00
/* Get domain policy handle */
2008-02-01 13:12:05 +03:00
result = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
CONST_DISCARD ( struct dom_sid2 * , domain_sid ) ,
& domain_pol ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-08 16:50:04 +03:00
init_lsa_String ( & lsa_acct_name , acct_name ) ;
result = rpccli_samr_LookupNames ( pipe_hnd , mem_ctx ,
& domain_pol ,
1 ,
& lsa_acct_name ,
& user_rids ,
& name_types ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2008-02-01 13:57:53 +03:00
result = rpccli_samr_OpenUser ( pipe_hnd , mem_ctx ,
& domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
2008-02-08 16:50:04 +03:00
user_rids . ids [ 0 ] ,
2008-02-01 13:57:53 +03:00
& user_pol ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* append the rid to the domain sid */
sid_copy ( & trust_acct_sid , domain_sid ) ;
2008-02-08 16:50:04 +03:00
if ( ! sid_append_rid ( & trust_acct_sid , user_rids . ids [ 0 ] ) ) {
2005-02-28 13:55:13 +03:00
goto done ;
}
/* remove the sid */
2008-02-05 13:21:07 +03:00
result = rpccli_samr_RemoveMemberFromForeignDomain ( pipe_hnd , mem_ctx ,
& user_pol ,
& trust_acct_sid ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Delete user */
2008-02-01 03:26:36 +03:00
result = rpccli_samr_DeleteUser ( pipe_hnd , mem_ctx ,
& user_pol ) ;
2005-02-28 13:55:13 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 0 , ( " Could not set trust account password: %s \n " ,
nt_errstr ( result ) ) ) ;
goto done ;
}
done :
return result ;
}
2002-03-01 05:56:35 +03:00
/**
* Delete interdomain trust account for a remote domain .
*
* @ param argc standard argc
* @ param argv standard argv without initial components
*
* @ return Integer status ( 0 means success )
* */
2005-02-28 13:55:13 +03:00
2002-03-01 05:56:35 +03:00
static int rpc_trustdom_del ( int argc , const char * * argv )
{
2005-02-28 13:55:13 +03:00
if ( argc > 0 ) {
return run_rpc_command ( NULL , PI_SAMR , 0 , rpc_trustdom_del_internals ,
argc , argv ) ;
} else {
d_printf ( " Usage: net rpc trustdom del <domain> \n " ) ;
return - 1 ;
}
2002-03-01 05:56:35 +03:00
}
2005-06-09 02:10:34 +04:00
2002-03-01 05:56:35 +03:00
/**
* Establish trust relationship to a trusting domain .
* Interdomain account must already be created on remote PDC .
*
* @ param argc standard argc
* @ param argv standard argv without initial components
*
* @ return Integer status ( 0 means success )
* */
2002-08-17 18:45:04 +04:00
static int rpc_trustdom_establish ( int argc , const char * * argv )
{
2005-09-30 21:13:37 +04:00
struct cli_state * cli = NULL ;
2007-10-25 01:16:54 +04:00
struct sockaddr_storage server_ss ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2002-03-01 05:56:35 +03:00
POLICY_HND connect_hnd ;
TALLOC_CTX * mem_ctx ;
NTSTATUS nt_status ;
2004-01-08 11:19:18 +03:00
DOM_SID * domain_sid ;
2007-10-25 01:16:54 +04:00
2002-03-01 05:56:35 +03:00
char * domain_name ;
char * acct_name ;
fstring pdc_name ;
2007-12-04 01:09:48 +03:00
char * dc_name ;
2008-02-08 04:12:30 +03:00
union lsa_PolicyInformation * info = NULL ;
2002-03-01 05:56:35 +03:00
/*
* Connect to \ \ server \ ipc $ as ' our domain ' account with password
*/
2002-07-15 14:35:28 +04:00
if ( argc ! = 1 ) {
2002-08-17 18:45:04 +04:00
d_printf ( " Usage: net rpc trustdom establish <domain_name> \n " ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
}
2002-03-01 05:56:35 +03:00
domain_name = smb_xstrdup ( argv [ 0 ] ) ;
2003-07-03 23:11:31 +04:00
strupper_m ( domain_name ) ;
2002-11-29 05:58:59 +03:00
/* account name used at first is our domain's name with '$' */
asprintf ( & acct_name , " %s$ " , lp_workgroup ( ) ) ;
2003-07-03 23:11:31 +04:00
strupper_m ( acct_name ) ;
2007-10-25 01:16:54 +04:00
2002-08-17 18:45:04 +04:00
/*
* opt_workgroup will be used by connection functions further ,
* hence it should be set to remote domain name instead of ours
*/
if ( opt_workgroup ) {
opt_workgroup = smb_xstrdup ( domain_name ) ;
} ;
2007-10-25 01:16:54 +04:00
2002-08-17 18:45:04 +04:00
opt_user_name = acct_name ;
2002-03-01 05:56:35 +03:00
/* find the domain controller */
2007-10-25 01:16:54 +04:00
if ( ! net_find_pdc ( & server_ss , pdc_name , domain_name ) ) {
2003-08-14 00:53:48 +04:00
DEBUG ( 0 , ( " Couldn't find domain controller for domain %s \n " , domain_name ) ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
/* connect to ipc$ as username/password */
2007-10-25 01:16:54 +04:00
nt_status = connect_to_ipc ( & cli , & server_ss , pdc_name ) ;
2002-03-01 05:56:35 +03:00
if ( ! NT_STATUS_EQUAL ( nt_status , NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ) ) {
/* Is it trusting domain account for sure ? */
DEBUG ( 0 , ( " Couldn't verify trusting domain account. Error was %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( nt_status ) ) ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2006-02-08 07:03:47 +03:00
/* store who we connected to */
2006-03-10 00:07:15 +03:00
saf_store ( domain_name , pdc_name ) ;
2007-10-25 01:16:54 +04:00
2002-03-01 05:56:35 +03:00
/*
* Connect to \ \ server \ ipc $ again ( this time anonymously )
*/
2007-10-25 01:16:54 +04:00
nt_status = connect_to_ipc_anonymous ( & cli , & server_ss , ( char * ) pdc_name ) ;
2007-12-04 01:09:48 +03:00
2002-03-01 05:56:35 +03:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't connect to domain %s controller. Error was %s. \n " ,
2002-03-17 07:36:35 +03:00
domain_name , nt_errstr ( nt_status ) ) ) ;
2007-01-20 02:08:20 +03:00
return - 1 ;
2002-03-01 05:56:35 +03:00
}
/*
* Use NetServerEnum2 to make sure we ' re talking to a proper server
*/
2007-12-04 01:09:48 +03:00
if ( ! cli_get_pdc_name ( cli , domain_name , & dc_name ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " NetServerEnum2 error: Couldn't find primary domain controller \
for domain % s \ n " , domain_name));
2007-01-20 02:08:20 +03:00
cli_shutdown ( cli ) ;
return - 1 ;
2002-03-01 05:56:35 +03:00
}
2007-12-04 01:09:48 +03:00
SAFE_FREE ( dc_name ) ;
2002-03-01 05:56:35 +03:00
2005-03-20 14:51:01 +03:00
if ( ! ( mem_ctx = talloc_init ( " establishing trust relationship to "
" domain %s " , domain_name ) ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " talloc_init() failed \n " ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
2005-06-09 02:10:34 +04:00
2002-03-01 05:56:35 +03:00
/*
* Call LsaOpenPolicy and LsaQueryInfo
*/
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise lsa pipe. Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
2002-08-17 18:45:04 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
2002-03-01 05:56:35 +03:00
}
2005-09-30 21:13:37 +04:00
nt_status = rpccli_lsa_open_policy2 ( pipe_hnd , mem_ctx , True , SEC_RIGHTS_QUERY_VALUE ,
2002-08-17 18:45:04 +04:00
& connect_hnd ) ;
2002-03-01 05:56:35 +03:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open policy handle. Error was %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
/* Querying info level 5 */
2008-02-08 04:12:30 +03:00
nt_status = rpccli_lsa_QueryInfoPolicy ( pipe_hnd , mem_ctx ,
& connect_hnd ,
LSA_POLICY_INFO_ACCOUNT_DOMAIN ,
& info ) ;
2002-03-01 05:56:35 +03:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " LSA Query Info failed. Returned error was %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2008-02-08 04:12:30 +03:00
domain_sid = info - > account_domain . sid ;
2002-03-01 05:56:35 +03:00
/* There should be actually query info level 3 (following nt serv behaviour),
but I still don ' t know if it ' s _really_ necessary */
2002-07-15 14:35:28 +04:00
/*
* Store the password in secrets db
*/
2007-01-16 11:17:26 +03:00
if ( ! pdb_set_trusteddom_pw ( domain_name , opt_password , domain_sid ) ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " Storing password for trusted domain failed. \n " ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
}
2002-03-01 05:56:35 +03:00
/*
* Close the pipes and clean up
*/
2006-09-21 02:49:02 +04:00
nt_status = rpccli_lsa_Close ( pipe_hnd , mem_ctx , & connect_hnd ) ;
2002-03-01 05:56:35 +03:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't close LSA pipe. Error was %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2005-03-20 14:51:01 +03:00
cli_shutdown ( cli ) ;
2002-03-01 05:56:35 +03:00
2002-07-15 14:35:28 +04:00
talloc_destroy ( mem_ctx ) ;
2002-03-01 05:56:35 +03:00
2004-03-18 10:32:15 +03:00
d_printf ( " Trust to domain %s established \n " , domain_name ) ;
2002-03-01 05:56:35 +03:00
return 0 ;
}
/**
* Revoke trust relationship to the remote domain
*
* @ param argc standard argc
* @ param argv standard argv without initial components
*
* @ return Integer status ( 0 means success )
* */
2002-08-17 18:45:04 +04:00
static int rpc_trustdom_revoke ( int argc , const char * * argv )
{
2002-03-01 05:56:35 +03:00
char * domain_name ;
2007-01-16 11:17:26 +03:00
int rc = - 1 ;
2002-03-01 05:56:35 +03:00
if ( argc < 1 ) return - 1 ;
/* generate upper cased domain name */
domain_name = smb_xstrdup ( argv [ 0 ] ) ;
2003-07-03 23:11:31 +04:00
strupper_m ( domain_name ) ;
2002-03-01 05:56:35 +03:00
/* delete password of the trust */
2007-01-16 11:17:26 +03:00
if ( ! pdb_del_trusteddom_pw ( domain_name ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " Failed to revoke relationship to the trusted domain %s \n " ,
domain_name ) ) ;
2007-01-16 11:17:26 +03:00
goto done ;
2002-03-01 05:56:35 +03:00
} ;
2007-01-16 11:17:26 +03:00
rc = 0 ;
done :
SAFE_FREE ( domain_name ) ;
return rc ;
2002-03-01 05:56:35 +03:00
}
/**
* Usage for ' net rpc trustdom ' command
*
* @ param argc standard argc
* @ param argv standard argv without inital components
*
* @ return Integer status returned to shell
* */
2002-08-17 18:45:04 +04:00
static int rpc_trustdom_usage ( int argc , const char * * argv )
{
2002-03-01 05:56:35 +03:00
d_printf ( " net rpc trustdom add \t \t add trusting domain's account \n " ) ;
d_printf ( " net rpc trustdom del \t \t delete trusting domain's account \n " ) ;
d_printf ( " net rpc trustdom establish \t establish relationship to trusted domain \n " ) ;
d_printf ( " net rpc trustdom revoke \t abandon relationship to trusted domain \n " ) ;
d_printf ( " net rpc trustdom list \t show current interdomain trust relationships \n " ) ;
2005-06-08 17:59:03 +04:00
d_printf ( " net rpc trustdom vampire \t vampire interdomain trust relationships from remote server \n " ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_query_domain_sid ( const DOM_SID * domain_sid ,
2005-09-30 21:13:37 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2002-08-17 18:45:04 +04:00
{
fstring str_sid ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( str_sid , domain_sid ) ;
2002-08-17 18:45:04 +04:00
d_printf ( " %s \n " , str_sid ) ;
return NT_STATUS_OK ;
2003-09-22 21:53:59 +04:00
}
2002-08-17 18:45:04 +04:00
2005-06-08 17:59:03 +04:00
static void print_trusted_domain ( DOM_SID * dom_sid , const char * trusted_dom_name )
{
fstring ascii_sid , padding ;
int pad_len , col_len = 20 ;
/* convert sid into ascii string */
2007-12-16 00:47:30 +03:00
sid_to_fstring ( ascii_sid , dom_sid ) ;
2005-06-08 17:59:03 +04:00
/* calculate padding space for d_printf to look nicer */
pad_len = col_len - strlen ( trusted_dom_name ) ;
padding [ pad_len ] = 0 ;
do padding [ - - pad_len ] = ' ' ; while ( pad_len ) ;
d_printf ( " %s%s%s \n " , trusted_dom_name , padding , ascii_sid ) ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS vampire_trusted_domain ( struct rpc_pipe_client * pipe_hnd ,
2005-06-08 17:59:03 +04:00
TALLOC_CTX * mem_ctx ,
POLICY_HND * pol ,
DOM_SID dom_sid ,
const char * trusted_dom_name )
{
NTSTATUS nt_status ;
2008-01-14 17:33:26 +03:00
union lsa_TrustedDomainInfo info ;
2005-07-28 19:01:29 +04:00
char * cleartextpwd = NULL ;
2005-06-08 17:59:03 +04:00
DATA_BLOB data ;
2008-01-14 17:33:26 +03:00
nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid ( pipe_hnd , mem_ctx ,
pol ,
& dom_sid ,
LSA_TRUSTED_DOMAIN_INFO_PASSWORD ,
& info ) ;
2005-06-08 17:59:03 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Could not query trusted domain info. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
goto done ;
}
2008-01-14 17:33:26 +03:00
data = data_blob ( NULL , info . password . password - > length ) ;
2005-06-08 17:59:03 +04:00
2008-01-14 17:33:26 +03:00
memcpy ( data . data ,
info . password . password - > data ,
info . password . password - > length ) ;
data . length = info . password . password - > length ;
cleartextpwd = decrypt_trustdom_secret ( pipe_hnd - > cli - > pwd . password ,
& data ) ;
2005-06-08 17:59:03 +04:00
if ( cleartextpwd = = NULL ) {
DEBUG ( 0 , ( " retrieved NULL password \n " ) ) ;
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2007-01-16 11:17:26 +03:00
if ( ! pdb_set_trusteddom_pw ( trusted_dom_name , cleartextpwd , & dom_sid ) ) {
2005-06-08 17:59:03 +04:00
DEBUG ( 0 , ( " Storing password for trusted domain failed. \n " ) ) ;
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2005-12-19 05:22:13 +03:00
# ifdef DEBUG_PASSWORD
2007-12-15 23:11:36 +03:00
DEBUG ( 100 , ( " sucessfully vampired trusted domain [%s], sid: [%s], "
" password: [%s] \n " , trusted_dom_name ,
sid_string_dbg ( & dom_sid ) , cleartextpwd ) ) ;
2005-12-19 05:22:13 +03:00
# endif
2005-06-08 17:59:03 +04:00
done :
SAFE_FREE ( cleartextpwd ) ;
data_blob_free ( & data ) ;
return nt_status ;
}
static int rpc_trustdom_vampire ( int argc , const char * * argv )
{
/* common variables */
TALLOC_CTX * mem_ctx ;
2005-09-30 21:13:37 +04:00
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-06-08 17:59:03 +04:00
NTSTATUS nt_status ;
const char * domain_name = NULL ;
DOM_SID * queried_dom_sid ;
POLICY_HND connect_hnd ;
2008-02-08 04:12:30 +03:00
union lsa_PolicyInformation * info = NULL ;
2005-06-08 17:59:03 +04:00
/* trusted domains listing variables */
2008-02-13 02:25:40 +03:00
unsigned int enum_ctx = 0 ;
2005-06-08 17:59:03 +04:00
int i ;
2008-02-13 02:25:40 +03:00
struct lsa_DomainList dom_list ;
2005-06-08 17:59:03 +04:00
fstring pdc_name ;
/*
* Listing trusted domains ( stored in secrets . tdb , if local )
*/
mem_ctx = talloc_init ( " trust relationships vampire " ) ;
/*
* set domain and pdc name to local samba server ( default )
* or to remote one given in command line
*/
if ( StrCaseCmp ( opt_workgroup , lp_workgroup ( ) ) ) {
domain_name = opt_workgroup ;
opt_target_workgroup = opt_workgroup ;
} else {
fstrcpy ( pdc_name , global_myname ( ) ) ;
domain_name = talloc_strdup ( mem_ctx , lp_workgroup ( ) ) ;
opt_target_workgroup = domain_name ;
} ;
/* open \PIPE\lsarpc and open policy handle */
2007-09-17 19:11:20 +04:00
nt_status = net_make_ipc_connection ( NET_FLAGS_PDC , & cli ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't connect to domain controller: %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
} ;
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise lsa pipe. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
} ;
2005-09-30 21:13:37 +04:00
nt_status = rpccli_lsa_open_policy2 ( pipe_hnd , mem_ctx , False , SEC_RIGHTS_QUERY_VALUE ,
2005-06-08 17:59:03 +04:00
& connect_hnd ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
} ;
/* query info level 5 to obtain sid of a domain being queried */
2008-02-08 04:12:30 +03:00
nt_status = rpccli_lsa_QueryInfoPolicy ( pipe_hnd , mem_ctx ,
& connect_hnd ,
LSA_POLICY_INFO_ACCOUNT_DOMAIN ,
& info ) ;
2005-06-08 17:59:03 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " LSA Query Info failed. Returned error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
}
2008-02-08 04:12:30 +03:00
queried_dom_sid = info - > account_domain . sid ;
2005-06-08 17:59:03 +04:00
/*
* Keep calling LsaEnumTrustdom over opened pipe until
* the end of enumeration is reached
*/
d_printf ( " Vampire trusted domains: \n \n " ) ;
do {
2008-02-13 02:25:40 +03:00
nt_status = rpccli_lsa_EnumTrustDom ( pipe_hnd , mem_ctx ,
& connect_hnd ,
& enum_ctx ,
& dom_list ,
( uint32_t ) - 1 ) ;
2005-06-08 17:59:03 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't enumerate trusted domains. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
} ;
2008-02-13 02:25:40 +03:00
for ( i = 0 ; i < dom_list . count ; i + + ) {
print_trusted_domain ( dom_list . domains [ i ] . sid ,
dom_list . domains [ i ] . name . string ) ;
2005-06-08 17:59:03 +04:00
2005-09-30 21:13:37 +04:00
nt_status = vampire_trusted_domain ( pipe_hnd , mem_ctx , & connect_hnd ,
2008-02-13 02:25:40 +03:00
* dom_list . domains [ i ] . sid ,
dom_list . domains [ i ] . name . string ) ;
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
2005-09-30 21:13:37 +04:00
}
2005-06-08 17:59:03 +04:00
} ;
/*
* in case of no trusted domains say something rather
* than just display blank line
*/
2008-02-13 02:25:40 +03:00
if ( ! dom_list . count ) d_printf ( " none \n " ) ;
2005-06-08 17:59:03 +04:00
} while ( NT_STATUS_EQUAL ( nt_status , STATUS_MORE_ENTRIES ) ) ;
/* close this connection before doing next one */
2006-09-21 02:49:02 +04:00
nt_status = rpccli_lsa_Close ( pipe_hnd , mem_ctx , & connect_hnd ) ;
2005-06-08 17:59:03 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close lsa policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2005-09-30 21:13:37 +04:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2005-06-08 17:59:03 +04:00
return - 1 ;
} ;
/* close lsarpc pipe and connection to IPC$ */
cli_shutdown ( cli ) ;
talloc_destroy ( mem_ctx ) ;
return 0 ;
}
2002-08-17 18:45:04 +04:00
static int rpc_trustdom_list ( int argc , const char * * argv )
{
/* common variables */
TALLOC_CTX * mem_ctx ;
2005-09-30 21:13:37 +04:00
struct cli_state * cli = NULL , * remote_cli = NULL ;
struct rpc_pipe_client * pipe_hnd = NULL ;
2002-08-17 18:45:04 +04:00
NTSTATUS nt_status ;
2003-01-03 11:28:12 +03:00
const char * domain_name = NULL ;
2004-01-08 11:19:18 +03:00
DOM_SID * queried_dom_sid ;
2005-06-08 17:59:03 +04:00
fstring padding ;
2002-08-17 18:45:04 +04:00
int ascii_dom_name_len ;
POLICY_HND connect_hnd ;
2008-02-08 04:12:30 +03:00
union lsa_PolicyInformation * info = NULL ;
2002-08-17 18:45:04 +04:00
/* trusted domains listing variables */
2003-08-15 08:42:05 +04:00
unsigned int num_domains , enum_ctx = 0 ;
int i , pad_len , col_len = 20 ;
2008-02-13 02:25:40 +03:00
struct lsa_DomainList dom_list ;
2004-01-08 11:19:18 +03:00
fstring pdc_name ;
2008-02-08 04:12:30 +03:00
2002-08-17 18:45:04 +04:00
/* trusting domains listing variables */
POLICY_HND domain_hnd ;
2008-02-12 13:36:33 +03:00
struct samr_SamArray * trusts = NULL ;
2002-08-17 18:45:04 +04:00
/*
* Listing trusted domains ( stored in secrets . tdb , if local )
*/
2002-12-20 23:21:31 +03:00
mem_ctx = talloc_init ( " trust relationships listing " ) ;
2002-08-17 18:45:04 +04:00
/*
* set domain and pdc name to local samba server ( default )
* or to remote one given in command line
*/
2003-01-03 11:28:12 +03:00
if ( StrCaseCmp ( opt_workgroup , lp_workgroup ( ) ) ) {
2002-08-17 18:45:04 +04:00
domain_name = opt_workgroup ;
opt_target_workgroup = opt_workgroup ;
} else {
2003-01-03 11:28:12 +03:00
fstrcpy ( pdc_name , global_myname ( ) ) ;
2002-08-17 18:45:04 +04:00
domain_name = talloc_strdup ( mem_ctx , lp_workgroup ( ) ) ;
opt_target_workgroup = domain_name ;
} ;
/* open \PIPE\lsarpc and open policy handle */
2007-09-17 19:11:20 +04:00
nt_status = net_make_ipc_connection ( NET_FLAGS_PDC , & cli ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't connect to domain controller: %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_LSARPC , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise lsa pipe. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2005-09-30 21:13:37 +04:00
nt_status = rpccli_lsa_open_policy2 ( pipe_hnd , mem_ctx , False , SEC_RIGHTS_QUERY_VALUE ,
2002-08-17 18:45:04 +04:00
& connect_hnd ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
/* query info level 5 to obtain sid of a domain being queried */
2008-02-08 04:12:30 +03:00
nt_status = rpccli_lsa_QueryInfoPolicy ( pipe_hnd , mem_ctx ,
& connect_hnd ,
LSA_POLICY_INFO_ACCOUNT_DOMAIN ,
& info ) ;
2003-04-14 08:00:15 +04:00
2002-08-17 18:45:04 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " LSA Query Info failed. Returned error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
}
2008-02-08 04:12:30 +03:00
queried_dom_sid = info - > account_domain . sid ;
2002-08-17 18:45:04 +04:00
/*
* Keep calling LsaEnumTrustdom over opened pipe until
* the end of enumeration is reached
*/
d_printf ( " Trusted domains list: \n \n " ) ;
do {
2008-02-13 02:25:40 +03:00
nt_status = rpccli_lsa_EnumTrustDom ( pipe_hnd , mem_ctx ,
& connect_hnd ,
& enum_ctx ,
& dom_list ,
( uint32_t ) - 1 ) ;
2002-08-17 18:45:04 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't enumerate trusted domains. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2008-02-13 02:25:40 +03:00
for ( i = 0 ; i < dom_list . count ; i + + ) {
print_trusted_domain ( dom_list . domains [ i ] . sid ,
dom_list . domains [ i ] . name . string ) ;
2002-08-17 18:45:04 +04:00
} ;
2008-02-13 02:25:40 +03:00
2002-09-25 19:19:00 +04:00
/*
* in case of no trusted domains say something rather
* than just display blank line
*/
2008-02-13 02:25:40 +03:00
if ( ! dom_list . count ) d_printf ( " none \n " ) ;
2002-08-17 18:45:04 +04:00
} while ( NT_STATUS_EQUAL ( nt_status , STATUS_MORE_ENTRIES ) ) ;
/* close this connection before doing next one */
2006-09-21 02:49:02 +04:00
nt_status = rpccli_lsa_Close ( pipe_hnd , mem_ctx , & connect_hnd ) ;
2002-08-17 18:45:04 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close lsa policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2005-09-30 21:13:37 +04:00
cli_rpc_pipe_close ( pipe_hnd ) ;
2002-08-17 18:45:04 +04:00
/*
* Listing trusting domains ( stored in passdb backend , if local )
*/
d_printf ( " \n Trusting domains list: \n \n " ) ;
/*
* Open \ PIPE \ samr and get needed policy handles
*/
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_SAMR , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 0 , ( " Could not initialise samr pipe. Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2008-02-04 21:43:07 +03:00
/* SamrConnect2 */
nt_status = rpccli_samr_Connect2 ( pipe_hnd , mem_ctx ,
pipe_hnd - > cli - > desthost ,
SA_RIGHT_SAM_OPEN_DOMAIN ,
& connect_hnd ) ;
2002-08-17 18:45:04 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open SAMR policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2008-02-01 13:12:05 +03:00
2002-08-17 18:45:04 +04:00
/* SamrOpenDomain - we have to open domain policy handle in order to be
able to enumerate accounts */
2008-02-01 13:12:05 +03:00
nt_status = rpccli_samr_OpenDomain ( pipe_hnd , mem_ctx ,
& connect_hnd ,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS ,
queried_dom_sid ,
& domain_hnd ) ;
2002-08-17 18:45:04 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open domain object. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
/*
* perform actual enumeration
*/
enum_ctx = 0 ; /* reset enumeration context from last enumeration */
do {
2008-02-12 13:36:33 +03:00
nt_status = rpccli_samr_EnumDomainUsers ( pipe_hnd , mem_ctx ,
& domain_hnd ,
& enum_ctx ,
ACB_DOMTRUST ,
& trusts ,
0xffff ,
& num_domains ) ;
2002-08-17 18:45:04 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't enumerate accounts. Error was: %s \n " ,
nt_errstr ( nt_status ) ) ) ;
2007-03-08 01:29:21 +03:00
cli_shutdown ( cli ) ;
2007-03-01 05:43:33 +03:00
talloc_destroy ( mem_ctx ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
} ;
2008-02-12 13:36:33 +03:00
2002-08-17 18:45:04 +04:00
for ( i = 0 ; i < num_domains ; i + + ) {
2008-02-12 13:36:33 +03:00
char * str = CONST_DISCARD ( char * , trusts - > entries [ i ] . name . string ) ;
2002-08-17 18:45:04 +04:00
/*
* get each single domain ' s sid ( do we _really_ need this ? ) :
* 1 ) connect to domain ' s pdc
* 2 ) query the pdc for domain ' s sid
*/
/* get rid of '$' tail */
2008-02-12 13:36:33 +03:00
ascii_dom_name_len = strlen ( str ) ;
2002-08-17 18:45:04 +04:00
if ( ascii_dom_name_len & & ascii_dom_name_len < FSTRING_LEN )
2008-02-12 13:36:33 +03:00
str [ ascii_dom_name_len - 1 ] = ' \0 ' ;
2002-08-17 18:45:04 +04:00
/* calculate padding space for d_printf to look nicer */
2008-02-12 13:36:33 +03:00
pad_len = col_len - strlen ( str ) ;
2002-08-17 18:45:04 +04:00
padding [ pad_len ] = 0 ;
do padding [ - - pad_len ] = ' ' ; while ( pad_len ) ;
/* set opt_* variables to remote domain */
2008-02-12 13:36:33 +03:00
strupper_m ( str ) ;
opt_workgroup = talloc_strdup ( mem_ctx , str ) ;
2002-08-17 18:45:04 +04:00
opt_target_workgroup = opt_workgroup ;
2008-02-12 13:36:33 +03:00
d_printf ( " %s%s " , str , padding ) ;
2002-08-17 18:45:04 +04:00
/* connect to remote domain controller */
2007-09-17 19:11:20 +04:00
nt_status = net_make_ipc_connection (
NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS ,
& remote_cli ) ;
if ( NT_STATUS_IS_OK ( nt_status ) ) {
2002-08-17 18:45:04 +04:00
/* query for domain's sid */
2002-10-04 08:10:23 +04:00
if ( run_rpc_command ( remote_cli , PI_LSARPC , 0 , rpc_query_domain_sid , argc , argv ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " couldn't get domain's sid \n " ) ;
2002-08-17 18:45:04 +04:00
cli_shutdown ( remote_cli ) ;
} else {
2007-09-17 19:11:20 +04:00
d_fprintf ( stderr , " domain controller is not "
" responding: %s \n " ,
nt_errstr ( nt_status ) ) ;
2002-08-17 18:45:04 +04:00
} ;
} ;
2002-09-25 19:19:00 +04:00
if ( ! num_domains ) d_printf ( " none \n " ) ;
2002-08-17 18:45:04 +04:00
} while ( NT_STATUS_EQUAL ( nt_status , STATUS_MORE_ENTRIES ) ) ;
/* close opened samr and domain policy handles */
2008-01-30 14:39:20 +03:00
nt_status = rpccli_samr_Close ( pipe_hnd , mem_ctx , & domain_hnd ) ;
2002-08-17 18:45:04 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close domain policy handle for domain %s \n " , domain_name ) ) ;
} ;
2008-01-30 14:39:20 +03:00
nt_status = rpccli_samr_Close ( pipe_hnd , mem_ctx , & connect_hnd ) ;
2002-08-17 18:45:04 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close samr policy handle for domain %s \n " , domain_name ) ) ;
} ;
/* close samr pipe and connection to IPC$ */
cli_shutdown ( cli ) ;
talloc_destroy ( mem_ctx ) ;
return 0 ;
}
2002-03-01 05:56:35 +03:00
/**
* Entrypoint for ' net rpc trustdom ' code
*
* @ param argc standard argc
* @ param argv standard argv without initial components
*
* @ return Integer status ( 0 means success )
*/
static int rpc_trustdom ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " add " , rpc_trustdom_add } ,
{ " del " , rpc_trustdom_del } ,
{ " establish " , rpc_trustdom_establish } ,
{ " revoke " , rpc_trustdom_revoke } ,
2002-03-15 23:03:07 +03:00
{ " help " , rpc_trustdom_usage } ,
2002-08-17 18:45:04 +04:00
{ " list " , rpc_trustdom_list } ,
2005-06-08 17:59:03 +04:00
{ " vampire " , rpc_trustdom_vampire } ,
2002-03-01 05:56:35 +03:00
{ NULL , NULL }
} ;
if ( argc = = 0 ) {
rpc_trustdom_usage ( argc , argv ) ;
return - 1 ;
}
return ( net_run_function ( argc , argv , func , rpc_user_usage ) ) ;
}
2002-04-05 05:36:28 +04:00
/**
* Check if a server will take rpc commands
* @ param flags Type of server to connect to ( PDC , DMB , localhost )
* if the host is not explicitly specified
2007-10-19 04:40:25 +04:00
* @ return bool ( true means rpc supported )
2002-04-05 05:36:28 +04:00
*/
2007-10-19 04:40:25 +04:00
bool net_rpc_check ( unsigned flags )
2002-04-05 05:36:28 +04:00
{
2006-07-11 22:01:26 +04:00
struct cli_state * cli ;
2007-10-19 04:40:25 +04:00
bool ret = False ;
2007-10-25 01:16:54 +04:00
struct sockaddr_storage server_ss ;
2002-04-05 05:36:28 +04:00
char * server_name = NULL ;
2007-06-20 21:38:42 +04:00
NTSTATUS status ;
2002-04-05 05:36:28 +04:00
/* flags (i.e. server type) may depend on command */
2007-10-25 01:16:54 +04:00
if ( ! net_find_server ( NULL , flags , & server_ss , & server_name ) )
2002-09-25 19:19:00 +04:00
return False ;
2002-04-05 05:36:28 +04:00
2006-07-11 22:01:26 +04:00
if ( ( cli = cli_initialise ( ) ) = = NULL ) {
2002-04-05 05:36:28 +04:00
return False ;
2006-07-11 22:01:26 +04:00
}
2002-04-05 05:36:28 +04:00
2007-10-25 01:16:54 +04:00
status = cli_connect ( cli , server_name , & server_ss ) ;
2007-06-20 21:38:42 +04:00
if ( ! NT_STATUS_IS_OK ( status ) )
2002-04-05 05:36:28 +04:00
goto done ;
2007-10-25 01:16:54 +04:00
if ( ! attempt_netbios_session_request ( & cli , global_myname ( ) ,
server_name , & server_ss ) )
2002-04-05 05:36:28 +04:00
goto done ;
2006-07-11 22:01:26 +04:00
if ( ! cli_negprot ( cli ) )
2002-04-05 05:36:28 +04:00
goto done ;
2006-07-11 22:01:26 +04:00
if ( cli - > protocol < PROTOCOL_NT1 )
2002-04-05 05:36:28 +04:00
goto done ;
ret = True ;
done :
2006-07-11 22:01:26 +04:00
cli_shutdown ( cli ) ;
2002-04-05 05:36:28 +04:00
return ret ;
}
2004-02-08 13:59:09 +03:00
/* dump sam database via samsync rpc calls */
static int rpc_samdump ( int argc , const char * * argv ) {
2005-09-30 21:13:37 +04:00
return run_rpc_command ( NULL , PI_NETLOGON , NET_FLAGS_ANONYMOUS , rpc_samdump_internals ,
2004-02-08 13:59:09 +03:00
argc , argv ) ;
}
2002-04-05 05:36:28 +04:00
2004-02-08 13:59:09 +03:00
/* syncronise sam database via samsync rpc calls */
static int rpc_vampire ( int argc , const char * * argv ) {
return run_rpc_command ( NULL , PI_NETLOGON , NET_FLAGS_ANONYMOUS , rpc_vampire_internals ,
argc , argv ) ;
}
2004-08-10 18:27:17 +04:00
/**
* Migrate everything from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
*
* The order is important !
* To successfully add drivers the print - queues have to exist !
* Applying ACLs should be the last step , because you ' re easily locked out
*
* */
static int rpc_printer_migrate_all ( int argc , const char * * argv )
{
int ret ;
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
ret = run_rpc_command ( NULL , PI_SPOOLSS , 0 , rpc_printer_migrate_printers_internals , argc , argv ) ;
if ( ret )
return ret ;
ret = run_rpc_command ( NULL , PI_SPOOLSS , 0 , rpc_printer_migrate_drivers_internals , argc , argv ) ;
if ( ret )
return ret ;
ret = run_rpc_command ( NULL , PI_SPOOLSS , 0 , rpc_printer_migrate_forms_internals , argc , argv ) ;
if ( ret )
return ret ;
ret = run_rpc_command ( NULL , PI_SPOOLSS , 0 , rpc_printer_migrate_settings_internals , argc , argv ) ;
if ( ret )
return ret ;
return run_rpc_command ( NULL , PI_SPOOLSS , 0 , rpc_printer_migrate_security_internals , argc , argv ) ;
}
/**
* Migrate print - drivers from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_migrate_drivers ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_migrate_drivers_internals ,
argc , argv ) ;
}
/**
* Migrate print - forms from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_migrate_forms ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_migrate_forms_internals ,
argc , argv ) ;
}
/**
* Migrate printers from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_migrate_printers ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_migrate_printers_internals ,
argc , argv ) ;
}
/**
* Migrate printer - ACLs from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_migrate_security ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_migrate_security_internals ,
argc , argv ) ;
}
/**
* Migrate printer - settings from a print - server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_migrate_settings ( int argc , const char * * argv )
{
2004-08-21 00:13:05 +04:00
if ( ! opt_host ) {
printf ( " no server to migrate \n " ) ;
return - 1 ;
}
2004-08-10 18:27:17 +04:00
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_migrate_settings_internals ,
argc , argv ) ;
}
/**
* ' net rpc printer ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
int rpc_printer_migrate ( int argc , const char * * argv )
{
/* ouch: when addriver and setdriver are called from within
rpc_printer_migrate_drivers_internals , the printer - queue already
* has * to exist */
struct functable func [ ] = {
{ " all " , rpc_printer_migrate_all } ,
{ " drivers " , rpc_printer_migrate_drivers } ,
{ " forms " , rpc_printer_migrate_forms } ,
{ " help " , rpc_printer_usage } ,
{ " printers " , rpc_printer_migrate_printers } ,
{ " security " , rpc_printer_migrate_security } ,
{ " settings " , rpc_printer_migrate_settings } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , rpc_printer_usage ) ;
}
/**
* List printers on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_list ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_list_internals ,
argc , argv ) ;
}
/**
* List printer - drivers on a remote RPC server
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_driver_list ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_driver_list_internals ,
argc , argv ) ;
}
2004-10-13 05:40:35 +04:00
/**
* Publish printer in ADS via MSRPC
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_publish_publish ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_publish_publish_internals ,
argc , argv ) ;
}
/**
* Update printer in ADS via MSRPC
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_publish_update ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_publish_update_internals ,
argc , argv ) ;
}
/**
* UnPublish printer in ADS via MSRPC
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_publish_unpublish ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_publish_unpublish_internals ,
argc , argv ) ;
}
/**
* List published printers via MSRPC
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_publish_list ( int argc , const char * * argv )
{
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_publish_list_internals ,
argc , argv ) ;
}
/**
* Publish printer in ADS
*
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return A shell status integer ( 0 for success )
* */
static int rpc_printer_publish ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " publish " , rpc_printer_publish_publish } ,
{ " update " , rpc_printer_publish_update } ,
{ " unpublish " , rpc_printer_publish_unpublish } ,
{ " list " , rpc_printer_publish_list } ,
{ " help " , rpc_printer_usage } ,
{ NULL , NULL }
} ;
if ( argc = = 0 )
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_publish_list_internals ,
argc , argv ) ;
return net_run_function ( argc , argv , func , rpc_printer_usage ) ;
}
2004-08-10 18:27:17 +04:00
/**
* Display rpc printer help page .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
int rpc_printer_usage ( int argc , const char * * argv )
{
return net_help_printer ( argc , argv ) ;
}
/**
* ' net rpc printer ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
int net_rpc_printer ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " list " , rpc_printer_list } ,
{ " migrate " , rpc_printer_migrate } ,
{ " driver " , rpc_printer_driver_list } ,
2004-10-13 05:40:35 +04:00
{ " publish " , rpc_printer_publish } ,
2004-08-10 18:27:17 +04:00
{ NULL , NULL }
} ;
if ( argc = = 0 )
return run_rpc_command ( NULL , PI_SPOOLSS , 0 ,
rpc_printer_list_internals ,
argc , argv ) ;
return net_run_function ( argc , argv , func , rpc_printer_usage ) ;
}
2001-12-31 16:00:59 +03:00
/****************************************************************************/
/**
* Basic usage function for ' net rpc '
2001-12-30 13:54:58 +03:00
* @ param argc Standard main ( ) style argc
2002-03-15 23:03:07 +03:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-30 13:54:58 +03:00
* stripped
* */
2001-12-03 07:39:23 +03:00
int net_rpc_usage ( int argc , const char * * argv )
{
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc info \t \t \t show basic info about a domain \n " ) ;
2002-03-15 23:03:07 +03:00
d_printf ( " net rpc join \t \t \t to join a domain \n " ) ;
2007-10-03 16:55:45 +04:00
d_printf ( " net rpc oldjoin \t \t to join a domain created in server manager \n " ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " net rpc testjoin \t \t tests that a join is valid \n " ) ;
2002-03-15 23:03:07 +03:00
d_printf ( " net rpc user \t \t \t to add, delete and list users \n " ) ;
2004-09-29 13:56:35 +04:00
d_printf ( " net rpc password <username> [<password>] -Uadmin_username%%admin_pass \n " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc group \t \t to list groups \n " ) ;
2004-08-21 00:13:05 +04:00
d_printf ( " net rpc share \t \t to add, delete, list and migrate shares \n " ) ;
2004-08-10 18:27:17 +04:00
d_printf ( " net rpc printer \t \t to list and migrate printers \n " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc file \t \t \t to list open files \n " ) ;
2001-12-05 14:00:26 +03:00
d_printf ( " net rpc changetrustpw \t to change the trust account password \n " ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " net rpc getsid \t \t fetch the domain sid into the local secrets.tdb \n " ) ;
2002-11-16 00:43:57 +03:00
d_printf ( " net rpc vampire \t \t syncronise an NT PDC's users and groups into the local passdb \n " ) ;
2007-10-03 16:55:45 +04:00
d_printf ( " net rpc samdump \t \t display an NT PDC's users, groups and other data \n " ) ;
2005-01-18 17:46:24 +03:00
d_printf ( " net rpc trustdom \t \t to create trusting domain's account or establish trust \n " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc abortshutdown \t to abort the shutdown of a remote server \n " ) ;
d_printf ( " net rpc shutdown \t \t to shutdown a remote server \n " ) ;
2005-01-18 17:46:24 +03:00
d_printf ( " net rpc rights \t \t to manage privileges assigned to SIDs \n " ) ;
2005-05-23 20:28:28 +04:00
d_printf ( " net rpc registry \t \t to manage registry hives \n " ) ;
2005-08-30 15:31:49 +04:00
d_printf ( " net rpc service \t \t to start, stop and query services \n " ) ;
2006-04-24 16:01:14 +04:00
d_printf ( " net rpc audit \t \t \t to modify global auditing settings \n " ) ;
2006-06-19 14:01:02 +04:00
d_printf ( " net rpc shell \t \t \t to open an interactive shell for remote server/account management \n " ) ;
2001-12-31 16:00:59 +03:00
d_printf ( " \n " ) ;
d_printf ( " 'net rpc shutdown' also accepts the following miscellaneous options: \n " ) ; /* misc options */
d_printf ( " \t -r or --reboot \t request remote server reboot on shutdown \n " ) ;
d_printf ( " \t -f or --force \t request the remote server force its shutdown \n " ) ;
d_printf ( " \t -t or --timeout=<timeout> \t number of seconds before shutdown \n " ) ;
2005-09-16 00:39:57 +04:00
d_printf ( " \t -C or --comment=<message> \t text message to display on impending shutdown \n " ) ;
2001-12-03 07:39:23 +03:00
return - 1 ;
}
2002-03-15 23:03:07 +03:00
/**
* Help function for ' net rpc ' . Calls command specific help if requested
* or displays usage of net rpc
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* */
2002-03-16 01:09:18 +03:00
int net_rpc_help ( int argc , const char * * argv )
2002-03-15 23:03:07 +03:00
{
struct functable func [ ] = {
{ " join " , rpc_join_usage } ,
2002-07-15 14:35:28 +04:00
{ " user " , rpc_user_usage } ,
{ " group " , rpc_group_usage } ,
{ " share " , rpc_share_usage } ,
2002-03-16 04:14:58 +03:00
/*{"changetrustpw", rpc_changetrustpw_usage}, */
2002-03-15 23:03:07 +03:00
{ " trustdom " , rpc_trustdom_usage } ,
2002-03-16 04:14:58 +03:00
/*{"abortshutdown", rpc_shutdown_abort_usage},*/
/*{"shutdown", rpc_shutdown_usage}, */
2005-07-07 01:02:43 +04:00
{ " vampire " , rpc_vampire_usage } ,
2002-03-15 23:03:07 +03:00
{ NULL , NULL }
} ;
if ( argc = = 0 ) {
net_rpc_usage ( argc , argv ) ;
return - 1 ;
}
return ( net_run_function ( argc , argv , func , rpc_user_usage ) ) ;
}
2001-12-30 13:54:58 +03:00
/**
2001-12-31 16:00:59 +03:00
* ' net rpc ' entrypoint .
2001-12-30 13:54:58 +03:00
* @ param argc Standard main ( ) style argc
2002-03-15 23:03:07 +03:00
* @ param argv Standard main ( ) style argv . Initial components are already
2001-12-30 13:54:58 +03:00
* stripped
* */
2001-12-03 07:39:23 +03:00
int net_rpc ( int argc , const char * * argv )
{
struct functable func [ ] = {
2006-04-11 19:47:24 +04:00
{ " audit " , net_rpc_audit } ,
2002-07-15 14:35:28 +04:00
{ " info " , net_rpc_info } ,
2002-03-16 01:09:18 +03:00
{ " join " , net_rpc_join } ,
2003-04-21 18:09:03 +04:00
{ " oldjoin " , net_rpc_oldjoin } ,
2002-08-17 18:45:04 +04:00
{ " testjoin " , net_rpc_testjoin } ,
2002-04-05 05:36:28 +04:00
{ " user " , net_rpc_user } ,
2004-02-07 06:54:39 +03:00
{ " password " , rpc_user_password } ,
2002-07-15 14:35:28 +04:00
{ " group " , net_rpc_group } ,
{ " share " , net_rpc_share } ,
{ " file " , net_rpc_file } ,
2004-08-10 18:27:17 +04:00
{ " printer " , net_rpc_printer } ,
2003-04-15 02:27:09 +04:00
{ " changetrustpw " , net_rpc_changetrustpw } ,
2002-03-01 05:56:35 +03:00
{ " trustdom " , rpc_trustdom } ,
2001-12-31 16:00:59 +03:00
{ " abortshutdown " , rpc_shutdown_abort } ,
{ " shutdown " , rpc_shutdown } ,
2002-09-25 19:19:00 +04:00
{ " samdump " , rpc_samdump } ,
{ " vampire " , rpc_vampire } ,
{ " getsid " , net_rpc_getsid } ,
2005-01-18 17:46:24 +03:00
{ " rights " , net_rpc_rights } ,
2005-03-24 07:25:49 +03:00
{ " service " , net_rpc_service } ,
2005-05-23 20:28:28 +04:00
{ " registry " , net_rpc_registry } ,
2006-02-04 01:19:41 +03:00
{ " shell " , net_rpc_shell } ,
2002-03-16 01:09:18 +03:00
{ " help " , net_rpc_help } ,
2001-12-03 07:39:23 +03:00
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_rpc_usage ) ;
}