2001-10-19 20:51:26 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Copyright ( C ) 2001 Steve French ( sfrench @ us . ibm . com )
Copyright ( C ) 2001 Jim McDonough ( jmcd @ us . ibm . com )
2001-11-24 16:26:01 +03:00
Copyright ( C ) 2001 Andrew Tridgell ( tridge @ samba . org )
2001-12-03 07:39:23 +03:00
Copyright ( C ) 2001 Andrew Bartlett ( abartlet @ samba . org )
2001-10-19 20:51:26 +04:00
2001-11-24 16:26:01 +03:00
Originally written by Steve and Jim . Largely rewritten by tridge in
November 2001.
2001-10-19 20:51:26 +04:00
2001-12-03 07:39:23 +03:00
Reworked again by abartlet in December 2001
2001-10-19 20:51:26 +04: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
2001-11-24 16:26:01 +03:00
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA . */
2001-10-19 20:51:26 +04:00
/*****************************************************/
/* */
/* Distributed SMB/CIFS Server Management Utility */
/* */
/* The intent was to make the syntax similar */
/* to the NET utility (first developed in DOS */
/* with additional interesting & useful functions */
/* added in later SMB server network operating */
/* systems). */
/* */
/*****************************************************/
2001-11-25 03:18:11 +03:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2001-10-19 20:51:26 +04:00
/***********************************************************************/
/* Beginning of internationalization section. Translatable constants */
/* should be kept in this area and referenced in the rest of the code. */
/* */
/* No functions, outside of Samba or LSB (Linux Standards Base) should */
/* be used (if possible). */
/***********************************************************************/
# define YES_STRING "Yes"
# define NO_STRING "No"
/************************************************************************************/
/* end of internationalization section */
/************************************************************************************/
2001-12-03 07:39:23 +03:00
/* Yes, these buggers are globals.... */
2003-01-03 11:28:12 +03:00
const char * opt_requester_name = NULL ;
const char * opt_host = NULL ;
const char * opt_password = NULL ;
const char * opt_user_name = NULL ;
2002-01-26 01:07:46 +03:00
BOOL opt_user_specified = False ;
2002-11-13 02:20:50 +03:00
const char * opt_workgroup = NULL ;
2001-12-03 07:39:23 +03:00
int opt_long_list_entries = 0 ;
2001-12-31 16:00:59 +03:00
int opt_reboot = 0 ;
int opt_force = 0 ;
2001-12-03 07:39:23 +03:00
int opt_port = 0 ;
2004-04-19 00:22:31 +04:00
int opt_verbose = 0 ;
2001-12-03 07:39:23 +03:00
int opt_maxusers = - 1 ;
2003-01-03 11:28:12 +03:00
const char * opt_comment = " " ;
2004-10-06 20:21:35 +04:00
const char * opt_container = NULL ;
2001-12-03 07:39:23 +03:00
int opt_flags = - 1 ;
2001-12-31 16:00:59 +03:00
int opt_timeout = 0 ;
2003-01-03 11:28:12 +03:00
const char * opt_target_workgroup = NULL ;
2003-10-23 18:33:19 +04:00
int opt_machine_pass = 0 ;
2004-02-26 14:29:56 +03:00
BOOL opt_localgroup = False ;
BOOL opt_domaingroup = False ;
const char * opt_newntname = " " ;
int opt_rid = 0 ;
2004-08-10 18:27:17 +04:00
int opt_acls = 0 ;
2004-08-21 00:13:05 +04:00
int opt_attrs = 0 ;
int opt_timestamps = 0 ;
2004-08-10 18:27:17 +04:00
const char * opt_exclude = NULL ;
2004-08-27 01:37:20 +04:00
const char * opt_destination = NULL ;
2001-11-24 16:26:01 +03:00
2001-12-11 08:21:50 +03:00
BOOL opt_have_ip = False ;
struct in_addr opt_dest_ip ;
2001-10-19 20:51:26 +04:00
2005-04-06 20:28:04 +04:00
extern struct in_addr loopback_ip ;
2003-07-19 04:23:08 +04:00
extern BOOL AllowDebugChange ;
2003-04-21 18:09:03 +04:00
uint32 get_sec_channel_type ( const char * param )
{
if ( ! ( param & & * param ) ) {
return get_default_sec_channel ( ) ;
} else {
2003-10-23 03:38:20 +04:00
if ( strequal ( param , " PDC " ) ) {
2003-04-21 18:09:03 +04:00
return SEC_CHAN_BDC ;
2003-10-23 03:38:20 +04:00
} else if ( strequal ( param , " BDC " ) ) {
2003-04-21 18:09:03 +04:00
return SEC_CHAN_BDC ;
2003-10-23 03:38:20 +04:00
} else if ( strequal ( param , " MEMBER " ) ) {
2003-04-21 18:09:03 +04:00
return SEC_CHAN_WKSTA ;
#if 0
2003-10-23 03:38:20 +04:00
} else if ( strequal ( param , " DOMAIN " ) ) {
2003-04-21 18:09:03 +04:00
return SEC_CHAN_DOMAIN ;
# endif
} else {
return get_default_sec_channel ( ) ;
}
}
}
2001-11-24 16:26:01 +03:00
/*
run a function from a function table . If not found then
call the specified usage function
*/
2001-11-24 17:16:41 +03:00
int net_run_function ( int argc , const char * * argv , struct functable * table ,
2001-11-26 07:53:08 +03:00
int ( * usage_fn ) ( int argc , const char * * argv ) )
2001-10-19 20:51:26 +04:00
{
2001-11-24 16:26:01 +03:00
int i ;
2001-12-03 07:39:23 +03:00
if ( argc < 1 ) {
d_printf ( " \n Usage: \n " ) ;
2001-11-26 07:53:08 +03:00
return usage_fn ( argc , argv ) ;
2001-12-03 07:39:23 +03:00
}
2001-11-24 16:26:01 +03:00
for ( i = 0 ; table [ i ] . funcname ; i + + ) {
2001-11-26 07:53:08 +03:00
if ( StrCaseCmp ( argv [ 0 ] , table [ i ] . funcname ) = = 0 )
2001-11-24 16:26:01 +03:00
return table [ i ] . fn ( argc - 1 , argv + 1 ) ;
}
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " No command: %s \n " , argv [ 0 ] ) ;
2001-11-26 07:53:08 +03:00
return usage_fn ( argc , argv ) ;
2001-10-19 20:51:26 +04:00
}
2006-02-04 01:19:41 +03:00
/*
* run a function from a function table .
*/
int net_run_function2 ( int argc , const char * * argv , const char * whoami ,
struct functable2 * table )
{
int i ;
if ( argc ! = 0 ) {
for ( i = 0 ; table [ i ] . funcname ; i + + ) {
if ( StrCaseCmp ( argv [ 0 ] , table [ i ] . funcname ) = = 0 )
return table [ i ] . fn ( argc - 1 , argv + 1 ) ;
}
}
for ( i = 0 ; table [ i ] . funcname ! = NULL ; i + + ) {
d_printf ( " %s %-15s %s \n " , whoami , table [ i ] . funcname ,
table [ i ] . helptext ) ;
}
return - 1 ;
}
2001-10-19 20:51:26 +04:00
/****************************************************************************
2004-08-10 18:27:17 +04:00
connect to \ \ server \ service
2001-10-19 20:51:26 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-10 18:27:17 +04:00
NTSTATUS connect_to_service ( struct cli_state * * c , struct in_addr * server_ip ,
const char * server_name ,
const char * service_name ,
const char * service_type )
2001-11-24 16:26:01 +03:00
{
2001-12-03 10:42:18 +03:00
NTSTATUS nt_status ;
2001-11-24 16:26:01 +03:00
2003-10-23 18:33:19 +04:00
if ( ! opt_password & & ! opt_machine_pass ) {
2001-12-03 10:42:18 +03:00
char * pass = getpass ( " Password: " ) ;
2001-11-24 16:26:01 +03:00
if ( pass ) {
2004-12-07 21:25:53 +03:00
opt_password = SMB_STRDUP ( pass ) ;
2001-11-24 16:26:01 +03:00
}
}
2001-10-19 20:51:26 +04:00
2004-04-05 12:31:58 +04:00
nt_status = cli_full_connection ( c , NULL , server_name ,
2001-12-03 10:42:18 +03:00
server_ip , opt_port ,
2004-08-10 18:27:17 +04:00
service_name , service_type ,
2001-12-03 10:42:18 +03:00
opt_user_name , opt_workgroup ,
2003-07-31 03:49:29 +04:00
opt_password , 0 , Undefined , NULL ) ;
2001-11-24 16:26:01 +03:00
2001-12-03 10:42:18 +03:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
2002-03-01 05:56:35 +03:00
return nt_status ;
2001-12-03 10:42:18 +03:00
} else {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not connect to server %s \n " , server_name ) ;
2001-12-14 06:55:09 +03:00
/* Display a nicer message depending on the result */
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_LOGON_FAILURE ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " The username or password was not correct. \n " ) ;
2004-01-21 17:36:56 +03:00
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_ACCOUNT_LOCKED_OUT ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " The account was locked out. \n " ) ;
2004-01-21 17:36:56 +03:00
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_ACCOUNT_DISABLED ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " The account was disabled. \n " ) ;
2001-12-14 06:55:09 +03:00
2002-03-01 05:56:35 +03:00
return nt_status ;
2001-11-24 16:26:01 +03:00
}
}
2001-10-19 20:51:26 +04:00
2004-08-10 18:27:17 +04:00
/****************************************************************************
connect to \ \ server \ ipc $
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS connect_to_ipc ( struct cli_state * * c , struct in_addr * server_ip ,
const char * server_name )
{
return connect_to_service ( c , server_ip , server_name , " IPC$ " , " IPC " ) ;
}
2001-12-05 06:14:21 +03:00
/****************************************************************************
connect to \ \ server \ ipc $ anonymously
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-01 05:56:35 +03:00
NTSTATUS connect_to_ipc_anonymous ( struct cli_state * * c ,
struct in_addr * server_ip , const char * server_name )
2001-12-05 06:14:21 +03:00
{
NTSTATUS nt_status ;
2002-03-01 05:56:35 +03:00
nt_status = cli_full_connection ( c , opt_requester_name , server_name ,
2001-12-05 06:14:21 +03:00
server_ip , opt_port ,
" IPC$ " , " IPC " ,
" " , " " ,
2003-07-31 03:49:29 +04:00
" " , 0 , Undefined , NULL ) ;
2001-12-05 06:14:21 +03:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
2002-03-01 05:56:35 +03:00
return nt_status ;
2001-12-05 06:14:21 +03:00
} else {
2002-04-04 20:53:07 +04:00
DEBUG ( 1 , ( " Cannot connect to server (anonymously). Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
2002-03-01 05:56:35 +03:00
return nt_status ;
2001-12-05 06:14:21 +03:00
}
}
2004-08-10 18:27:17 +04:00
/**
2004-08-27 01:37:20 +04:00
* Connect a server and open a given pipe
2004-08-10 18:27:17 +04:00
*
2004-08-27 01:37:20 +04:00
* @ param cli_dst A cli_state
2004-08-10 18:27:17 +04:00
* @ param pipe The pipe to open
2004-08-21 00:13:05 +04:00
* @ param got_pipe boolean that stores if we got a pipe
2004-08-10 18:27:17 +04:00
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
NTSTATUS connect_dst_pipe ( struct cli_state * * cli_dst , struct rpc_pipe_client * * pp_pipe_hnd , int pipe_num )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status ;
2004-12-07 21:25:53 +03:00
char * server_name = SMB_STRDUP ( " 127.0.0.1 " ) ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_tmp = NULL ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2004-08-10 18:27:17 +04:00
2004-08-27 01:37:20 +04:00
if ( opt_destination )
2004-12-07 21:25:53 +03:00
server_name = SMB_STRDUP ( opt_destination ) ;
2004-08-27 01:37:20 +04:00
/* make a connection to a named pipe */
nt_status = connect_to_ipc ( & cli_tmp , NULL , server_name ) ;
2005-09-30 21:13:37 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2004-08-10 18:27:17 +04:00
return nt_status ;
2005-09-30 21:13:37 +04:00
}
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli_tmp , pipe_num , & nt_status ) ;
if ( ! pipe_hnd ) {
2004-08-21 00:13:05 +04:00
DEBUG ( 0 , ( " couldn't not initialize pipe \n " ) ) ;
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_tmp ) ;
2005-09-30 21:13:37 +04:00
return nt_status ;
2004-08-10 18:27:17 +04:00
}
2004-08-27 01:37:20 +04:00
* cli_dst = cli_tmp ;
2005-09-30 21:13:37 +04:00
* pp_pipe_hnd = pipe_hnd ;
2004-08-10 18:27:17 +04:00
return nt_status ;
}
2003-08-20 02:47:10 +04:00
/****************************************************************************
2005-09-30 21:13:37 +04:00
Use the local machine ' s password for this session .
2003-08-20 02:47:10 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
2003-08-20 02:47:10 +04:00
int net_use_machine_password ( void )
{
char * user_name = NULL ;
if ( ! secrets_init ( ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " ERROR: Unable to open secrets database \n " ) ;
2003-08-20 02:47:10 +04:00
exit ( 1 ) ;
}
user_name = NULL ;
opt_password = secrets_fetch_machine_password ( opt_target_workgroup , NULL , NULL ) ;
if ( asprintf ( & user_name , " %s$@%s " , global_myname ( ) , lp_realm ( ) ) = = - 1 ) {
return - 1 ;
}
opt_user_name = user_name ;
return 0 ;
}
2002-04-05 05:36:28 +04:00
BOOL net_find_server ( unsigned flags , struct in_addr * server_ip , char * * server_name )
2001-11-24 16:26:01 +03:00
{
2001-12-04 07:48:01 +03:00
if ( opt_host ) {
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( opt_host ) ;
2001-12-04 07:48:01 +03:00
}
2001-12-11 08:21:50 +03:00
if ( opt_have_ip ) {
* server_ip = opt_dest_ip ;
2001-12-05 05:58:40 +03:00
if ( ! * server_name ) {
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( inet_ntoa ( opt_dest_ip ) ) ;
2001-12-03 07:39:23 +03:00
}
2001-12-05 14:00:26 +03:00
} else if ( * server_name ) {
2001-12-03 07:39:23 +03:00
/* resolve the IP address */
2001-12-05 05:58:40 +03:00
if ( ! resolve_name ( * server_name , server_ip , 0x20 ) ) {
2001-12-03 10:42:18 +03:00
DEBUG ( 1 , ( " Unable to resolve server name \n " ) ) ;
2001-12-05 05:58:40 +03:00
return False ;
2001-12-03 07:39:23 +03:00
}
2001-12-04 07:48:01 +03:00
} else if ( flags & NET_FLAGS_PDC ) {
2002-11-06 08:14:15 +03:00
struct in_addr pdc_ip ;
if ( get_pdc_ip ( opt_target_workgroup , & pdc_ip ) ) {
2001-12-04 07:48:01 +03:00
fstring dc_name ;
2002-11-06 08:14:15 +03:00
if ( is_zero_ip ( pdc_ip ) )
2001-12-05 05:58:40 +03:00
return False ;
2001-12-04 07:48:01 +03:00
2003-06-25 21:41:05 +04:00
if ( ! name_status_find ( opt_target_workgroup , 0x1b , 0x20 , pdc_ip , dc_name ) )
2001-12-05 05:58:40 +03:00
return False ;
2001-12-04 07:48:01 +03:00
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( dc_name ) ;
2002-11-09 06:27:42 +03:00
* server_ip = pdc_ip ;
2001-11-24 16:26:01 +03:00
}
2001-12-04 07:48:01 +03:00
} else if ( flags & NET_FLAGS_DMB ) {
struct in_addr msbrow_ip ;
/* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
if ( ! resolve_name ( opt_target_workgroup , & msbrow_ip , 0x1B ) ) {
DEBUG ( 1 , ( " Unable to resolve domain browser via name lookup \n " ) ) ;
2001-12-05 05:58:40 +03:00
return False ;
2001-12-04 07:48:01 +03:00
} else {
2001-12-05 05:58:40 +03:00
* server_ip = msbrow_ip ;
2001-12-04 07:48:01 +03:00
}
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( inet_ntoa ( opt_dest_ip ) ) ;
2001-12-03 07:39:23 +03:00
} else if ( flags & NET_FLAGS_MASTER ) {
2001-11-24 16:26:01 +03:00
struct in_addr brow_ips ;
2001-12-04 07:48:01 +03:00
if ( ! resolve_name ( opt_target_workgroup , & brow_ips , 0x1D ) ) {
2001-11-24 16:26:01 +03:00
/* go looking for workgroups */
DEBUG ( 1 , ( " Unable to resolve master browser via name lookup \n " ) ) ;
2001-12-05 05:58:40 +03:00
return False ;
2001-11-24 16:26:01 +03:00
} else {
2001-12-05 05:58:40 +03:00
* server_ip = brow_ips ;
2001-11-24 16:26:01 +03:00
}
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( inet_ntoa ( opt_dest_ip ) ) ;
2001-12-03 07:39:23 +03:00
} else if ( ! ( flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE ) ) {
2001-12-05 05:58:40 +03:00
* server_ip = loopback_ip ;
2004-12-07 21:25:53 +03:00
* server_name = SMB_STRDUP ( " 127.0.0.1 " ) ;
2001-11-24 16:26:01 +03:00
}
2001-10-19 20:51:26 +04:00
2001-12-05 05:58:40 +03:00
if ( ! server_name | | ! * server_name ) {
2001-11-24 16:26:01 +03:00
DEBUG ( 1 , ( " no server to connect to \n " ) ) ;
2001-12-05 05:58:40 +03:00
return False ;
2001-11-24 16:26:01 +03:00
}
2001-12-03 07:39:23 +03:00
2001-12-05 05:58:40 +03:00
return True ;
}
2002-03-01 05:56:35 +03:00
2003-06-25 21:41:05 +04:00
BOOL net_find_pdc ( struct in_addr * server_ip , fstring server_name , const char * domain_name )
2002-03-01 05:56:35 +03:00
{
2002-11-06 08:14:15 +03:00
if ( get_pdc_ip ( domain_name , server_ip ) ) {
2002-03-01 05:56:35 +03:00
if ( is_zero_ip ( * server_ip ) )
return False ;
2003-06-25 21:41:05 +04:00
if ( ! name_status_find ( domain_name , 0x1b , 0x20 , * server_ip , server_name ) )
2002-03-01 05:56:35 +03:00
return False ;
2003-06-25 21:41:05 +04:00
return True ;
}
else
2002-03-01 05:56:35 +03:00
return False ;
}
2001-12-05 05:58:40 +03:00
struct cli_state * net_make_ipc_connection ( unsigned flags )
{
char * server_name = NULL ;
struct in_addr server_ip ;
2002-03-01 05:56:35 +03:00
struct cli_state * cli = NULL ;
NTSTATUS nt_status ;
2001-12-05 05:58:40 +03:00
if ( ! net_find_server ( flags , & server_ip , & server_name ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " \n Unable to find a suitable server \n " ) ;
2001-12-05 05:58:40 +03:00
return NULL ;
}
2001-12-05 06:14:21 +03:00
if ( flags & NET_FLAGS_ANONYMOUS ) {
2002-03-01 05:56:35 +03:00
nt_status = connect_to_ipc_anonymous ( & cli , & server_ip , server_name ) ;
2001-12-05 06:14:21 +03:00
} else {
2002-03-01 05:56:35 +03:00
nt_status = connect_to_ipc ( & cli , & server_ip , server_name ) ;
2001-12-05 06:14:21 +03:00
}
2002-10-01 17:10:57 +04:00
2001-12-04 07:48:01 +03:00
SAFE_FREE ( server_name ) ;
2002-10-01 17:10:57 +04:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
return cli ;
} else {
2006-02-04 01:19:41 +03:00
d_fprintf ( stderr , " Connection failed: %s \n " ,
nt_errstr ( nt_status ) ) ;
2002-10-01 17:10:57 +04:00
return NULL ;
}
2001-10-19 20:51:26 +04:00
}
2002-04-04 20:53:07 +04:00
static int net_user ( int argc , const char * * argv )
{
if ( net_ads_check ( ) = = 0 )
return net_ads_user ( argc , argv ) ;
2002-04-05 05:36:28 +04:00
/* if server is not specified, default to PDC? */
if ( net_rpc_check ( NET_FLAGS_PDC ) )
return net_rpc_user ( argc , argv ) ;
2002-04-04 20:53:07 +04:00
return net_rap_user ( argc , argv ) ;
}
2002-07-15 14:35:28 +04:00
static int net_group ( int argc , const char * * argv )
{
if ( net_ads_check ( ) = = 0 )
return net_ads_group ( argc , argv ) ;
if ( argc = = 0 & & net_rpc_check ( NET_FLAGS_PDC ) )
return net_rpc_group ( argc , argv ) ;
return net_rap_group ( argc , argv ) ;
}
2001-10-19 20:51:26 +04:00
2002-03-16 01:04:53 +03:00
static int net_join ( int argc , const char * * argv )
{
2002-04-04 20:53:07 +04:00
if ( net_ads_check ( ) = = 0 ) {
2002-03-16 01:04:53 +03:00
if ( net_ads_join ( argc , argv ) = = 0 )
return 0 ;
else
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " ADS join did not work, falling back to RPC... \n " ) ;
2002-03-16 01:04:53 +03:00
}
return net_rpc_join ( argc , argv ) ;
}
2003-04-15 02:27:09 +04:00
static int net_changetrustpw ( int argc , const char * * argv )
{
if ( net_ads_check ( ) = = 0 )
return net_ads_changetrustpw ( argc , argv ) ;
return net_rpc_changetrustpw ( argc , argv ) ;
}
2003-08-29 00:24:25 +04:00
static int net_changesecretpw ( int argc , const char * * argv )
{
char * trust_pw ;
uint32 sec_channel_type = SEC_CHAN_WKSTA ;
if ( opt_force ) {
trust_pw = getpass ( " Enter machine password: " ) ;
if ( ! secrets_store_machine_password ( trust_pw , lp_workgroup ( ) , sec_channel_type ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unable to write the machine account password in the secrets database " ) ;
2003-08-29 00:24:25 +04:00
return 1 ;
}
else {
d_printf ( " Modified trust account password in secrets database \n " ) ;
}
}
else {
d_printf ( " Machine account password change requires the -f flag. \n " ) ;
d_printf ( " Do NOT use this function unless you know what it does! \n " ) ;
d_printf ( " This function will change the ADS Domain member machine account password in the secrets.tdb file! \n " ) ;
}
return 0 ;
}
2002-07-15 14:35:28 +04:00
static int net_share ( int argc , const char * * argv )
{
if ( net_rpc_check ( 0 ) )
return net_rpc_share ( argc , argv ) ;
return net_rap_share ( argc , argv ) ;
}
static int net_file ( int argc , const char * * argv )
{
if ( net_rpc_check ( 0 ) )
return net_rpc_file ( argc , argv ) ;
return net_rap_file ( argc , argv ) ;
}
2002-09-25 19:19:00 +04:00
/*
Retrieve our local SID or the SID for the specified name
*/
static int net_getlocalsid ( int argc , const char * * argv )
{
DOM_SID sid ;
const char * name ;
fstring sid_str ;
if ( argc > = 1 ) {
name = argv [ 0 ] ;
}
else {
2002-11-13 02:20:50 +03:00
name = global_myname ( ) ;
2002-09-25 19:19:00 +04:00
}
2004-02-26 01:01:02 +03:00
if ( ! initialize_password_db ( False ) ) {
DEBUG ( 0 , ( " WARNING: Could not open passdb - local sid may not reflect passdb \n "
" backend knowlege (such as the sid stored in LDAP) \n " ) ) ;
}
2004-11-15 20:20:58 +03:00
/* first check to see if we can even access secrets, so we don't
panic when we can ' t . */
if ( ! secrets_init ( ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Unable to open secrets.tdb. Can't fetch domain SID for name: %s \n " , name ) ;
2004-11-15 20:20:58 +03:00
return 1 ;
}
2004-02-26 02:12:29 +03:00
/* Generate one, if it doesn't exist */
get_global_sam_sid ( ) ;
2002-09-25 19:19:00 +04:00
if ( ! secrets_fetch_domain_sid ( name , & sid ) ) {
2004-11-15 20:20:58 +03:00
DEBUG ( 0 , ( " Can't fetch domain SID for name: %s \n " , name ) ) ;
2002-09-25 19:19:00 +04:00
return 1 ;
}
sid_to_string ( sid_str , & sid ) ;
d_printf ( " SID for domain %s is: %s \n " , name , sid_str ) ;
return 0 ;
}
static int net_setlocalsid ( int argc , const char * * argv )
{
DOM_SID sid ;
if ( ( argc ! = 1 )
| | ( strncmp ( argv [ 0 ] , " S-1-5-21- " , strlen ( " S-1-5-21- " ) ) ! = 0 )
| | ( ! string_to_sid ( & sid , argv [ 0 ] ) )
| | ( sid . num_auths ! = 4 ) ) {
d_printf ( " usage: net setlocalsid S-1-5-21-x-y-z \n " ) ;
return 1 ;
}
2002-11-13 02:20:50 +03:00
if ( ! secrets_store_domain_sid ( global_myname ( ) , & sid ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " Can't store domain SID as a pdc/bdc. \n " ) ) ;
return 1 ;
}
return 0 ;
}
static int net_getdomainsid ( int argc , const char * * argv )
{
DOM_SID domain_sid ;
fstring sid_str ;
2004-02-26 01:01:02 +03:00
if ( ! initialize_password_db ( False ) ) {
DEBUG ( 0 , ( " WARNING: Could not open passdb - domain sid may not reflect passdb \n "
" backend knowlege (such as the sid stored in LDAP) \n " ) ) ;
}
2004-02-26 02:12:29 +03:00
/* Generate one, if it doesn't exist */
get_global_sam_sid ( ) ;
2002-11-13 02:20:50 +03:00
if ( ! secrets_fetch_domain_sid ( global_myname ( ) , & domain_sid ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not fetch local SID \n " ) ;
2002-09-25 19:19:00 +04:00
return 1 ;
}
sid_to_string ( sid_str , & domain_sid ) ;
2002-11-13 02:20:50 +03:00
d_printf ( " SID for domain %s is: %s \n " , global_myname ( ) , sid_str ) ;
2002-09-25 19:19:00 +04:00
2003-04-21 21:25:54 +04:00
if ( ! secrets_fetch_domain_sid ( opt_workgroup , & domain_sid ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not fetch domain SID \n " ) ;
2002-09-25 19:19:00 +04:00
return 1 ;
}
sid_to_string ( sid_str , & domain_sid ) ;
2003-04-21 21:25:54 +04:00
d_printf ( " SID for domain %s is: %s \n " , opt_workgroup , sid_str ) ;
2002-09-25 19:19:00 +04:00
return 0 ;
}
2003-09-07 20:36:13 +04:00
# ifdef WITH_FAKE_KASERVER
2005-02-10 20:38:49 +03:00
int net_help_afs ( int argc , const char * * argv )
2003-09-07 20:36:13 +04:00
{
2005-02-10 20:38:49 +03:00
d_printf ( " net afs key filename \n "
2003-09-07 20:36:13 +04:00
" \t Imports a OpenAFS KeyFile into our secrets.tdb \n \n " ) ;
2005-02-10 20:38:49 +03:00
d_printf ( " net afs impersonate <user> <cell> \n "
" \t Creates a token for user@cell \n \n " ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
2005-02-10 20:38:49 +03:00
static int net_afs_key ( int argc , const char * * argv )
2003-09-07 20:36:13 +04:00
{
int fd ;
struct afs_keyfile keyfile ;
2003-09-23 18:52:21 +04:00
if ( argc ! = 2 ) {
2005-06-30 00:17:05 +04:00
d_printf ( " usage: 'net afs key <keyfile> cell' \n " ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
if ( ! secrets_init ( ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not open secrets.tdb \n " ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
if ( ( fd = open ( argv [ 0 ] , O_RDONLY , 0 ) ) < 0 ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not open %s \n " , argv [ 0 ] ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
if ( read ( fd , & keyfile , sizeof ( keyfile ) ) ! = sizeof ( keyfile ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not read keyfile \n " ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
2003-09-23 18:52:21 +04:00
if ( ! secrets_store_afs_keyfile ( argv [ 1 ] , & keyfile ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not write keyfile to secrets.tdb \n " ) ;
2003-09-07 20:36:13 +04:00
return - 1 ;
}
return 0 ;
}
2005-02-10 20:38:49 +03:00
static int net_afs_impersonate ( int argc , const char * * argv )
{
char * token ;
if ( argc ! = 2 ) {
fprintf ( stderr , " Usage: net afs impersonate <user> <cell> \n " ) ;
exit ( 1 ) ;
}
token = afs_createtoken_str ( argv [ 0 ] , argv [ 1 ] ) ;
if ( token = = NULL ) {
fprintf ( stderr , " Could not create token \n " ) ;
exit ( 1 ) ;
}
if ( ! afs_settoken_str ( token ) ) {
fprintf ( stderr , " Could not set token into kernel \n " ) ;
exit ( 1 ) ;
}
printf ( " Success: %s@%s \n " , argv [ 0 ] , argv [ 1 ] ) ;
return 0 ;
}
static int net_afs ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " key " , net_afs_key } ,
{ " impersonate " , net_afs_impersonate } ,
{ " help " , net_help_afs } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_help_afs ) ;
}
2003-09-07 20:36:13 +04:00
# endif /* WITH_FAKE_KASERVER */
2005-04-10 19:26:37 +04:00
static BOOL search_maxrid ( struct pdb_search * search , const char * type ,
uint32 * max_rid )
2003-01-15 20:22:48 +03:00
{
2005-04-10 19:26:37 +04:00
struct samr_displayentry * entries ;
uint32 i , num_entries ;
2003-01-15 20:22:48 +03:00
2005-04-10 19:26:37 +04:00
if ( search = = NULL ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " get_maxrid: Could not search %s \n " , type ) ;
2005-04-10 19:26:37 +04:00
return False ;
2003-01-15 20:22:48 +03:00
}
2005-04-10 19:26:37 +04:00
num_entries = pdb_search_entries ( search , 0 , 0xffffffff , & entries ) ;
for ( i = 0 ; i < num_entries ; i + + )
* max_rid = MAX ( * max_rid , entries [ i ] . rid ) ;
pdb_search_destroy ( search ) ;
return True ;
}
2003-01-15 20:22:48 +03:00
2005-04-10 19:26:37 +04:00
static uint32 get_maxrid ( void )
{
uint32 max_rid = 0 ;
2003-01-15 20:22:48 +03:00
2005-04-10 19:26:37 +04:00
if ( ! search_maxrid ( pdb_search_users ( 0 ) , " users " , & max_rid ) )
return 0 ;
2003-01-15 20:22:48 +03:00
2005-04-10 19:26:37 +04:00
if ( ! search_maxrid ( pdb_search_groups ( ) , " groups " , & max_rid ) )
return 0 ;
2003-01-15 20:22:48 +03:00
2005-04-10 19:26:37 +04:00
if ( ! search_maxrid ( pdb_search_aliases ( get_global_sam_sid ( ) ) ,
" aliases " , & max_rid ) )
return 0 ;
2003-01-15 20:22:48 +03:00
return max_rid ;
}
static int net_maxrid ( int argc , const char * * argv )
{
uint32 rid ;
if ( argc ! = 0 ) {
2003-04-14 07:59:04 +04:00
DEBUG ( 0 , ( " usage: net maxrid \n " ) ) ;
2003-01-15 20:22:48 +03:00
return 1 ;
}
if ( ( rid = get_maxrid ( ) ) = = 0 ) {
DEBUG ( 0 , ( " can't get current maximum rid \n " ) ) ;
return 1 ;
}
d_printf ( " Currently used maximum rid: %d \n " , rid ) ;
return 0 ;
}
2001-11-24 16:26:01 +03:00
/* main function table */
static struct functable net_func [ ] = {
2001-12-03 07:39:23 +03:00
{ " RPC " , net_rpc } ,
{ " RAP " , net_rap } ,
2001-11-25 03:18:11 +03:00
{ " ADS " , net_ads } ,
2001-12-11 01:25:21 +03:00
/* eventually these should auto-choose the transport ... */
2002-07-15 14:35:28 +04:00
{ " FILE " , net_file } ,
{ " SHARE " , net_share } ,
2001-12-11 01:25:21 +03:00
{ " SESSION " , net_rap_session } ,
{ " SERVER " , net_rap_server } ,
{ " DOMAIN " , net_rap_domain } ,
{ " PRINTQ " , net_rap_printq } ,
2002-04-04 20:53:07 +04:00
{ " USER " , net_user } ,
2002-07-15 14:35:28 +04:00
{ " GROUP " , net_group } ,
2003-04-19 09:53:55 +04:00
{ " GROUPMAP " , net_groupmap } ,
2006-02-04 01:19:41 +03:00
{ " SAM " , net_sam } ,
2001-12-11 01:25:21 +03:00
{ " VALIDATE " , net_rap_validate } ,
{ " GROUPMEMBER " , net_rap_groupmember } ,
{ " ADMIN " , net_rap_admin } ,
{ " SERVICE " , net_rap_service } ,
{ " PASSWORD " , net_rap_password } ,
2003-04-15 02:27:09 +04:00
{ " CHANGETRUSTPW " , net_changetrustpw } ,
2003-08-29 00:24:25 +04:00
{ " CHANGESECRETPW " , net_changesecretpw } ,
2001-12-11 08:21:50 +03:00
{ " TIME " , net_time } ,
2001-12-20 10:42:00 +03:00
{ " LOOKUP " , net_lookup } ,
2002-03-16 01:04:53 +03:00
{ " JOIN " , net_join } ,
2002-09-25 19:19:00 +04:00
{ " CACHE " , net_cache } ,
{ " GETLOCALSID " , net_getlocalsid } ,
{ " SETLOCALSID " , net_setlocalsid } ,
{ " GETDOMAINSID " , net_getdomainsid } ,
2003-01-15 20:22:48 +03:00
{ " MAXRID " , net_maxrid } ,
2003-06-13 20:19:02 +04:00
{ " IDMAP " , net_idmap } ,
2003-12-01 16:58:43 +03:00
{ " STATUS " , net_status } ,
2006-02-04 01:19:41 +03:00
{ " USERSHARE " , net_usershare } ,
2004-10-12 15:58:01 +04:00
{ " USERSIDLIST " , net_usersidlist } ,
2003-09-07 20:36:13 +04:00
# ifdef WITH_FAKE_KASERVER
2005-02-10 20:38:49 +03:00
{ " AFS " , net_afs } ,
2003-09-07 20:36:13 +04:00
# endif
2001-12-11 01:25:21 +03:00
2001-11-24 16:26:01 +03:00
{ " HELP " , net_help } ,
{ NULL , NULL }
} ;
2001-11-13 01:50:48 +03:00
2001-10-19 20:51:26 +04:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-26 08:59:43 +03:00
int main ( int argc , const char * * argv )
2001-10-19 20:51:26 +04:00
{
2001-11-24 16:26:01 +03:00
int opt , i ;
char * p ;
int rc = 0 ;
int argc_new = 0 ;
const char * * argv_new ;
poptContext pc ;
struct poptOption long_options [ ] = {
2002-03-15 23:03:07 +03:00
{ " help " , ' h ' , POPT_ARG_NONE , 0 , ' h ' } ,
{ " workgroup " , ' w ' , POPT_ARG_STRING , & opt_target_workgroup } ,
{ " user " , ' U ' , POPT_ARG_STRING , & opt_user_name , ' U ' } ,
{ " ipaddress " , ' I ' , POPT_ARG_STRING , 0 , ' I ' } ,
{ " port " , ' p ' , POPT_ARG_INT , & opt_port } ,
{ " myname " , ' n ' , POPT_ARG_STRING , & opt_requester_name } ,
{ " server " , ' S ' , POPT_ARG_STRING , & opt_host } ,
2003-01-15 19:10:57 +03:00
{ " container " , ' c ' , POPT_ARG_STRING , & opt_container } ,
2002-03-15 23:03:07 +03:00
{ " comment " , ' C ' , POPT_ARG_STRING , & opt_comment } ,
{ " maxusers " , ' M ' , POPT_ARG_INT , & opt_maxusers } ,
{ " flags " , ' F ' , POPT_ARG_INT , & opt_flags } ,
{ " long " , ' l ' , POPT_ARG_NONE , & opt_long_list_entries } ,
{ " reboot " , ' r ' , POPT_ARG_NONE , & opt_reboot } ,
{ " force " , ' f ' , POPT_ARG_NONE , & opt_force } ,
{ " timeout " , ' t ' , POPT_ARG_INT , & opt_timeout } ,
2002-07-15 14:35:28 +04:00
{ " machine-pass " , ' P ' , POPT_ARG_NONE , & opt_machine_pass } ,
2003-04-14 07:59:04 +04:00
{ " myworkgroup " , ' W ' , POPT_ARG_STRING , & opt_workgroup } ,
2004-04-19 00:22:31 +04:00
{ " verbose " , ' v ' , POPT_ARG_NONE , & opt_verbose } ,
2004-02-26 14:29:56 +03:00
/* Options for 'net groupmap set' */
{ " local " , ' L ' , POPT_ARG_NONE , & opt_localgroup } ,
{ " domain " , ' D ' , POPT_ARG_NONE , & opt_domaingroup } ,
{ " ntname " , ' N ' , POPT_ARG_STRING , & opt_newntname } ,
{ " rid " , ' R ' , POPT_ARG_INT , & opt_rid } ,
2004-08-10 18:27:17 +04:00
/* Options for 'net rpc share migrate' */
2004-08-27 01:37:20 +04:00
{ " acls " , 0 , POPT_ARG_NONE , & opt_acls } ,
{ " attrs " , 0 , POPT_ARG_NONE , & opt_attrs } ,
{ " timestamps " , 0 , POPT_ARG_NONE , & opt_timestamps } ,
2004-08-10 18:27:17 +04:00
{ " exclude " , ' e ' , POPT_ARG_STRING , & opt_exclude } ,
2004-08-27 01:37:20 +04:00
{ " destination " , 0 , POPT_ARG_STRING , & opt_destination } ,
2004-02-26 14:29:56 +03:00
2003-04-14 07:59:04 +04:00
POPT_COMMON_SAMBA
2001-11-24 16:26:01 +03:00
{ 0 , 0 , 0 , 0 }
} ;
2001-12-11 08:21:50 +03:00
zero_ip ( & opt_dest_ip ) ;
2001-11-24 16:26:01 +03:00
2005-12-29 00:10:11 +03:00
load_case_tables ( ) ;
2003-07-19 04:23:08 +04:00
/* set default debug level to 0 regardless of what smb.conf sets */
DEBUGLEVEL_CLASS [ DBGC_ALL ] = 0 ;
2001-12-20 10:13:47 +03:00
dbf = x_stderr ;
2001-11-24 16:26:01 +03:00
pc = poptGetContext ( NULL , argc , ( const char * * ) argv , long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
case ' h ' :
2002-04-05 05:36:28 +04:00
net_help ( argc , argv ) ;
2001-11-24 16:26:01 +03:00
exit ( 0 ) ;
break ;
case ' I ' :
2001-12-11 08:21:50 +03:00
opt_dest_ip = * interpret_addr2 ( poptGetOptArg ( pc ) ) ;
if ( is_zero_ip ( opt_dest_ip ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " \n Invalid ip address specified \n " ) ;
2001-11-24 16:26:01 +03:00
else
2001-12-11 08:21:50 +03:00
opt_have_ip = True ;
2001-11-24 16:26:01 +03:00
break ;
case ' U ' :
2002-01-26 01:07:46 +03:00
opt_user_specified = True ;
2004-12-07 21:25:53 +03:00
opt_user_name = SMB_STRDUP ( opt_user_name ) ;
2001-11-24 16:26:01 +03:00
p = strchr ( opt_user_name , ' % ' ) ;
if ( p ) {
* p = 0 ;
opt_password = p + 1 ;
}
break ;
default :
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " \n Invalid option %s: %s \n " ,
2003-01-21 17:08:33 +03:00
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
2002-04-05 05:36:28 +04:00
net_help ( argc , argv ) ;
2002-07-15 14:35:28 +04:00
exit ( 1 ) ;
2001-11-24 16:26:01 +03:00
}
2001-10-23 18:16:59 +04:00
}
2003-04-14 07:59:04 +04:00
2003-07-19 04:23:08 +04:00
/*
* Don ' t load debug level from smb . conf . It should be
* set by cmdline arg or remain default ( 0 )
*/
AllowDebugChange = False ;
2006-01-29 01:53:04 +03:00
lp_load ( dyn_CONFIGFILE , True , False , False , True ) ;
2003-07-19 04:23:08 +04:00
argv_new = ( const char * * ) poptGetArgs ( pc ) ;
2001-10-19 20:51:26 +04:00
2001-11-24 16:26:01 +03:00
argc_new = argc ;
for ( i = 0 ; i < argc ; i + + ) {
if ( argv_new [ i ] = = NULL ) {
argc_new = i ;
break ;
}
}
2002-07-15 14:35:28 +04:00
2004-04-05 12:31:58 +04:00
if ( opt_requester_name ) {
set_global_myname ( opt_requester_name ) ;
2001-11-24 16:26:01 +03:00
}
if ( ! opt_user_name & & getenv ( " LOGNAME " ) ) {
opt_user_name = getenv ( " LOGNAME " ) ;
}
if ( ! opt_workgroup ) {
2003-04-21 18:09:03 +04:00
opt_workgroup = smb_xstrdup ( lp_workgroup ( ) ) ;
2001-11-24 16:26:01 +03:00
}
2001-12-04 07:48:01 +03:00
if ( ! opt_target_workgroup ) {
2003-04-21 18:09:03 +04:00
opt_target_workgroup = smb_xstrdup ( lp_workgroup ( ) ) ;
2001-12-04 07:48:01 +03:00
}
2002-11-13 02:20:50 +03:00
if ( ! init_names ( ) )
exit ( 1 ) ;
2001-12-05 14:00:26 +03:00
2001-11-24 16:26:01 +03:00
load_interfaces ( ) ;
2003-06-14 04:49:02 +04:00
/* this makes sure that when we do things like call scripts,
that it won ' t assert becouse we are not root */
sec_init ( ) ;
2001-10-19 20:51:26 +04:00
2002-07-15 14:35:28 +04:00
if ( opt_machine_pass ) {
/* it is very useful to be able to make ads queries as the
machine account for testing purposes and for domain leave */
2003-08-20 02:47:10 +04:00
net_use_machine_password ( ) ;
2002-07-15 14:35:28 +04:00
}
2003-04-14 07:59:04 +04:00
if ( ! opt_password ) {
opt_password = getenv ( " PASSWD " ) ;
}
2002-07-15 14:35:28 +04:00
2002-04-05 05:36:28 +04:00
rc = net_run_function ( argc_new - 1 , argv_new + 1 , net_func , net_help ) ;
2001-11-24 16:26:01 +03:00
DEBUG ( 2 , ( " return code = %d \n " , rc ) ) ;
return rc ;
}