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 )
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"
# include "../utils/net.h"
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 .
* */
/* A function of this type is passed to the 'run_rpc_command' wrapper */
2004-02-08 13:59:09 +03:00
typedef NTSTATUS ( * rpc_command_fn ) ( const DOM_SID * , const char * ,
struct cli_state * , TALLOC_CTX * , int , const char * * ) ;
2001-12-05 03:26:36 +03:00
2001-12-30 13:54:58 +03:00
/**
* 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
2002-10-04 08:10:23 +04:00
static 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 ) ) {
if ( cli - > nt_pipe_fnum )
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 ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " Sequence number: %u \n " , ctr . info . inf2 . seq_num ) ;
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 ;
}
/**
* 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 ) ;
/* Look up rids */
rids = ( uint32 * ) talloc ( mem_ctx , sizeof ( uint32 ) * num_rids ) ;
for ( i = 0 ; i < num_rids ; i + + )
rids [ i ] = user_gids [ i ] . g_rid ;
result = cli_samr_lookup_rids ( cli , mem_ctx , & domain_pol ,
flags , num_rids , rids ,
& num_names , & names , & name_types ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto done ;
}
/* Display results */
for ( i = 0 ; i < num_names ; i + + )
printf ( " %s \n " , names [ i ] ) ;
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 } ,
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
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 ) ;
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 ;
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 ) ;
2003-06-12 20:21:22 +04:00
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 ) ;
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
2004-02-09 21:19:25 +03:00
result = cli_samr_lookup_rids ( cli , mem_ctx , domain_pol , 1000 ,
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 ;
}
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 ) ;
}
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 [ ] = {
#if 0
{ " add " , rpc_group_add } ,
{ " delete " , rpc_group_delete } ,
# endif
2003-11-28 18:10:00 +03:00
{ " list " , rpc_group_list } ,
2003-11-26 13:07:07 +03:00
{ " members " , rpc_group_members } ,
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 */
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 ,
num_users , path , password ) ;
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 ;
}
/**
* ' 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 } ,
{ 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 ) ;
if ( NT_STATUS_IS_OK ( result ) )
DEBUG ( 5 , ( " cmd_shutdown_abort: query succeeded \n " ) ) ;
else
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 ;
2001-12-31 16:00:59 +03:00
result = cli_reg_abort_shutdown ( cli , mem_ctx ) ;
if ( NT_STATUS_IS_OK ( result ) )
DEBUG ( 5 , ( " cmd_reg_abort_shutdown: query succeeded \n " ) ) ;
else
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 ) ;
}
/**
* Shut down 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-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-02-08 13:59:09 +03:00
static NTSTATUS rpc_shutdown_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
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-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 */
2003-01-04 10:50:04 +03:00
result = cli_reg_shutdown ( cli , mem_ctx , msg , timeout , opt_reboot , opt_force ) ;
2001-12-31 16:00:59 +03:00
if ( NT_STATUS_IS_OK ( result ) )
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
*
* @ 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 )
{
2002-10-04 08:10:23 +04:00
return run_rpc_command ( NULL , PI_WINREG , 0 , rpc_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 */
acb_info = ACB_DOMTRUST ;
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 ;
SAM_USER_INFO_24 p24 ;
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 ) ;
ZERO_STRUCT ( p24 ) ;
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 ,
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
}
/**
* 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 )
* */
static int rpc_trustdom_del ( int argc , const char * * argv )
{
d_printf ( " Sorry, not yet implemented. \n " ) ;
2003-08-15 23:47:10 +04:00
d_printf ( " Use 'smbpasswd -x -i' instead. \n " ) ;
2002-03-01 05:56:35 +03:00
return - 1 ;
}
/**
* 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 ;
2002-03-01 05:56:35 +03:00
WKS_INFO_100 wks_info ;
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));
}
/*
* Call WksQueryInfo to check remote server ' s capabilities
2002-08-17 18:45:04 +04:00
* note : It is now used only to get unicode domain name
2002-03-01 05:56:35 +03:00
*/
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_WKSSVC ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " Couldn't not initialise wkssvc pipe \n " ) ) ;
return - 1 ;
}
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " establishing trust relationship to domain %s " ,
2002-08-17 18:45:04 +04:00
domain_name ) ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " talloc_init() failed \n " ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
nt_status = cli_wks_query_info ( cli , mem_ctx , & wks_info ) ;
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
DEBUG ( 0 , ( " WksQueryInfo call failed. \n " ) ) ;
return - 1 ;
}
2002-07-15 14:35:28 +04:00
if ( cli - > nt_pipe_fnum )
2002-03-01 05:56:35 +03:00
cli_nt_session_close ( cli ) ;
/*
* Call LsaOpenPolicy and LsaQueryInfo
*/
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " rpc_trustdom_establish " ) ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " talloc_init() failed \n " ) ) ;
cli_shutdown ( cli ) ;
return - 1 ;
}
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 ,
2004-01-08 11:19:18 +03:00
5 /* info level */ , & domain_name_pol ,
2002-08-17 18:45:04 +04:00
& 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 ;
}
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
*/
if ( ! secrets_store_trusted_domain_password ( domain_name , wks_info . uni_lan_grp . buffer ,
wks_info . uni_lan_grp . uni_str_len , 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 ;
}
if ( cli - > nt_pipe_fnum )
cli_nt_session_close ( cli ) ;
2002-07-15 14:35:28 +04:00
talloc_destroy ( mem_ctx ) ;
2002-03-01 05:56:35 +03:00
DEBUG ( 0 , ( " Success! \n " ) ) ;
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 ) ;
}
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-02-08 12:25:58 +03:00
d_printf ( " net rpc password <username> [<password>] -Uadmin_username%%admin_pass " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc group \t \t to list groups \n " ) ;
d_printf ( " net rpc share \t \t to add, delete, and list shares \n " ) ;
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 " ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " net rpc trustdom \t \t to create trusting domain's account \n "
" \t \t \t \t \t or establish trust \n " ) ;
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 " ) ;
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 } ,
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 } ,
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 ) ;
}