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 )
2004-10-13 05:40:35 +04:00
Copyright ( C ) 2004 Guenther Deschner ( gd @ 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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA . */
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2001-12-03 07:39:23 +03: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
2004-02-08 13:59:09 +03:00
static DOM_SID * net_get_remote_domain_sid ( struct cli_state * cli , TALLOC_CTX * mem_ctx , char * * domain_name )
2001-12-05 03:26:36 +03:00
{
DOM_SID * domain_sid ;
POLICY_HND pol ;
NTSTATUS result = NT_STATUS_OK ;
uint32 info_class = 5 ;
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_LSARPC ) ) {
2001-12-05 03:26:36 +03:00
fprintf ( stderr , " could not initialise lsa pipe \n " ) ;
goto error ;
}
2003-05-05 12:32:30 +04:00
result = cli_lsa_open_policy ( cli , mem_ctx , False ,
2001-12-05 03:26:36 +03:00
SEC_RIGHTS_MAXIMUM_ALLOWED ,
& pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto error ;
}
result = cli_lsa_query_info_policy ( cli , mem_ctx , & pol , info_class ,
2004-02-08 13:59:09 +03:00
domain_name , & domain_sid ) ;
2001-12-05 03:26:36 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2003-08-15 06:01:56 +04:00
error :
fprintf ( stderr , " could not obtain sid for domain %s \n " , cli - > domain ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
fprintf ( stderr , " error: %s \n " , nt_errstr ( result ) ) ;
}
exit ( 1 ) ;
2001-12-05 03:26:36 +03:00
}
cli_lsa_close ( cli , mem_ctx , & pol ) ;
cli_nt_session_close ( cli ) ;
return domain_sid ;
}
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-01-18 17:46:24 +03:00
int run_rpc_command ( struct cli_state * cli_arg , const int pipe_idx , int conn_flags ,
2002-08-17 18:45:04 +04:00
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 ;
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 ;
2004-02-08 13:59:09 +03:00
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 */
if ( ! cli_arg )
cli = net_make_ipc_connection ( conn_flags ) ;
else
cli = cli_arg ;
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 ;
}
2004-02-08 13:59:09 +03:00
domain_sid = net_get_remote_domain_sid ( cli , mem_ctx , & domain_name ) ;
2004-01-16 18:07:28 +03:00
2004-02-08 13:59:09 +03:00
if ( ! ( conn_flags & NET_FLAGS_NO_PIPE ) ) {
if ( ! cli_nt_session_open ( cli , pipe_idx ) ) {
DEBUG ( 0 , ( " Could not initialise pipe \n " ) ) ;
}
2001-12-05 03:26:36 +03:00
}
2004-02-08 13:59:09 +03:00
nt_status = fn ( domain_sid , domain_name , cli , 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-01-06 18:35:02 +03:00
if ( cli - > nt_pipe_fnum [ cli - > pipe_idx ] )
2004-02-08 13:59:09 +03:00
cli_nt_session_close ( cli ) ;
}
2002-08-17 18:45:04 +04:00
/* close the connection only if it was opened here */
if ( ! cli_arg )
cli_shutdown ( cli ) ;
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
/****************************************************************************/
2001-12-05 03:26:36 +03:00
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
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_changetrustpw_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv ) {
2001-12-05 14:00:26 +03:00
return trust_pw_find_change_and_store_it ( cli , mem_ctx , opt_target_workgroup ) ;
}
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 .
* */
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_oldjoin_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
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
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
2003-04-21 18:09:03 +04:00
result = trust_pw_change_and_store_it ( cli , mem_ctx , opt_target_workgroup ,
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 ,
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 ) {
d_printf ( " Failed to join domain \n " ) ;
}
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
*
* Main ' net_rpc_join ( ) ' ( where the admain username / password is used ) is
* 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
{
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
}
2001-12-30 13:54:58 +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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_info_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
SAM_UNK_CTR ctr ;
2002-09-25 19:19:00 +04:00
fstring sid_str ;
sid_to_string ( sid_str , domain_sid ) ;
2002-07-15 14:35:28 +04:00
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
ZERO_STRUCT ( ctr ) ;
result = cli_samr_query_dom_info ( cli , mem_ctx , & domain_pol ,
2 , & ctr ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
2002-12-20 23:21:31 +03:00
TALLOC_CTX * ctx = talloc_init ( " rpc_info_internals " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " Domain Name: %s \n " , unistr2_tdup ( ctx , & ctr . info . inf2 . uni_domain ) ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " Domain SID: %s \n " , sid_str ) ;
2005-01-25 04:19:02 +03:00
d_printf ( " Sequence number: %u \n " , ctr . info . inf2 . seq_num . low ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " Num users: %u \n " , ctr . info . inf2 . num_domain_usrs ) ;
d_printf ( " Num domain groups: %u \n " , ctr . info . inf2 . num_domain_grps ) ;
d_printf ( " Num local groups: %u \n " , ctr . info . inf2 . num_local_grps ) ;
talloc_destroy ( ctx ) ;
}
done :
return result ;
}
/**
* ' net rpc info ' entrypoint .
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
int net_rpc_info ( 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-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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_getsid_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
2002-09-25 19:19:00 +04:00
{
fstring sid_str ;
sid_to_string ( sid_str , domain_sid ) ;
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
* */
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 .
* */
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_user_add_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2001-12-30 13:54:58 +03:00
int argc , const char * * argv ) {
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
const char * acct_name ;
uint16 acb_info ;
uint32 unknown , user_rid ;
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 ] ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Create domain user */
acb_info = ACB_NORMAL ;
unknown = 0xe005000b ; /* No idea what this is - a permission mask? */
result = cli_samr_create_dom_user ( cli , mem_ctx , & domain_pol ,
acct_name , acb_info , unknown ,
& user_pol , & user_rid ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
done :
2002-03-15 12:23:24 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to add user %s - %s \n " , acct_name ,
2002-03-17 07:36:35 +03:00
nt_errstr ( result ) ) ;
2002-03-15 12:23:24 +03:00
} else {
d_printf ( " Added user %s \n " , acct_name ) ;
}
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 ,
2004-02-08 13:59:09 +03:00
const char * domain_name ,
2002-04-05 05:36:28 +04:00
struct cli_state * cli ,
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 ;
if ( argc < 1 ) {
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
/* Get sam policy and domain handles */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get handle on user */
{
uint32 * user_rids , num_rids , * name_types ;
uint32 flags = 0x000003e8 ; /* Unknown */
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol ,
2002-07-15 14:35:28 +04:00
flags , 1 , & argv [ 0 ] ,
2002-04-05 05:36:28 +04:00
& num_rids , & user_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
user_rids [ 0 ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
}
/* Delete user */
result = cli_samr_delete_dom_user ( cli , mem_ctx , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Display results */
done :
return result ;
}
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 .
* */
static NTSTATUS rpc_user_rename_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv ) {
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 info_level = 7 ;
const char * old_name , * new_name ;
uint32 * user_rid ;
uint32 flags = 0x000003e8 ; /* Unknown */
uint32 num_rids , * name_types ;
uint32 num_names = 1 ;
const char * * names ;
SAM_USERINFO_CTR * user_ctr ;
SAM_USERINFO_CTR ctr ;
SAM_USER_INFO_7 info7 ;
if ( argc ! = 2 ) {
d_printf ( " New and old username must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
old_name = argv [ 0 ] ;
new_name = argv [ 1 ] ;
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( user_ctr ) ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
names = TALLOC_ARRAY ( mem_ctx , const char * , num_names ) ;
names [ 0 ] = old_name ;
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol ,
flags , num_names , names ,
& num_rids , & user_rid , & name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Open domain user */
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS , user_rid [ 0 ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Query user info */
result = cli_samr_query_userinfo ( cli , mem_ctx , & user_pol ,
info_level , & user_ctr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
ctr . switch_value = info_level ;
ctr . info . id7 = & info7 ;
init_sam_user_info7 ( & info7 , new_name ) ;
/* Set new name */
result = cli_samr_set_userinfo ( cli , mem_ctx , & user_pol ,
info_level , & cli - > user_session_key , & ctr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
done :
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to rename user from %s to %s - %s \n " , old_name , new_name ,
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 ,
2004-02-08 13:59:09 +03:00
const char * domain_name ,
2004-02-07 06:54:39 +03:00
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
POLICY_HND connect_pol , domain_pol , user_pol ;
SAM_USERINFO_CTR ctr ;
SAM_USER_INFO_24 p24 ;
uchar pwbuf [ 516 ] ;
const char * user ;
const char * new_password ;
char * prompt = NULL ;
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 */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get handle on user */
{
uint32 * user_rids , num_rids , * name_types ;
uint32 flags = 0x000003e8 ; /* Unknown */
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol ,
flags , 1 , & user ,
& num_rids , & user_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
user_rids [ 0 ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
}
/* Set password on account */
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( p24 ) ;
encode_pw_buffer ( pwbuf , new_password , STR_UNICODE ) ;
init_sam_user_info24 ( & p24 , ( char * ) pwbuf , 24 ) ;
ctr . switch_value = 24 ;
ctr . info . id24 = & p24 ;
result = cli_samr_set_userinfo ( cli , mem_ctx , & user_pol , 24 ,
& cli - > user_session_key , & ctr ) ;
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_user_info_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-04-05 05:36:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 * rids , num_rids , * name_types , num_names ;
uint32 flags = 0x000003e8 ; /* Unknown */
int i ;
char * * names ;
DOM_GID * user_gids ;
if ( argc < 1 ) {
d_printf ( " User must be specified \n " ) ;
rpc_user_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get handle on user */
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol ,
2002-07-15 14:35:28 +04:00
flags , 1 , & argv [ 0 ] ,
2002-04-05 05:36:28 +04:00
& num_rids , & rids , & name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
rids [ 0 ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
result = cli_samr_query_usergroups ( cli , mem_ctx , & user_pol ,
& num_rids , & user_gids ) ;
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
2005-03-19 01:31:44 +03:00
if ( num_rids ) {
2005-02-10 21:27:23 +03:00
rids = TALLOC_ARRAY ( mem_ctx , uint32 , num_rids ) ;
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
for ( i = 0 ; i < num_rids ; i + + )
rids [ i ] = user_gids [ i ] . g_rid ;
2002-04-05 05:36:28 +04:00
2005-02-10 21:27:23 +03:00
result = cli_samr_lookup_rids ( cli , mem_ctx , & domain_pol ,
2005-02-20 18:15:33 +03:00
num_rids , rids ,
2005-02-10 21:27:23 +03:00
& num_names , & names , & name_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
2005-02-10 21:27:23 +03:00
for ( i = 0 ; i < num_names ; i + + )
printf ( " %s \n " , names [ i ] ) ;
}
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_user_list_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-04-05 05:36:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
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
SAM_DISPINFO_CTR ctr ;
SAM_DISPINFO_1 info1 ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Query domain users */
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( info1 ) ;
ctr . sam . info1 = & info1 ;
if ( opt_long_list_entries )
d_printf ( " \n User name Comment " \
" \n ----------------------------- \n " ) ;
do {
fstring user , desc ;
2003-01-29 23:15:35 +03:00
uint32 max_entries , max_size ;
get_query_dispinfo_params (
loop_count , & max_entries , & max_size ) ;
2002-04-05 05:36:28 +04:00
result = cli_samr_query_dispinfo ( cli , mem_ctx , & domain_pol ,
& start_idx , 1 , & num_entries ,
2003-01-29 23:15:35 +03:00
max_entries , max_size , & ctr ) ;
loop_count + + ;
2002-04-05 05:36:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
unistr2_to_ascii ( user , & ( & ctr . sam . info1 - > str [ i ] ) - > uni_acct_name , sizeof ( user ) - 1 ) ;
if ( opt_long_list_entries )
unistr2_to_ascii ( desc , & ( & ctr . sam . info1 - > str [ i ] ) - > uni_acct_desc , sizeof ( desc ) - 1 ) ;
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 ) {
2002-04-05 05:36:28 +04:00
if ( opt_long_list_entries ) {
} else {
}
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_SAMR , 0 ,
2002-04-05 05:36:28 +04:00
rpc_user_list_internals ,
argc , argv ) ;
2001-12-05 03:26:36 +03:00
}
return net_run_function ( argc , argv , func , rpc_user_usage ) ;
}
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 ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
POLICY_HND connect_pol , domain_pol , group_pol , user_pol ;
BOOL group_is_primary = False ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
uint32 * group_rids , num_rids , * name_types , num_members ,
* group_attrs , group_rid ;
uint32 flags = 0x000003e8 ; /* Unknown */
/* char **names; */
int i ;
/* DOM_GID *user_gids; */
SAM_USERINFO_CTR * user_ctr ;
fstring temp ;
if ( argc < 1 ) {
d_printf ( " specify group \n " ) ;
rpc_group_usage ( argc , argv ) ;
return NT_STATUS_OK ; /* ok? */
}
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Request samr_connect failed \n " ) ;
goto done ;
}
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Request open_domain failed \n " ) ;
goto done ;
}
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol ,
flags , 1 , & argv [ 0 ] ,
& num_rids , & group_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Lookup of '%s' failed \n " , argv [ 0 ] ) ;
goto done ;
}
switch ( name_types [ 0 ] )
{
case SID_NAME_DOM_GRP :
result = cli_samr_open_group ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rids [ 0 ] , & group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Request open_group failed " ) ;
goto done ;
}
group_rid = group_rids [ 0 ] ;
result = cli_samr_query_groupmem ( cli , mem_ctx , & group_pol ,
& num_members , & group_rids ,
& group_attrs ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Unable to query group members of %s " , argv [ 0 ] ) ;
goto done ;
}
if ( opt_verbose ) {
d_printf ( " Domain Group %s (rid: %d) has %d members \n " ,
argv [ 0 ] , group_rid , num_members ) ;
}
/* Check if group is anyone's primary group */
for ( i = 0 ; i < num_members ; i + + )
{
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rids [ i ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Unable to open group member %d \n " , group_rids [ i ] ) ;
goto done ;
}
ZERO_STRUCT ( user_ctr ) ;
result = cli_samr_query_userinfo ( cli , mem_ctx , & user_pol ,
21 , & user_ctr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Unable to lookup userinfo for group member %d \n " , group_rids [ i ] ) ;
goto done ;
}
if ( user_ctr - > info . id21 - > group_rid = = group_rid ) {
unistr2_to_ascii ( temp , & ( user_ctr - > info . id21 ) - > uni_user_name ,
sizeof ( temp ) - 1 ) ;
if ( opt_verbose )
d_printf ( " Group is primary group of %s \n " , temp ) ;
group_is_primary = True ;
}
cli_samr_close ( cli , mem_ctx , & user_pol ) ;
}
if ( group_is_primary ) {
d_printf ( " Unable to delete group because some of it's "
" members have it as primary group \n " ) ;
result = NT_STATUS_MEMBERS_PRIMARY_GROUP ;
goto done ;
}
/* remove all group members */
for ( i = 0 ; i < num_members ; i + + )
{
if ( opt_verbose )
d_printf ( " Remove group member %d... " , group_rids [ i ] ) ;
result = cli_samr_del_groupmem ( cli , mem_ctx , & group_pol , group_rids [ i ] ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
if ( opt_verbose )
d_printf ( " ok \n " ) ;
} else {
if ( opt_verbose )
d_printf ( " failed \n " ) ;
goto done ;
}
}
result = cli_samr_delete_dom_group ( cli , mem_ctx , & group_pol ) ;
break ;
/* removing a local group is easier... */
case SID_NAME_ALIAS :
result = cli_samr_open_alias ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rids [ 0 ] , & group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Request open_alias failed \n " ) ;
goto done ;
}
result = cli_samr_delete_dom_alias ( cli , mem_ctx , & group_pol ) ;
break ;
default :
d_printf ( " %s is of type %s. This command is only for deleting local or global groups \n " ,
argv [ 0 ] , sid_type_lookup ( name_types [ 0 ] ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( NT_STATUS_IS_OK ( result ) ) {
if ( opt_verbose )
d_printf ( " Deleted %s '%s' \n " , sid_type_lookup ( name_types [ 0 ] ) , argv [ 0 ] ) ;
} else {
d_printf ( " Deleting of %s failed: %s \n " , argv [ 0 ] ,
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 ) ;
}
2004-02-24 21:00:41 +03:00
static NTSTATUS
rpc_group_add_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
POLICY_HND connect_pol , domain_pol , group_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
GROUP_INFO_CTR group_info ;
if ( argc ! = 1 ) {
d_printf ( " Group name must be specified \n " ) ;
rpc_group_usage ( argc , argv ) ;
return NT_STATUS_OK ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Create the group */
result = cli_samr_create_dom_group ( cli , mem_ctx , & domain_pol ,
argv [ 0 ] , MAXIMUM_ALLOWED_ACCESS ,
& group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
if ( strlen ( opt_comment ) = = 0 ) goto done ;
/* We've got a comment to set */
group_info . switch_value1 = 4 ;
init_samr_group_info4 ( & group_info . group . info4 , opt_comment ) ;
result = cli_samr_set_groupinfo ( cli , mem_ctx , & group_pol , & group_info ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
done :
if ( NT_STATUS_IS_OK ( result ) )
DEBUG ( 5 , ( " add group succeeded \n " ) ) ;
else
d_printf ( " add group failed: %s \n " , nt_errstr ( result ) ) ;
return result ;
}
2004-02-28 21:41:16 +03:00
static NTSTATUS
rpc_alias_add_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
POLICY_HND connect_pol , domain_pol , alias_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
ALIAS_INFO_CTR alias_info ;
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 ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
/* Create the group */
result = cli_samr_create_dom_alias ( cli , mem_ctx , & domain_pol ,
argv [ 0 ] , & alias_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) goto done ;
if ( strlen ( opt_comment ) = = 0 ) goto done ;
/* We've got a comment to set */
alias_info . switch_value1 = 3 ;
alias_info . switch_value2 = 3 ;
init_samr_alias_info3 ( & alias_info . alias . info3 , opt_comment ) ;
result = cli_samr_set_aliasinfo ( cli , mem_ctx , & alias_pol , & alias_info ) ;
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
2005-01-25 04:19:02 +03:00
d_printf ( " 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 ) ;
}
2004-02-28 21:41:16 +03:00
static NTSTATUS
get_sid_from_name ( struct cli_state * cli , TALLOC_CTX * mem_ctx , const char * name ,
DOM_SID * sid , enum SID_NAME_USE * type )
{
int current_pipe = cli - > pipe_idx ;
DOM_SID * sids = NULL ;
uint32 * types = NULL ;
POLICY_HND lsa_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
if ( current_pipe ! = PI_LSARPC ) {
if ( current_pipe ! = - 1 )
cli_nt_session_close ( cli ) ;
if ( ! cli_nt_session_open ( cli , PI_LSARPC ) )
goto done ;
}
result = cli_lsa_open_policy ( cli , mem_ctx , False ,
SEC_RIGHTS_MAXIMUM_ALLOWED , & lsa_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = cli_lsa_lookup_names ( cli , mem_ctx , & lsa_pol , 1 ,
& name , & sids , & types ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
sid_copy ( sid , & sids [ 0 ] ) ;
* type = types [ 0 ] ;
}
cli_lsa_close ( cli , mem_ctx , & lsa_pol ) ;
done :
if ( current_pipe ! = PI_LSARPC ) {
cli_nt_session_close ( cli ) ;
if ( current_pipe ! = - 1 )
cli_nt_session_open ( cli , current_pipe ) ;
}
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 ;
}
static NTSTATUS
rpc_add_groupmem ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
const DOM_SID * group_sid , const char * member )
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 group_rid ;
POLICY_HND group_pol ;
uint32 num_rids ;
uint32 * rids = NULL ;
uint32 * rid_types = NULL ;
DOM_SID sid ;
sid_copy ( & sid , group_sid ) ;
if ( ! sid_split_rid ( & sid , & group_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , 1000 ,
1 , & member ,
& num_rids , & rids , & rid_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not lookup up group member %s \n " , member ) ;
goto done ;
}
result = cli_samr_open_group ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rid , & group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = cli_samr_add_groupmem ( cli , mem_ctx , & group_pol , rids [ 0 ] ) ;
done :
cli_samr_close ( cli , mem_ctx , & connect_pol ) ;
return result ;
}
static NTSTATUS
rpc_add_aliasmem ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
const DOM_SID * alias_sid , const char * member )
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 alias_rid ;
POLICY_HND alias_pol ;
DOM_SID member_sid ;
enum SID_NAME_USE member_type ;
DOM_SID sid ;
sid_copy ( & sid , alias_sid ) ;
if ( ! sid_split_rid ( & sid , & alias_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
result = get_sid_from_name ( cli , mem_ctx , member ,
& member_sid , & member_type ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not lookup up group member %s \n " , member ) ;
return result ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_alias ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
alias_rid , & alias_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_add_aliasmem ( cli , mem_ctx , & alias_pol , & member_sid ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
done :
cli_samr_close ( cli , mem_ctx , & connect_pol ) ;
return result ;
}
static NTSTATUS
rpc_group_addmem_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
DOM_SID group_sid ;
enum SID_NAME_USE group_type ;
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 ) ) ) {
d_printf ( " Could not lookup group name %s \n " , argv [ 0 ] ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( group_type = = SID_NAME_DOM_GRP ) {
NTSTATUS result = rpc_add_groupmem ( cli , mem_ctx ,
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not add %s to %s: %s \n " ,
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 ) {
NTSTATUS result = rpc_add_aliasmem ( cli , mem_ctx ,
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not add %s to %s: %s \n " ,
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
}
2004-02-29 15:47:45 +03:00
d_printf ( " Can only add members to global or local groups which "
" %s is not \n " , argv [ 0 ] ) ;
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 ) ;
}
static NTSTATUS
rpc_del_groupmem ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
const DOM_SID * group_sid , const char * member )
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 group_rid ;
POLICY_HND group_pol ;
uint32 num_rids ;
uint32 * rids = NULL ;
uint32 * rid_types = NULL ;
DOM_SID sid ;
sid_copy ( & sid , group_sid ) ;
if ( ! sid_split_rid ( & sid , & group_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , 1000 ,
1 , & member ,
& num_rids , & rids , & rid_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not lookup up group member %s \n " , member ) ;
goto done ;
}
result = cli_samr_open_group ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
group_rid , & group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = cli_samr_del_groupmem ( cli , mem_ctx , & group_pol , rids [ 0 ] ) ;
done :
cli_samr_close ( cli , mem_ctx , & connect_pol ) ;
return result ;
}
static NTSTATUS
rpc_del_aliasmem ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
const DOM_SID * alias_sid , const char * member )
{
POLICY_HND connect_pol , domain_pol ;
NTSTATUS result ;
uint32 alias_rid ;
POLICY_HND alias_pol ;
DOM_SID member_sid ;
enum SID_NAME_USE member_type ;
DOM_SID sid ;
sid_copy ( & sid , alias_sid ) ;
if ( ! sid_split_rid ( & sid , & alias_rid ) )
return NT_STATUS_UNSUCCESSFUL ;
result = get_sid_from_name ( cli , mem_ctx , member ,
& member_sid , & member_type ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Could not lookup up group member %s \n " , member ) ;
return result ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_alias ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
alias_rid , & alias_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_del_aliasmem ( cli , mem_ctx , & alias_pol , & member_sid ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
done :
cli_samr_close ( cli , mem_ctx , & connect_pol ) ;
return result ;
}
static NTSTATUS
rpc_group_delmem_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
DOM_SID group_sid ;
enum SID_NAME_USE group_type ;
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 ) ) ) {
d_printf ( " Could not lookup group name %s \n " , argv [ 0 ] ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( group_type = = SID_NAME_DOM_GRP ) {
NTSTATUS result = rpc_del_groupmem ( cli , mem_ctx ,
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-03-04 20:51:29 +03:00
d_printf ( " 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 ) {
NTSTATUS result = rpc_del_aliasmem ( cli , mem_ctx ,
& group_sid , argv [ 1 ] ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-03-04 20:47:14 +03:00
d_printf ( " 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
}
2004-02-29 15:47:45 +03:00
d_printf ( " Can only delete members from global or local groups which "
" %s is not \n " , argv [ 0 ] ) ;
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_group_list_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
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 ;
2002-07-15 14:35:28 +04:00
struct acct_info * groups ;
DOM_SID global_sid_Builtin ;
2003-11-28 18:10:00 +03:00
BOOL global = False ;
BOOL local = False ;
BOOL builtin = False ;
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
string_to_sid ( & global_sid_Builtin , " S-1-5-32 " ) ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
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 {
2003-06-12 20:21:22 +04:00
SAM_DISPINFO_CTR ctr ;
SAM_DISPINFO_3 info3 ;
uint32 max_size ;
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( info3 ) ;
ctr . sam . info3 = & info3 ;
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 ) ;
result = cli_samr_query_dispinfo ( cli , mem_ctx , & domain_pol ,
& start_idx , 3 , & num_entries ,
max_entries , max_size , & ctr ) ;
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 ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
fstring group , desc ;
unistr2_to_ascii ( group , & ( & ctr . sam . info3 - > str [ i ] ) - > uni_grp_name , sizeof ( group ) - 1 ) ;
unistr2_to_ascii ( desc , & ( & ctr . sam . info3 - > str [ i ] ) - > uni_grp_desc , sizeof ( desc ) - 1 ) ;
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 ;
2004-06-01 18:45:49 +04:00
/* The max_size field in cli_samr_enum_als_groups is more like
* an account_control field with indiviual bits what to
* retrieve . Set this to 0xffff as NT4 usrmgr . exe does to get
* everything . I ' m too lazy ( sorry ) to get this through to
* rpc_parse / etc . Volker */
2002-07-15 14:35:28 +04:00
result = cli_samr_enum_als_groups ( cli , mem_ctx , & domain_pol ,
2004-06-01 18:45:49 +04:00
& start_idx , 0xffff ,
2002-07-15 14:35:28 +04:00
& groups , & num_entries ) ;
2003-06-12 20:21:22 +04: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 ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
char * description = NULL ;
if ( opt_long_list_entries ) {
POLICY_HND alias_pol ;
ALIAS_INFO_CTR ctr ;
if ( ( NT_STATUS_IS_OK ( cli_samr_open_alias ( cli , mem_ctx ,
& domain_pol ,
0x8 ,
groups [ i ] . rid ,
& alias_pol ) ) ) & &
( NT_STATUS_IS_OK ( cli_samr_query_alias_info ( cli , mem_ctx ,
& alias_pol , 3 ,
& ctr ) ) ) & &
( NT_STATUS_IS_OK ( cli_samr_close ( cli , mem_ctx ,
& alias_pol ) ) ) ) {
description = unistr2_tdup ( mem_ctx ,
& ctr . alias . info3 . uni_acct_desc ) ;
}
}
if ( description ! = NULL ) {
2002-07-15 14:35:28 +04:00
printf ( " %-21.21s %-50.50s \n " ,
groups [ i ] . acct_name ,
2003-06-12 20:21:22 +04:00
description ) ;
} else {
2003-12-01 17:12:26 +03:00
printf ( " %s \n " , groups [ i ] . acct_name ) ;
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
cli_samr_close ( cli , mem_ctx , & domain_pol ) ;
/* Get builtin policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& global_sid_Builtin , & domain_pol ) ;
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 ;
2002-07-15 14:35:28 +04:00
result = cli_samr_enum_als_groups ( cli , mem_ctx , & domain_pol ,
& start_idx , max_entries ,
& groups , & 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 ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_entries ; i + + ) {
2003-06-12 20:21:22 +04:00
char * description = NULL ;
if ( opt_long_list_entries ) {
POLICY_HND alias_pol ;
ALIAS_INFO_CTR ctr ;
if ( ( NT_STATUS_IS_OK ( cli_samr_open_alias ( cli , mem_ctx ,
& domain_pol ,
0x8 ,
groups [ i ] . rid ,
& alias_pol ) ) ) & &
( NT_STATUS_IS_OK ( cli_samr_query_alias_info ( cli , mem_ctx ,
& alias_pol , 3 ,
& ctr ) ) ) & &
( NT_STATUS_IS_OK ( cli_samr_close ( cli , mem_ctx ,
& alias_pol ) ) ) ) {
description = unistr2_tdup ( mem_ctx ,
& ctr . alias . info3 . uni_acct_desc ) ;
}
}
if ( description ! = NULL ) {
2002-07-15 14:35:28 +04:00
printf ( " %-21.21s %-50.50s \n " ,
groups [ i ] . acct_name ,
2003-06-12 20:21:22 +04:00
description ) ;
} else {
2003-12-01 17:12:26 +03:00
printf ( " %s \n " , groups [ i ] . acct_name ) ;
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
static NTSTATUS
rpc_list_group_members ( struct cli_state * cli , 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 ;
2003-11-26 13:07:07 +03:00
uint32 num_members , * group_rids , * group_attrs ;
uint32 num_names ;
char * * names ;
uint32 * name_types ;
int i ;
2004-02-09 21:19:25 +03:00
fstring sid_str ;
sid_to_string ( sid_str , domain_sid ) ;
2003-11-26 13:07:07 +03:00
2004-02-09 21:19:25 +03:00
result = cli_samr_open_group ( cli , mem_ctx , domain_pol ,
2003-11-26 13:07:07 +03:00
MAXIMUM_ALLOWED_ACCESS ,
2004-02-09 21:19:25 +03:00
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
result = cli_samr_query_groupmem ( cli , mem_ctx , & group_pol ,
& num_members , & group_rids ,
& group_attrs ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
2004-02-09 21:19:25 +03:00
return result ;
2003-11-26 13:07:07 +03:00
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
2005-02-20 18:15:33 +03:00
result = cli_samr_lookup_rids ( cli , mem_ctx , domain_pol ,
2003-11-27 20:31:18 +03:00
this_time , group_rids ,
& num_names , & names , & name_types ) ;
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 ,
group_rids [ i ] , domain_name , names [ i ] ,
SID_NAME_USER ) ;
} else {
printf ( " %s \\ %s \n " , domain_name , names [ i ] ) ;
}
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 ;
}
static NTSTATUS
rpc_list_alias_members ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * domain_pol , uint32 rid )
{
NTSTATUS result ;
POLICY_HND alias_pol , lsa_pol ;
uint32 num_members ;
DOM_SID * alias_sids ;
char * * domains ;
char * * names ;
uint32 * types ;
int i ;
result = cli_samr_open_alias ( cli , mem_ctx , domain_pol ,
MAXIMUM_ALLOWED_ACCESS , rid , & alias_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_query_aliasmem ( cli , mem_ctx , & alias_pol ,
& num_members , & alias_sids ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Couldn't list alias members \n " ) ;
return result ;
}
2004-02-17 13:08:18 +03:00
if ( num_members = = 0 ) {
return NT_STATUS_OK ;
}
2004-02-09 21:19:25 +03:00
cli_nt_session_close ( cli ) ;
if ( ! cli_nt_session_open ( cli , PI_LSARPC ) ) {
d_printf ( " Couldn't open LSA pipe \n " ) ;
return result ;
}
result = cli_lsa_open_policy ( cli , mem_ctx , True ,
SEC_RIGHTS_MAXIMUM_ALLOWED , & lsa_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Couldn't open LSA policy handle \n " ) ;
return result ;
}
result = cli_lsa_lookup_sids ( cli , mem_ctx , & lsa_pol , num_members ,
alias_sids ,
& domains , & names , & types ) ;
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) ) {
d_printf ( " Couldn't lookup SIDs \n " ) ;
return result ;
}
for ( i = 0 ; i < num_members ; i + + ) {
fstring sid_str ;
sid_to_string ( sid_str , & alias_sids [ i ] ) ;
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 ) ;
}
}
return NT_STATUS_OK ;
}
static NTSTATUS
rpc_group_members_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
NTSTATUS result ;
POLICY_HND connect_pol , domain_pol ;
uint32 num_rids , * rids , * rid_types ;
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , 1000 ,
1 , argv , & num_rids , & rids , & rid_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
/* Ok, did not find it in the global sam, try with builtin */
DOM_SID sid_Builtin ;
cli_samr_close ( cli , mem_ctx , & domain_pol ) ;
string_to_sid ( & sid_Builtin , " S-1-5-32 " ) ;
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
& sid_Builtin , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Couldn't find group %s \n " , argv [ 0 ] ) ;
return result ;
}
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , 1000 ,
1 , argv , & num_rids ,
& rids , & rid_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Couldn't find group %s \n " , argv [ 0 ] ) ;
return result ;
}
}
if ( num_rids ! = 1 ) {
d_printf ( " Couldn't find group %s \n " , argv [ 0 ] ) ;
return result ;
}
if ( rid_types [ 0 ] = = SID_NAME_DOM_GRP ) {
return rpc_list_group_members ( cli , mem_ctx , domain_name ,
domain_sid , & domain_pol ,
rids [ 0 ] ) ;
}
if ( rid_types [ 0 ] = = SID_NAME_ALIAS ) {
return rpc_list_alias_members ( cli , mem_ctx , & domain_pol ,
rids [ 0 ] ) ;
}
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 ) ;
}
2004-06-02 18:25:29 +04:00
static NTSTATUS
rpc_group_rename_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
NTSTATUS result ;
POLICY_HND connect_pol , domain_pol , group_pol ;
uint32 num_rids , * rids , * rid_types ;
GROUP_INFO_CTR ctr ;
if ( argc ! = 2 ) {
d_printf ( " Usage: 'net rpc group rename group newname' \n " ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* Get sam policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , 1000 ,
1 , argv , & num_rids , & rids , & rid_types ) ;
if ( num_rids ! = 1 ) {
d_printf ( " Couldn't find group %s \n " , argv [ 0 ] ) ;
return result ;
}
if ( rid_types [ 0 ] ! = SID_NAME_DOM_GRP ) {
d_printf ( " Can only rename domain groups \n " ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
result = cli_samr_open_group ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
rids [ 0 ] , & group_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
ZERO_STRUCT ( ctr ) ;
ctr . switch_value1 = 2 ;
init_samr_group_info2 ( & ctr . group . info2 , argv [ 1 ] ) ;
result = cli_samr_set_groupinfo ( cli , mem_ctx , & group_pol , & ctr ) ;
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 ) {
if ( opt_long_list_entries ) {
} else {
}
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_share_add_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
WERROR result ;
char * sharename = talloc_strdup ( mem_ctx , argv [ 0 ] ) ;
char * path ;
uint32 type = 0 ; /* only allow disk shares to be added */
uint32 num_users = 0 , perms = 0 ;
char * password = NULL ; /* don't allow a share password */
2004-08-10 18:27:17 +04:00
uint32 level = 2 ;
2002-07-15 14:35:28 +04:00
path = strchr ( sharename , ' = ' ) ;
if ( ! path )
return NT_STATUS_UNSUCCESSFUL ;
* path + + = ' \0 ' ;
result = cli_srvsvc_net_share_add ( cli , mem_ctx , sharename , type ,
opt_comment , perms , opt_maxusers ,
2004-08-10 18:27:17 +04:00
num_users , path , password ,
level , NULL ) ;
2002-07-15 14:35:28 +04:00
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_share_del_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
WERROR result ;
result = cli_srvsvc_net_share_del ( cli , mem_ctx , argv [ 0 ] ) ;
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
/**
* 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
*
* @ param info1 pointer to SRV_SHARE_INFO_1 to format
* */
static void display_share_info_1 ( SRV_SHARE_INFO_1 * info1 )
{
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 ) ;
if ( opt_long_list_entries ) {
2004-02-11 17:59:08 +03:00
d_printf ( " %-12s %-8.8s %-50s \n " ,
2002-07-15 14:35:28 +04:00
netname , share_type [ info1 - > info_1 . type ] , remark ) ;
} else {
2004-02-11 17:59:08 +03:00
d_printf ( " %s \n " , netname ) ;
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_share_list_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
SRV_SHARE_INFO_CTR ctr ;
WERROR result ;
ENUM_HND hnd ;
uint32 preferred_len = 0xffffffff , i ;
init_enum_hnd ( & hnd , 0 ) ;
result = cli_srvsvc_net_share_enum (
cli , mem_ctx , 1 , & ctr , preferred_len , & hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) )
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 " ) ;
}
for ( i = 0 ; i < ctr . num_entries ; i + + )
display_share_info_1 ( & ctr . share . info1 [ i ] ) ;
done :
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
2004-08-10 18:27:17 +04:00
/**
* Migrate shares 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 .
* */
static NTSTATUS
rpc_share_migrate_shares_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
WERROR result ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
SRV_SHARE_INFO_CTR ctr_src ;
ENUM_HND hnd ;
uint32 type = 0 ; /* only allow disk shares to be added */
uint32 num_uses = 0 , perms = 0 , max_uses = 0 ;
char * password = NULL ; /* don't allow a share password */
uint32 preferred_len = 0xffffffff , i ;
BOOL got_dst_srvsvc_pipe = False ;
struct cli_state * cli_dst = NULL ;
uint32 level = 502 ; /* includes secdesc */
SEC_DESC * share_sd = NULL ;
init_enum_hnd ( & hnd , 0 ) ;
result = cli_srvsvc_net_share_enum (
cli , mem_ctx , level , & ctr_src , preferred_len , & hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) )
goto done ;
/* connect local PI_SRVSVC */
2004-08-27 01:37:20 +04:00
nt_status = connect_pipe ( & cli_dst , PI_SRVSVC , & got_dst_srvsvc_pipe ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
for ( i = 0 ; i < ctr_src . num_entries ; i + + ) {
fstring netname = " " , remark = " " , path = " " ;
/* reset error-code */
nt_status = NT_STATUS_UNSUCCESSFUL ;
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 ) ;
num_uses = ctr_src . share . info502 [ i ] . info_502 . num_uses ;
max_uses = ctr_src . share . info502 [ i ] . info_502 . max_uses ;
perms = ctr_src . share . info502 [ i ] . info_502 . perms ;
if ( opt_acls )
share_sd = dup_sec_desc (
mem_ctx , ctr_src . share . info502 [ i ] . info_502_str . sd ) ;
/* since we do not have NetShareGetInfo implemented in samba3 we
only can skip inside the enum - ctr_src */
if ( argc = = 1 ) {
char * one_share = talloc_strdup ( mem_ctx , argv [ 0 ] ) ;
if ( ! strequal ( netname , one_share ) )
continue ;
}
/* skip builtin shares */
/* FIXME: should print$ be added too ? */
if ( strequal ( netname , " IPC$ " ) | | strequal ( netname , " ADMIN$ " ) | |
strequal ( netname , " global " ) )
continue ;
/* only work with file-shares */
if ( ! cli_send_tconX ( cli , netname , " A: " , " " , 0 ) ) {
2004-08-21 00:13:05 +04:00
d_printf ( " skipping [%s]: not a file share. \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
if ( ! cli_tdis ( cli ) )
goto done ;
/* finallly add the share on the dst server
please note that samba currently does not allow to
add a share without existing directory */
printf ( " migrating: [%s], path: %s, comment: %s, %s share-ACLs \n " ,
netname , path , remark , opt_acls ? " including " : " without " ) ;
if ( opt_verbose & & opt_acls )
display_sec_desc ( share_sd ) ;
result = cli_srvsvc_net_share_add ( cli_dst , mem_ctx , netname , type ,
remark , perms , max_uses ,
num_uses , path , password ,
level , share_sd ) ;
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ALREADY_EXISTS ) ) {
2004-08-21 00:13:05 +04:00
printf ( " [%s] does already exist \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
2004-08-21 00:13:05 +04:00
}
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot add share: %s \n " , dos_errstr ( result ) ) ;
goto done ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_dst_srvsvc_pipe ) {
cli_nt_session_close ( cli_dst ) ;
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 ) ;
}
typedef struct copy_clistate {
TALLOC_CTX * mem_ctx ;
struct cli_state * cli_share_src ;
struct cli_state * cli_share_dst ;
const char * cwd ;
} copy_clistate ;
/**
* 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
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
struct copy_clistate * local_state = ( struct copy_clistate * ) state ;
fstring filename , new_mask , dir ;
if ( strequal ( f - > name , " . " ) | | strequal ( f - > name , " .. " ) )
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 ) ;
/* create that directory */
nt_status = net_copy_file ( local_state - > mem_ctx ,
local_state - > cli_share_src ,
local_state - > cli_share_dst ,
dir , dir ,
2004-08-21 00:13:05 +04:00
opt_acls ? True : False ,
opt_attrs ? True : False ,
opt_timestamps ? True : False ,
False ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
printf ( " could not copy dir %s: %s \n " ,
dir , nt_errstr ( nt_status ) ) ;
/* search below that directory */
fstrcpy ( new_mask , dir ) ;
fstrcat ( new_mask , " \\ * " ) ;
if ( ! sync_files ( local_state - > mem_ctx ,
local_state - > cli_share_src ,
local_state - > cli_share_dst ,
new_mask , dir ) )
printf ( " could not sync files \n " ) ;
return ;
}
/* FILE */
fstrcpy ( filename , local_state - > cwd ) ;
fstrcat ( filename , " \\ " ) ;
fstrcat ( filename , f - > name ) ;
DEBUG ( 3 , ( " got file: %s \n " , filename ) ) ;
nt_status = net_copy_file ( local_state - > mem_ctx ,
local_state - > cli_share_src ,
local_state - > cli_share_dst ,
filename , filename ,
2004-08-21 00:13:05 +04:00
opt_acls ? True : False ,
opt_attrs ? True : False ,
opt_timestamps ? True : False ,
True ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
printf ( " could not copy file %s: %s \n " ,
filename , nt_errstr ( nt_status ) ) ;
}
/**
* sync files , can be called recursivly to list files
* and then call copy_fn for each file
*
* @ param mem_ctx TALLOC_CTX
* @ param cli_share_src a connected share on the originating server
* @ param cli_share_dst a connected share on the destination server
* @ param mask the current search mask
* @ param cwd the current path
*
* @ return Boolean result
* */
BOOL sync_files ( TALLOC_CTX * mem_ctx ,
struct cli_state * cli_share_src ,
struct cli_state * cli_share_dst ,
pstring mask , fstring cwd )
{
uint16 attribute = aSYSTEM | aHIDDEN | aDIR ;
struct copy_clistate clistate ;
clistate . mem_ctx = mem_ctx ;
clistate . cli_share_src = cli_share_src ;
clistate . cli_share_dst = cli_share_dst ;
clistate . cwd = cwd ;
DEBUG ( 3 , ( " calling cli_list with mask: %s \n " , mask ) ) ;
if ( cli_list ( cli_share_src , mask , attribute , copy_fn , & clistate ) = = - 1 ) {
d_printf ( " listing %s failed with error: %s \n " ,
mask , cli_errstr ( cli_share_src ) ) ;
return False ;
}
return True ;
}
/**
* 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 .
* */
static NTSTATUS
rpc_share_migrate_files_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
WERROR result ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
SRV_SHARE_INFO_CTR ctr_src ;
ENUM_HND hnd ;
uint32 preferred_len = 0xffffffff , i ;
uint32 level = 2 ;
struct cli_state * cli_share_src = NULL ;
struct cli_state * cli_share_dst = NULL ;
BOOL got_src_share = False ;
BOOL got_dst_share = False ;
pstring 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
init_enum_hnd ( & hnd , 0 ) ;
result = cli_srvsvc_net_share_enum (
cli , mem_ctx , level , & ctr_src , preferred_len , & hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) )
goto done ;
for ( i = 0 ; i < ctr_src . num_entries ; i + + ) {
fstring netname = " " , remark = " " , path = " " ;
rpcstr_pull_unistr2_fstring (
netname , & ctr_src . share . info2 [ i ] . info_2_str . uni_netname ) ;
rpcstr_pull_unistr2_fstring (
remark , & ctr_src . share . info2 [ i ] . info_2_str . uni_remark ) ;
rpcstr_pull_unistr2_fstring (
path , & ctr_src . share . info2 [ i ] . info_2_str . uni_path ) ;
/* since we do not have NetShareGetInfo implemented in samba3 we
only can skip inside the enum - ctr_src */
if ( argc = = 1 ) {
char * one_share = talloc_strdup ( mem_ctx , argv [ 0 ] ) ;
if ( ! strequal ( netname , one_share ) )
continue ;
}
/* skip builtin and hidden shares
In particular , one might not want to mirror whole discs : ) */
if ( strequal ( netname , " IPC$ " ) | | strequal ( netname , " ADMIN$ " ) )
continue ;
if ( strequal ( netname , " print$ " ) | | netname [ 1 ] = = ' $ ' ) {
2004-08-21 00:13:05 +04:00
d_printf ( " skipping [%s]: builtin/hidden share \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
if ( opt_exclude & & in_list ( netname , ( char * ) opt_exclude , False ) ) {
2004-08-21 00:13:05 +04:00
printf ( " excluding [%s] \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
/* only work with file-shares */
if ( ! cli_send_tconX ( cli , netname , " A: " , " " , 0 ) ) {
2004-08-21 00:13:05 +04:00
d_printf ( " skipping [%s]: not a file share. \n " , netname ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
if ( ! cli_tdis ( cli ) )
return NT_STATUS_UNSUCCESSFUL ;
2004-08-21 00:13:05 +04:00
printf ( " syncing [%s] files and directories %s ACLs, %s DOS Attributes %s \n " ,
netname ,
opt_acls ? " including " : " without " ,
opt_attrs ? " including " : " without " ,
opt_timestamps ? " (preserving timestamps) " : " " ) ;
2004-08-10 18:27:17 +04:00
/* open share source */
nt_status = connect_to_service ( & cli_share_src , & cli - > dest_ip ,
cli - > desthost , netname , " A: " ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
got_src_share = True ;
/* open share destination */
2004-08-27 01:37:20 +04:00
nt_status = connect_to_service ( & cli_share_dst , NULL ,
dst , netname , " A: " ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
got_dst_share = True ;
/* now call the filesync */
pstrcpy ( mask , " \\ * " ) ;
if ( ! sync_files ( mem_ctx , cli_share_src , cli_share_dst , mask , NULL ) ) {
d_printf ( " could not sync files for share: %s \n " , netname ) ;
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_src_share )
cli_shutdown ( cli_share_src ) ;
if ( got_dst_share )
cli_shutdown ( cli_share_dst ) ;
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 ) ;
}
/**
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 ;
}
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 ;
#if 0
ret = run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_migrate_shares_security_internals , argc , argv ) ;
if ( ret )
return ret ;
# endif
return run_rpc_command ( NULL , PI_SRVSVC , 0 , rpc_share_migrate_files_internals , argc , argv ) ;
}
/**
* ' 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 } ,
2004-08-10 18:27:17 +04:00
/* {"security", rpc_share_migrate_security},*/
{ " shares " , rpc_share_migrate_shares } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , rpc_share_usage ) ;
}
2004-10-12 15:58:01 +04:00
struct full_alias {
DOM_SID sid ;
int num_members ;
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 .
*/
static NTSTATUS
rpc_fetch_domain_aliases ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * connect_pol ,
const DOM_SID * domain_sid )
{
uint32 start_idx , max_entries , num_entries , i ;
struct acct_info * groups ;
NTSTATUS result ;
POLICY_HND domain_pol ;
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return result ;
start_idx = 0 ;
max_entries = 250 ;
do {
result = cli_samr_enum_als_groups ( cli , mem_ctx , & domain_pol ,
& start_idx , max_entries ,
& groups , & num_entries ) ;
for ( i = 0 ; i < num_entries ; i + + ) {
POLICY_HND alias_pol ;
struct full_alias alias ;
DOM_SID * members ;
int j ;
result = cli_samr_open_alias ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
groups [ i ] . rid ,
& alias_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = cli_samr_query_aliasmem ( cli , mem_ctx ,
& alias_pol ,
& alias . num_members ,
& members ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = cli_samr_close ( cli , mem_ctx , & alias_pol ) ;
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 ] ,
& members [ j ] ) ;
}
sid_copy ( & alias . sid , domain_sid ) ;
sid_append_rid ( & alias . sid , groups [ i ] . rid ) ;
push_alias ( mem_ctx , & alias ) ;
}
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
result = NT_STATUS_OK ;
done :
cli_samr_close ( cli , mem_ctx , & domain_pol ) ;
return result ;
}
/*
* Dump server_aliases as names for debugging purposes .
*/
static NTSTATUS
rpc_aliaslist_dump ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
int i ;
NTSTATUS result ;
POLICY_HND lsa_pol ;
result = cli_lsa_open_policy ( cli , mem_ctx , True ,
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 ;
uint32 * types ;
int j ;
struct full_alias * alias = & server_aliases [ i ] ;
result = cli_lsa_lookup_sids ( cli , mem_ctx , & lsa_pol , 1 ,
& 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 ;
}
result = cli_lsa_lookup_sids ( cli , mem_ctx , & lsa_pol ,
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 " ) ) ;
}
cli_lsa_close ( cli , mem_ctx , & lsa_pol ) ;
return NT_STATUS_OK ;
}
/*
* Fetch a list of all server aliases and their members into
* server_aliases .
*/
static NTSTATUS
rpc_aliaslist_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
NTSTATUS result ;
POLICY_HND connect_pol ;
DOM_SID global_sid_Builtin ;
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
string_to_sid ( & global_sid_Builtin , " S-1-5-32 " ) ;
result = rpc_fetch_domain_aliases ( cli , mem_ctx , & connect_pol ,
& global_sid_Builtin ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
result = rpc_fetch_domain_aliases ( cli , mem_ctx , & connect_pol ,
domain_sid ) ;
cli_samr_close ( cli , mem_ctx , & connect_pol ) ;
done :
return result ;
}
static void init_user_token ( NT_USER_TOKEN * token , DOM_SID * user_sid )
{
DOM_SID global_sid_World ;
DOM_SID global_sid_Network ;
DOM_SID global_sid_Authenticated_Users ;
string_to_sid ( & global_sid_World , " S-1-1-0 " ) ;
string_to_sid ( & global_sid_Network , " S-1-5-2 " ) ;
string_to_sid ( & global_sid_Authenticated_Users , " S-1-5-11 " ) ;
token - > num_sids = 4 ;
2004-12-07 21:25:53 +03:00
token - > user_sids = SMB_MALLOC_ARRAY ( DOM_SID , 4 ) ;
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 ) ;
}
static BOOL is_sid_in_token ( NT_USER_TOKEN * token , DOM_SID * sid )
{
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 ) ;
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 + + ) {
d_printf ( " %s \n " , sid_string_static ( & token - > token . user_sids [ i ] ) ) ;
}
}
static BOOL is_alias_member ( DOM_SID * sid , struct full_alias * alias )
{
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 ] ) ;
}
}
static BOOL get_user_sids ( const char * domain , const char * user ,
NT_USER_TOKEN * token )
{
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 ) ;
result = winbindd_request ( WINBINDD_LOOKUPNAME , & request , & response ) ;
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 ) ;
result = winbindd_request ( WINBINDD_GETGROUPS , & request , & response ) ;
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 + + ) {
gid_t gid = ( ( gid_t * ) response . extra_data ) [ i ] ;
DOM_SID sid ;
struct winbindd_request sidrequest ;
struct winbindd_response sidresponse ;
ZERO_STRUCT ( sidrequest ) ;
ZERO_STRUCT ( sidresponse ) ;
sidrequest . data . gid = gid ;
result = winbindd_request ( WINBINDD_GID_TO_SID ,
& 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 ) ;
}
SAFE_FREE ( response . extra_data ) ;
return True ;
}
/**
* Get a list of all user tokens we want to look at
* */
static BOOL get_user_tokens ( int * num_tokens , struct user_token * * user_tokens )
{
struct winbindd_request request ;
struct winbindd_response response ;
const char * extra_data ;
fstring name ;
int i ;
struct user_token * result ;
/* Send request to winbind daemon */
ZERO_STRUCT ( request ) ;
ZERO_STRUCT ( response ) ;
if ( winbindd_request ( WINBINDD_LIST_USERS , & request , & response ) ! =
NSS_STATUS_SUCCESS )
return False ;
/* Look through extra data */
if ( ! response . extra_data )
return False ;
extra_data = ( const char * ) response . extra_data ;
* num_tokens = 0 ;
while ( next_token ( & extra_data , name , " , " , sizeof ( fstring ) ) ) {
* 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 " ) ) ;
return False ;
}
extra_data = ( const char * ) response . extra_data ;
i = 0 ;
while ( next_token ( & extra_data , name , " , " , sizeof ( fstring ) ) ) {
fstring domain , user ;
char * p ;
fstrcpy ( result [ i ] . name , name ) ;
p = strchr ( name , * lp_winbind_separator ( ) ) ;
DEBUG ( 3 , ( " %s \n " , name ) ) ;
if ( p = = NULL )
continue ;
* p + + = ' \0 ' ;
fstrcpy ( domain , name ) ;
strupper_m ( domain ) ;
fstrcpy ( user , p ) ;
get_user_sids ( domain , user , & ( result [ i ] . token ) ) ;
i + = 1 ;
}
SAFE_FREE ( response . extra_data ) ;
* user_tokens = result ;
return True ;
}
static BOOL get_user_tokens_from_file ( FILE * f ,
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
*/
static void show_userlist ( struct cli_state * cli ,
TALLOC_CTX * mem_ctx , const char * netname ,
int num_tokens , struct user_token * tokens )
{
int fnum ;
SEC_DESC * share_sd = NULL ;
SEC_DESC * root_sd = NULL ;
int i ;
SRV_SHARE_INFO info ;
WERROR result ;
uint16 cnum ;
result = cli_srvsvc_net_share_get_info ( cli , mem_ctx , netname ,
502 , & info ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 1 , ( " Coult not query secdesc for share %s \n " ,
netname ) ) ;
return ;
}
share_sd = info . share . info502 . info_502_str . sd ;
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 ) ;
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 .
* */
static NTSTATUS
rpc_share_allowedusers_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
int ret ;
BOOL r ;
ENUM_HND hnd ;
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 ) ;
init_enum_hnd ( & hnd , 0 ) ;
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 ) ;
show_userlist ( cli , mem_ctx , netname ,
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 ;
}
static int
rpc_share_allowedusers ( int argc , const char * * argv )
{
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 } ,
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 ) ;
}
/****************************************************************************/
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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_file_close_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
WERROR result ;
result = cli_srvsvc_net_file_close ( cli , mem_ctx , atoi ( argv [ 0 ] ) ) ;
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
/**
* 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
* */
static void display_file_info_3 ( FILE_INFO_3 * info3 , FILE_INFO_3_STR * str3 )
{
fstring user = " " , path = " " ;
rpcstr_pull_unistr2_fstring ( user , & str3 - > uni_user_name ) ;
rpcstr_pull_unistr2_fstring ( path , & str3 - > uni_path_name ) ;
d_printf ( " %-7.1d %-20.20s 0x%-4.2x %-6.1d %s \n " ,
info3 - > id , user , info3 - > perms , info3 - > num_locks , path ) ;
}
/**
* 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 .
* */
static NTSTATUS
2004-02-08 13:59:09 +03:00
rpc_file_list_internals ( const DOM_SID * domain_sid , const char * domain_name ,
struct cli_state * cli ,
2002-07-15 14:35:28 +04:00
TALLOC_CTX * mem_ctx , int argc , const char * * argv )
{
SRV_FILE_INFO_CTR ctr ;
WERROR result ;
ENUM_HND hnd ;
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
init_enum_hnd ( & hnd , 0 ) ;
/* 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
result = cli_srvsvc_net_file_enum (
cli , mem_ctx , 3 , username , & ctr , preferred_len , & hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) )
goto done ;
/* Display results */
d_printf (
" \n Enumerating open files on remote server: \n \n " \
" \n FileId Opened by Perms Locks Path " \
" \n ------ --------- ----- ----- ---- \n " ) ;
for ( i = 0 ; i < ctr . num_entries ; i + + )
display_file_info_3 ( & ctr . file . info3 [ i ] . info_3 ,
& ctr . file . info3 [ i ] . info_3_str ) ;
done :
return W_ERROR_IS_OK ( result ) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
/**
* 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 )
* */
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 ,
2004-02-08 13:59:09 +03:00
const char * domain_name ,
2003-10-24 18:03:18 +04:00
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
2001-12-31 16:00:59 +03:00
int argc , const char * * argv )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2003-10-24 18:03:18 +04:00
result = cli_shutdown_abort ( cli , mem_ctx ) ;
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 ,
2004-02-08 13:59:09 +03:00
const char * domain_name ,
2003-10-24 18:03:18 +04:00
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2005-01-10 23:33:41 +03:00
result = werror_to_ntstatus ( cli_reg_abort_shutdown ( cli , mem_ctx ) ) ;
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 )
{
2003-10-24 18:03:18 +04:00
int rc = run_rpc_command ( NULL , PI_SHUTDOWN , 0 ,
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 .
* */
2004-11-15 23:57:27 +03:00
static NTSTATUS rpc_init_shutdown_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
const char * msg = " This machine will be shutdown shortly " ;
uint32 timeout = 20 ;
if ( opt_comment ) {
msg = opt_comment ;
}
if ( opt_timeout ) {
timeout = opt_timeout ;
}
/* create an entry */
result = cli_shutdown_init ( cli , mem_ctx , msg , timeout , opt_reboot ,
opt_force ) ;
if ( NT_STATUS_IS_OK ( result ) ) {
d_printf ( " \n Shutdown of remote machine succeeded \n " ) ;
DEBUG ( 5 , ( " Shutdown of remote machine succeeded \n " ) ) ;
} else
DEBUG ( 0 , ( " Shutdown of remote machine failed! \n " ) ) ;
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 .
* */
static NTSTATUS rpc_reg_shutdown_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
2001-12-31 16:00:59 +03:00
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
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 ;
#if 0
poptContext pc ;
int rc ;
struct poptOption long_options [ ] = {
{ " message " , ' m ' , POPT_ARG_STRING , & msg } ,
{ " timeout " , ' t ' , POPT_ARG_INT , & timeout } ,
{ " reboot " , ' r ' , POPT_ARG_NONE , & reboot } ,
{ " force " , ' f ' , POPT_ARG_NONE , & force } ,
{ 0 , 0 , 0 , 0 }
} ;
pc = poptGetContext ( NULL , argc , ( const char * * ) argv , long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
rc = poptGetNextOpt ( pc ) ;
if ( rc < - 1 ) {
/* an error occurred during option processing */
DEBUG ( 0 , ( " %s: %s \n " ,
poptBadOption ( pc , POPT_BADOPTION_NOALIAS ) ,
poptStrerror ( rc ) ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
# endif
if ( opt_comment ) {
msg = opt_comment ;
}
if ( opt_timeout ) {
timeout = opt_timeout ;
}
/* create an entry */
2005-01-10 23:33:41 +03:00
result = werror_to_ntstatus ( cli_reg_shutdown ( cli , mem_ctx , msg , timeout , opt_reboot , opt_force ) ) ;
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 of remote machine succeeded \n " ) ;
2001-12-31 16:00:59 +03:00
DEBUG ( 5 , ( " Shutdown of remote machine succeeded \n " ) ) ;
2004-11-15 23:57:27 +03:00
}
2001-12-31 16:00:59 +03:00
else
DEBUG ( 0 , ( " Shutdown of remote machine failed! \n " ) ) ;
return result ;
}
/**
* 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 )
{
2004-11-15 23:57:27 +03:00
int rc = run_rpc_command ( NULL , PI_SHUTDOWN , 0 ,
rpc_init_shutdown_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_internals ,
2001-12-31 16:00:59 +03:00
argc , argv ) ;
}
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 ,
const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2002-08-17 18:45:04 +04:00
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 ;
uint16 acb_info ;
uint32 unknown , user_rid ;
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 )
*/
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
2002-08-17 18:45:04 +04:00
/* Get samr policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
2002-03-01 05:56:35 +03:00
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Create trusting domain's account */
2005-02-26 18:26:55 +03:00
acb_info = ACB_NORMAL ;
2003-05-11 20:59:06 +04:00
unknown = 0xe00500b0 ; /* No idea what this is - a permission mask?
2002-08-17 18:45:04 +04:00
mimir : yes , most probably it is */
2002-03-01 05:56:35 +03:00
result = cli_samr_create_dom_user ( cli , mem_ctx , & domain_pol ,
acct_name , acb_info , unknown ,
& user_pol , & user_rid ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
2003-05-11 20:59:06 +04:00
{
SAM_USERINFO_CTR ctr ;
2005-02-26 18:26:55 +03:00
SAM_USER_INFO_23 p23 ;
NTTIME notime ;
char nostr [ ] = " " ;
LOGON_HRS hrs ;
2003-05-11 20:59:06 +04:00
uchar pwbuf [ 516 ] ;
2004-01-26 11:45:02 +03:00
encode_pw_buffer ( ( char * ) pwbuf , argv [ 1 ] , STR_UNICODE ) ;
2003-05-11 20:59:06 +04:00
ZERO_STRUCT ( ctr ) ;
2005-02-26 18:26:55 +03:00
ZERO_STRUCT ( p23 ) ;
ZERO_STRUCT ( notime ) ;
hrs . max_len = 1260 ;
hrs . offset = 0 ;
hrs . len = 21 ;
memset ( hrs . hours , 0xFF , sizeof ( hrs . hours ) ) ;
acb_info = ACB_DOMTRUST ;
init_sam_user_info23A ( & p23 , & notime , & notime , & notime ,
& notime , & notime , & notime ,
nostr , nostr , nostr , nostr , nostr ,
nostr , nostr , nostr , nostr , nostr ,
0 , 0 , acb_info , ACCT_FLAGS , 168 , & hrs ,
0 , 0 , ( char * ) pwbuf ) ;
ctr . switch_value = 23 ;
ctr . info . id23 = & p23 ;
p23 . passmustchange = 0 ;
result = cli_samr_set_userinfo ( cli , mem_ctx , & user_pol , 23 ,
2003-11-23 02:38:41 +03:00
& cli - > user_session_key , & ctr ) ;
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-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 ,
const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv ) {
POLICY_HND connect_pol , domain_pol , user_pol ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
char * acct_name ;
DOM_SID trust_acct_sid ;
uint32 * user_rids , num_rids , * name_types ;
uint32 flags = 0x000003e8 ; /* Unknown */
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 )
*/
if ( asprintf ( & acct_name , " %s$ " , argv [ 0 ] ) < 0 ) {
return NT_STATUS_NO_MEMORY ;
}
strupper_m ( acct_name ) ;
/* Get samr policy handle */
result = cli_samr_connect ( cli , mem_ctx , MAXIMUM_ALLOWED_ACCESS ,
& connect_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Get domain policy handle */
result = cli_samr_open_domain ( cli , mem_ctx , & connect_pol ,
MAXIMUM_ALLOWED_ACCESS ,
domain_sid , & domain_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_lookup_names ( cli , mem_ctx , & domain_pol , flags , 1 ,
& acct_name , & num_rids , & user_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
result = cli_samr_open_user ( cli , mem_ctx , & domain_pol ,
MAXIMUM_ALLOWED_ACCESS ,
user_rids [ 0 ] , & user_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* append the rid to the domain sid */
sid_copy ( & trust_acct_sid , domain_sid ) ;
if ( ! sid_append_rid ( & trust_acct_sid , user_rids [ 0 ] ) ) {
goto done ;
}
/* remove the sid */
result = cli_samr_remove_sid_foreign_domain ( cli , mem_ctx , & user_pol ,
& trust_acct_sid ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Delete user */
result = cli_samr_delete_dom_user ( cli , mem_ctx , & user_pol ) ;
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 :
SAFE_FREE ( acct_name ) ;
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
}
/**
* 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 )
{
2002-03-01 05:56:35 +03:00
struct cli_state * cli ;
struct in_addr server_ip ;
POLICY_HND connect_hnd ;
TALLOC_CTX * mem_ctx ;
NTSTATUS nt_status ;
2004-01-08 11:19:18 +03:00
DOM_SID * domain_sid ;
2005-03-20 14:51:01 +03:00
smb_ucs2_t * uni_domain_name ;
2002-03-01 05:56:35 +03:00
char * domain_name ;
2004-01-08 11:19:18 +03:00
char * domain_name_pol ;
2002-03-01 05:56:35 +03:00
char * acct_name ;
fstring pdc_name ;
/*
* 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 ) ;
2002-03-01 05:56:35 +03: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 ) ;
} ;
opt_user_name = acct_name ;
2002-03-01 05:56:35 +03:00
/* find the domain controller */
2003-06-25 21:41:05 +04:00
if ( ! net_find_pdc ( & server_ip , 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 */
nt_status = connect_to_ipc ( & cli , & server_ip , pdc_name ) ;
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 ;
}
/*
* Connect to \ \ server \ ipc $ again ( this time anonymously )
*/
nt_status = connect_to_ipc_anonymous ( & cli , & server_ip , ( char * ) pdc_name ) ;
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 ) ) ) ;
2002-03-01 05:56:35 +03:00
}
/*
* Use NetServerEnum2 to make sure we ' re talking to a proper server
*/
if ( ! cli_get_pdc_name ( cli , domain_name , ( char * ) pdc_name ) ) {
DEBUG ( 0 , ( " NetServerEnum2 error: Couldn't find primary domain controller \
for domain % s \ n " , domain_name));
}
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 ;
}
/*
* Call LsaOpenPolicy and LsaQueryInfo
*/
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_LSARPC ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " Could not initialise lsa pipe \n " ) ) ;
2002-08-17 18:45:04 +04:00
cli_shutdown ( cli ) ;
return - 1 ;
2002-03-01 05:56:35 +03:00
}
nt_status = cli_lsa_open_policy2 ( cli , 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 ) ) ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
/* Querying info level 5 */
nt_status = cli_lsa_query_info_policy ( cli , mem_ctx , & connect_hnd ,
2005-03-20 14:51:01 +03:00
5 /* info level */ ,
& domain_name_pol , & domain_sid ) ;
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 ) ) ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2005-03-20 14:51:01 +03:00
if ( push_ucs2_talloc ( mem_ctx , & uni_domain_name , domain_name_pol ) < 0 ) {
DEBUG ( 0 , ( " Could not convert domain name %s to unicode \n " ,
domain_name_pol ) ) ;
return - 1 ;
}
2002-08-17 18:45:04 +04:00
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
*/
2005-03-20 14:51:01 +03:00
if ( ! secrets_store_trusted_domain_password ( domain_name ,
uni_domain_name ,
strlen_w ( uni_domain_name ) + 1 ,
opt_password ,
2004-01-08 11:19:18 +03:00
* domain_sid ) ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " Storing password for trusted domain failed. \n " ) ) ;
return - 1 ;
}
2002-03-01 05:56:35 +03:00
/*
* Close the pipes and clean up
*/
nt_status = cli_lsa_close ( cli , mem_ctx , & connect_hnd ) ;
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 ) ) ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
2005-01-06 18:35:02 +03:00
if ( cli - > nt_pipe_fnum [ cli - > pipe_idx ] )
2002-03-01 05:56:35 +03:00
cli_nt_session_close ( cli ) ;
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 ;
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 */
if ( ! trusted_domain_password_delete ( domain_name ) ) {
DEBUG ( 0 , ( " Failed to revoke relationship to the trusted domain %s \n " ,
domain_name ) ) ;
return - 1 ;
} ;
return 0 ;
}
/**
* 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 " ) ;
return - 1 ;
}
2004-02-08 13:59:09 +03:00
static NTSTATUS rpc_query_domain_sid ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
2002-08-17 18:45:04 +04:00
{
fstring str_sid ;
sid_to_string ( str_sid , domain_sid ) ;
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
static int rpc_trustdom_list ( int argc , const char * * argv )
{
/* common variables */
TALLOC_CTX * mem_ctx ;
struct cli_state * cli , * remote_cli ;
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 ;
2002-08-17 18:45:04 +04:00
fstring ascii_sid , padding ;
int ascii_dom_name_len ;
POLICY_HND connect_hnd ;
/* 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 ;
2002-08-17 18:45:04 +04:00
DOM_SID * domain_sids ;
char * * trusted_dom_names ;
2004-01-08 11:19:18 +03:00
fstring pdc_name ;
char * dummy ;
2002-08-17 18:45:04 +04:00
/* trusting domains listing variables */
POLICY_HND domain_hnd ;
char * * trusting_dom_names ;
uint32 * trusting_dom_rids ;
/*
* 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 */
if ( ! ( cli = net_make_ipc_connection ( NET_FLAGS_PDC ) ) ) {
DEBUG ( 0 , ( " Couldn't connect to domain controller \n " ) ) ;
return - 1 ;
} ;
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_LSARPC ) ) {
2002-08-17 18:45:04 +04:00
DEBUG ( 0 , ( " Could not initialise lsa pipe \n " ) ) ;
return - 1 ;
} ;
2003-05-05 12:32:30 +04:00
nt_status = cli_lsa_open_policy2 ( cli , 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 ) ) ) ;
return - 1 ;
} ;
/* query info level 5 to obtain sid of a domain being queried */
2003-04-14 08:00:15 +04:00
nt_status = cli_lsa_query_info_policy (
cli , mem_ctx , & connect_hnd , 5 /* info level */ ,
2004-01-08 11:19:18 +03:00
& dummy , & queried_dom_sid ) ;
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 ) ) ) ;
return - 1 ;
}
/*
* Keep calling LsaEnumTrustdom over opened pipe until
* the end of enumeration is reached
*/
d_printf ( " Trusted domains list: \n \n " ) ;
do {
nt_status = cli_lsa_enum_trust_dom ( cli , mem_ctx , & connect_hnd , & enum_ctx ,
& num_domains ,
& trusted_dom_names , & domain_sids ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't enumerate trusted domains. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
return - 1 ;
} ;
for ( i = 0 ; i < num_domains ; i + + ) {
/* convert sid into ascii string */
sid_to_string ( ascii_sid , & ( domain_sids [ i ] ) ) ;
/* calculate padding space for d_printf to look nicer */
pad_len = col_len - strlen ( trusted_dom_names [ i ] ) ;
padding [ pad_len ] = 0 ;
do padding [ - - pad_len ] = ' ' ; while ( pad_len ) ;
d_printf ( " %s%s%s \n " , trusted_dom_names [ i ] , padding , ascii_sid ) ;
} ;
2002-09-25 19:19:00 +04:00
/*
* in case of no trusted domains say something rather
* than just display blank line
*/
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 this connection before doing next one */
nt_status = cli_lsa_close ( cli , mem_ctx , & connect_hnd ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close lsa policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
return - 1 ;
} ;
cli_nt_session_close ( cli ) ;
/*
* 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
*/
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_SAMR ) ) {
2002-08-17 18:45:04 +04:00
DEBUG ( 0 , ( " Could not initialise samr pipe \n " ) ) ;
return - 1 ;
} ;
/* SamrConnect */
2002-11-02 15:53:13 +03:00
nt_status = cli_samr_connect ( cli , mem_ctx , SA_RIGHT_SAM_OPEN_DOMAIN ,
2002-08-17 18:45:04 +04:00
& connect_hnd ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't open SAMR policy handle. Error was %s \n " ,
nt_errstr ( nt_status ) ) ) ;
return - 1 ;
} ;
/* SamrOpenDomain - we have to open domain policy handle in order to be
able to enumerate accounts */
nt_status = cli_samr_open_domain ( cli , mem_ctx , & connect_hnd ,
2004-01-08 11:19:18 +03:00
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 ) ) ) ;
return - 1 ;
} ;
/*
* perform actual enumeration
*/
enum_ctx = 0 ; /* reset enumeration context from last enumeration */
do {
nt_status = cli_samr_enum_dom_users ( cli , mem_ctx , & domain_hnd ,
& enum_ctx , ACB_DOMTRUST , 0xffff ,
& trusting_dom_names , & trusting_dom_rids ,
& num_domains ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't enumerate accounts. Error was: %s \n " ,
nt_errstr ( nt_status ) ) ) ;
return - 1 ;
} ;
for ( i = 0 ; i < num_domains ; i + + ) {
/*
* 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 */
ascii_dom_name_len = strlen ( trusting_dom_names [ i ] ) ;
if ( ascii_dom_name_len & & ascii_dom_name_len < FSTRING_LEN )
trusting_dom_names [ i ] [ ascii_dom_name_len - 1 ] = ' \0 ' ;
/* calculate padding space for d_printf to look nicer */
pad_len = col_len - strlen ( trusting_dom_names [ i ] ) ;
padding [ pad_len ] = 0 ;
do padding [ - - pad_len ] = ' ' ; while ( pad_len ) ;
/* set opt_* variables to remote domain */
2003-07-03 23:11:31 +04:00
strupper_m ( trusting_dom_names [ i ] ) ;
2002-08-17 18:45:04 +04:00
opt_workgroup = talloc_strdup ( mem_ctx , trusting_dom_names [ i ] ) ;
opt_target_workgroup = opt_workgroup ;
d_printf ( " %s%s " , trusting_dom_names [ i ] , padding ) ;
/* connect to remote domain controller */
remote_cli = net_make_ipc_connection ( NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS ) ;
if ( remote_cli ) {
/* 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 ) )
2002-08-17 18:45:04 +04:00
d_printf ( " couldn't get domain's sid \n " ) ;
cli_shutdown ( remote_cli ) ;
} else {
d_printf ( " domain controller is not responding \n " ) ;
} ;
} ;
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 */
nt_status = cli_samr_close ( cli , mem_ctx , & domain_hnd ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 0 , ( " Couldn't properly close domain policy handle for domain %s \n " , domain_name ) ) ;
} ;
nt_status = cli_samr_close ( cli , mem_ctx , & connect_hnd ) ;
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_nt_session_close ( cli ) ;
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 } ,
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
* @ return BOOL ( true means rpc supported )
*/
BOOL net_rpc_check ( unsigned flags )
{
struct cli_state cli ;
BOOL ret = False ;
struct in_addr server_ip ;
char * server_name = NULL ;
/* flags (i.e. server type) may depend on command */
if ( ! net_find_server ( flags , & server_ip , & server_name ) )
2002-09-25 19:19:00 +04:00
return False ;
2002-04-05 05:36:28 +04:00
ZERO_STRUCT ( cli ) ;
if ( cli_initialise ( & cli ) = = False )
return False ;
if ( ! cli_connect ( & cli , server_name , & server_ip ) )
goto done ;
2002-11-13 02:20:50 +03:00
if ( ! attempt_netbios_session_request ( & cli , global_myname ( ) ,
2002-04-05 05:36:28 +04:00
server_name , & server_ip ) )
goto done ;
if ( ! cli_negprot ( & cli ) )
goto done ;
if ( cli . protocol < PROTOCOL_NT1 )
goto done ;
ret = True ;
done :
cli_shutdown ( & cli ) ;
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 ) {
return run_rpc_command ( NULL , PI_NETLOGON , NET_FLAGS_ANONYMOUS , rpc_samdump_internals ,
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 " ) ;
2003-04-21 18:09:03 +04:00
d_printf ( " net rpc oldjoin \t \t \t to join a domain created in server manager \n \n \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 " ) ;
d_printf ( " net rpc samdump \t \t diplay 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 " ) ;
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 " ) ;
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}, */
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 [ ] = {
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 } ,
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 ) ;
}