2000-04-25 18:04:06 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
client connect / disconnect routines
Copyright ( C ) Andrew Tridgell 1994 - 1998
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 .
*/
# define NO_SYSLOG
# include "includes.h"
static struct {
int prot ;
char * name ;
}
prots [ ] =
{
{ PROTOCOL_CORE , " PC NETWORK PROGRAM 1.0 " } ,
{ PROTOCOL_COREPLUS , " MICROSOFT NETWORKS 1.03 " } ,
{ PROTOCOL_LANMAN1 , " MICROSOFT NETWORKS 3.0 " } ,
{ PROTOCOL_LANMAN1 , " LANMAN1.0 " } ,
{ PROTOCOL_LANMAN2 , " LM1.2X002 " } ,
{ PROTOCOL_LANMAN2 , " Samba " } ,
{ PROTOCOL_NT1 , " NT LANMAN 1.0 " } ,
{ PROTOCOL_NT1 , " NT LM 0.12 " } ,
{ - 1 , NULL }
} ;
/****************************************************************************
2001-02-14 08:34:50 +03:00
Send a session setup . The username and workgroup is in UNIX character
format and must be converted to DOS codepage format before sending . If the
password is in plaintext , the same should be done .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_session_setup ( struct cli_state * cli ,
char * user ,
char * pass , int passlen ,
char * ntpass , int ntpasslen ,
char * workgroup )
{
char * p ;
fstring pword , ntpword ;
2000-12-04 07:26:22 +03:00
fstring user2 ;
/* allow for workgroups as part of the username */
fstrcpy ( user2 , user ) ;
if ( ( p = strchr ( user2 , ' \\ ' ) ) | | ( p = strchr ( user2 , ' / ' ) ) ) {
* p = 0 ;
user = p + 1 ;
workgroup = user2 ;
}
2000-04-25 18:04:06 +04:00
if ( cli - > protocol < PROTOCOL_LANMAN1 )
return True ;
if ( passlen > sizeof ( pword ) - 1 | | ntpasslen > sizeof ( ntpword ) - 1 ) {
return False ;
}
if ( ( ( passlen = = 0 ) | | ( passlen = = 1 ) ) & & ( pass [ 0 ] = = ' \0 ' ) ) {
/* Null session connect. */
pword [ 0 ] = ' \0 ' ;
ntpword [ 0 ] = ' \0 ' ;
} else {
if ( ( cli - > sec_mode & 2 ) & & passlen ! = 24 ) {
/*
* Encrypted mode needed , and non encrypted password supplied .
*/
passlen = 24 ;
ntpasslen = 24 ;
fstrcpy ( pword , pass ) ;
unix_to_dos ( pword , True ) ;
fstrcpy ( ntpword , ntpass ) ; ;
SMBencrypt ( ( uchar * ) pword , ( uchar * ) cli - > cryptkey , ( uchar * ) pword ) ;
SMBNTencrypt ( ( uchar * ) ntpword , ( uchar * ) cli - > cryptkey , ( uchar * ) ntpword ) ;
} else if ( ( cli - > sec_mode & 2 ) & & passlen = = 24 ) {
/*
* Encrypted mode needed , and encrypted password supplied .
*/
memcpy ( pword , pass , passlen ) ;
if ( ntpasslen = = 24 ) {
memcpy ( ntpword , ntpass , ntpasslen ) ;
} else {
fstrcpy ( ntpword , " " ) ;
ntpasslen = 0 ;
}
} else {
/*
* Plaintext mode needed , assume plaintext supplied .
*/
2001-03-10 14:35:25 +03:00
passlen = clistr_push ( cli , pword , pass , - 1 , STR_CONVERT | STR_TERMINATE ) ;
2000-04-25 18:04:06 +04:00
fstrcpy ( ntpword , " " ) ;
ntpasslen = 0 ;
}
}
/* if in share level security then don't send a password now */
if ( ! ( cli - > sec_mode & 1 ) ) {
fstrcpy ( pword , " " ) ;
passlen = 1 ;
fstrcpy ( ntpword , " " ) ;
ntpasslen = 1 ;
}
/* send a session setup command */
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
if ( cli - > protocol < PROTOCOL_NT1 )
{
2001-02-20 13:11:40 +03:00
set_message ( cli - > outbuf , 10 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
CVAL ( cli - > outbuf , smb_com ) = SMBsesssetupX ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , cli - > max_xmit ) ;
SSVAL ( cli - > outbuf , smb_vwv3 , 2 ) ;
SSVAL ( cli - > outbuf , smb_vwv4 , 1 ) ;
SIVAL ( cli - > outbuf , smb_vwv5 , cli - > sesskey ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , passlen ) ;
p = smb_buf ( cli - > outbuf ) ;
memcpy ( p , pword , passlen ) ;
p + = passlen ;
2001-03-10 14:35:25 +03:00
p + = clistr_push ( cli , p , user , - 1 , STR_CONVERT | STR_UPPER | STR_TERMINATE ) ;
2001-02-20 15:45:50 +03:00
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
}
else
{
2001-02-20 15:22:30 +03:00
uint32 capabilities ;
capabilities = CAP_NT_SMBS ;
2001-02-21 06:40:20 +03:00
if ( cli - > use_level_II_oplocks ) {
2001-02-20 15:22:30 +03:00
capabilities | = CAP_LEVEL_II_OPLOCKS ;
2001-02-21 06:40:20 +03:00
}
if ( cli - > capabilities & CAP_UNICODE ) {
2001-02-20 15:22:30 +03:00
capabilities | = CAP_UNICODE ;
}
2000-04-25 18:04:06 +04:00
set_message ( cli - > outbuf , 13 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBsesssetupX ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , CLI_BUFFER_SIZE ) ;
SSVAL ( cli - > outbuf , smb_vwv3 , 2 ) ;
SSVAL ( cli - > outbuf , smb_vwv4 , cli - > pid ) ;
SIVAL ( cli - > outbuf , smb_vwv5 , cli - > sesskey ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , passlen ) ;
SSVAL ( cli - > outbuf , smb_vwv8 , ntpasslen ) ;
2001-02-20 15:22:30 +03:00
SIVAL ( cli - > outbuf , smb_vwv11 , capabilities ) ;
2000-04-25 18:04:06 +04:00
p = smb_buf ( cli - > outbuf ) ;
memcpy ( p , pword , passlen ) ;
p + = SVAL ( cli - > outbuf , smb_vwv7 ) ;
memcpy ( p , ntpword , ntpasslen ) ;
p + = SVAL ( cli - > outbuf , smb_vwv8 ) ;
2001-03-10 14:35:25 +03:00
p + = clistr_push ( cli , p , user , - 1 , STR_CONVERT | STR_TERMINATE | STR_UPPER ) ;
p + = clistr_push ( cli , p , workgroup , - 1 , STR_CONVERT | STR_TERMINATE | STR_UPPER ) ;
p + = clistr_push ( cli , p , " Unix " , - 1 , STR_CONVERT | STR_TERMINATE ) ;
p + = clistr_push ( cli , p , " Samba " , - 1 , STR_CONVERT | STR_TERMINATE ) ;
2001-02-20 15:45:50 +03:00
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
}
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
show_msg ( cli - > inbuf ) ;
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
/* use the returned vuid from now on */
cli - > vuid = SVAL ( cli - > inbuf , smb_uid ) ;
if ( cli - > protocol > = PROTOCOL_NT1 ) {
2001-02-20 11:09:06 +03:00
/*
* Save off some of the connected server
* info .
*/
2001-03-01 09:36:57 +03:00
char * q = smb_buf ( cli - > inbuf ) ;
2001-03-10 14:35:25 +03:00
q + = clistr_pull ( cli , cli - > server_os , q , sizeof ( fstring ) , - 1 , STR_TERMINATE | STR_CONVERT ) ;
q + = clistr_pull ( cli , cli - > server_type , q , sizeof ( fstring ) , - 1 , STR_TERMINATE | STR_CONVERT ) ;
q + = clistr_pull ( cli , cli - > server_domain , q , sizeof ( fstring ) , - 1 , STR_TERMINATE | STR_CONVERT ) ;
2000-04-25 18:04:06 +04:00
}
fstrcpy ( cli - > user_name , user ) ;
return True ;
}
/****************************************************************************
Send a uloggoff .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_ulogoff ( struct cli_state * cli )
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
set_message ( cli - > outbuf , 2 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBulogoffX ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
SSVAL ( cli - > outbuf , smb_vwv2 , 0 ) ; /* no additional info */
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
return CVAL ( cli - > inbuf , smb_rcls ) = = 0 ;
}
/****************************************************************************
send a tconX
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_send_tconX ( struct cli_state * cli ,
char * share , char * dev , char * pass , int passlen )
{
fstring fullshare , pword , dos_pword ;
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
fstrcpy ( cli - > share , share ) ;
/* in user level security don't send a password now */
if ( cli - > sec_mode & 1 ) {
passlen = 1 ;
pass = " " ;
}
if ( ( cli - > sec_mode & 2 ) & & * pass & & passlen ! = 24 ) {
/*
* Non - encrypted passwords - convert to DOS codepage before encryption .
*/
passlen = 24 ;
fstrcpy ( dos_pword , pass ) ;
unix_to_dos ( dos_pword , True ) ;
SMBencrypt ( ( uchar * ) dos_pword , ( uchar * ) cli - > cryptkey , ( uchar * ) pword ) ;
} else {
2001-02-20 11:09:06 +03:00
if ( ( cli - > sec_mode & 3 ) = = 0 ) {
2000-04-25 18:04:06 +04:00
/*
* Non - encrypted passwords - convert to DOS codepage before using .
*/
2001-03-10 14:35:25 +03:00
passlen = clistr_push ( cli , pword , pass , - 1 , STR_CONVERT | STR_TERMINATE ) ;
2000-04-25 18:04:06 +04:00
} else {
memcpy ( pword , pass , passlen ) ;
}
}
slprintf ( fullshare , sizeof ( fullshare ) - 1 ,
" \\ \\ %s \\ %s " , cli - > desthost , share ) ;
unix_to_dos ( fullshare , True ) ;
strupper ( fullshare ) ;
2001-02-20 13:11:40 +03:00
set_message ( cli - > outbuf , 4 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
CVAL ( cli - > outbuf , smb_com ) = SMBtconX ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
SSVAL ( cli - > outbuf , smb_vwv3 , passlen ) ;
p = smb_buf ( cli - > outbuf ) ;
memcpy ( p , pword , passlen ) ;
p + = passlen ;
2001-03-10 14:35:25 +03:00
p + = clistr_push ( cli , p , fullshare , - 1 , STR_CONVERT | STR_TERMINATE ) ;
2001-02-20 11:09:06 +03:00
fstrcpy ( p , dev ) ; p + = strlen ( dev ) + 1 ;
2001-02-20 15:45:50 +03:00
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
SCVAL ( cli - > inbuf , smb_rcls , 1 ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
fstrcpy ( cli - > dev , " A: " ) ;
if ( cli - > protocol > = PROTOCOL_NT1 ) {
2001-03-10 14:35:25 +03:00
clistr_pull ( cli , cli - > dev , smb_buf ( cli - > inbuf ) , sizeof ( fstring ) , - 1 , STR_TERMINATE | STR_CONVERT ) ;
2000-04-25 18:04:06 +04:00
}
if ( strcasecmp ( share , " IPC$ " ) = = 0 ) {
fstrcpy ( cli - > dev , " IPC " ) ;
}
/* only grab the device if we have a recent protocol level */
if ( cli - > protocol > = PROTOCOL_NT1 & &
smb_buflen ( cli - > inbuf ) = = 3 ) {
/* almost certainly win95 - enable bug fixes */
cli - > win95 = True ;
}
cli - > cnum = SVAL ( cli - > inbuf , smb_tid ) ;
return True ;
}
/****************************************************************************
send a tree disconnect
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_tdis ( struct cli_state * cli )
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
set_message ( cli - > outbuf , 0 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBtdis ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
return CVAL ( cli - > inbuf , smb_rcls ) = = 0 ;
}
2000-09-26 09:44:42 +04:00
/****************************************************************************
send a negprot command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void cli_negprot_send ( struct cli_state * cli )
{
char * p ;
int numprots ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
/* setup the protocol strings */
2001-02-26 02:46:02 +03:00
set_message ( cli - > outbuf , 0 , 0 , True ) ;
2000-09-26 09:44:42 +04:00
p = smb_buf ( cli - > outbuf ) ;
for ( numprots = 0 ;
prots [ numprots ] . name & & prots [ numprots ] . prot < = cli - > protocol ;
numprots + + ) {
* p + + = 2 ;
pstrcpy ( p , prots [ numprots ] . name ) ;
unix_to_dos ( p , True ) ;
p + = strlen ( p ) + 1 ;
}
CVAL ( cli - > outbuf , smb_com ) = SMBnegprot ;
2001-02-26 02:46:02 +03:00
cli_setup_bcc ( cli , p ) ;
2000-09-26 09:44:42 +04:00
cli_setup_packet ( cli ) ;
CVAL ( smb_buf ( cli - > outbuf ) , 0 ) = 2 ;
cli_send_smb ( cli ) ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
send a negprot command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_negprot ( struct cli_state * cli )
{
char * p ;
int numprots ;
int plength ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
/* setup the protocol strings */
for ( plength = 0 , numprots = 0 ;
prots [ numprots ] . name & & prots [ numprots ] . prot < = cli - > protocol ;
numprots + + )
plength + = strlen ( prots [ numprots ] . name ) + 2 ;
set_message ( cli - > outbuf , 0 , plength , True ) ;
p = smb_buf ( cli - > outbuf ) ;
for ( numprots = 0 ;
prots [ numprots ] . name & & prots [ numprots ] . prot < = cli - > protocol ;
numprots + + ) {
* p + + = 2 ;
pstrcpy ( p , prots [ numprots ] . name ) ;
unix_to_dos ( p , True ) ;
p + = strlen ( p ) + 1 ;
}
CVAL ( cli - > outbuf , smb_com ) = SMBnegprot ;
cli_setup_packet ( cli ) ;
CVAL ( smb_buf ( cli - > outbuf ) , 0 ) = 2 ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
show_msg ( cli - > inbuf ) ;
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 | |
( ( int ) SVAL ( cli - > inbuf , smb_vwv0 ) > = numprots ) ) {
return ( False ) ;
}
cli - > protocol = prots [ SVAL ( cli - > inbuf , smb_vwv0 ) ] . prot ;
if ( cli - > protocol > = PROTOCOL_NT1 ) {
/* NT protocol */
cli - > sec_mode = CVAL ( cli - > inbuf , smb_vwv1 ) ;
cli - > max_mux = SVAL ( cli - > inbuf , smb_vwv1 + 1 ) ;
cli - > max_xmit = IVAL ( cli - > inbuf , smb_vwv3 + 1 ) ;
cli - > sesskey = IVAL ( cli - > inbuf , smb_vwv7 + 1 ) ;
cli - > serverzone = SVALS ( cli - > inbuf , smb_vwv15 + 1 ) ;
cli - > serverzone * = 60 ;
/* this time arrives in real GMT */
cli - > servertime = interpret_long_date ( cli - > inbuf + smb_vwv11 + 1 ) ;
memcpy ( cli - > cryptkey , smb_buf ( cli - > inbuf ) , 8 ) ;
cli - > capabilities = IVAL ( cli - > inbuf , smb_vwv9 + 1 ) ;
2000-12-21 03:30:32 +03:00
if ( cli - > capabilities & CAP_RAW_MODE ) {
2000-04-25 18:04:06 +04:00
cli - > readbraw_supported = True ;
cli - > writebraw_supported = True ;
}
2001-06-21 09:38:28 +04:00
/* work out if they sent us a workgroup */
if ( smb_buflen ( cli - > inbuf ) > 8 ) {
clistr_pull ( cli , cli - > server_domain ,
smb_buf ( cli - > inbuf ) + 8 , sizeof ( cli - > server_domain ) ,
smb_buflen ( cli - > inbuf ) - 8 , STR_CONVERT | STR_UNICODE | STR_NOALIGN ) ;
}
2000-04-25 18:04:06 +04:00
} else if ( cli - > protocol > = PROTOCOL_LANMAN1 ) {
cli - > sec_mode = SVAL ( cli - > inbuf , smb_vwv1 ) ;
cli - > max_xmit = SVAL ( cli - > inbuf , smb_vwv2 ) ;
cli - > sesskey = IVAL ( cli - > inbuf , smb_vwv6 ) ;
cli - > serverzone = SVALS ( cli - > inbuf , smb_vwv10 ) ;
cli - > serverzone * = 60 ;
/* this time is converted to GMT by make_unix_date */
cli - > servertime = make_unix_date ( cli - > inbuf + smb_vwv8 ) ;
cli - > readbraw_supported = ( ( SVAL ( cli - > inbuf , smb_vwv5 ) & 0x1 ) ! = 0 ) ;
cli - > writebraw_supported = ( ( SVAL ( cli - > inbuf , smb_vwv5 ) & 0x2 ) ! = 0 ) ;
memcpy ( cli - > cryptkey , smb_buf ( cli - > inbuf ) , 8 ) ;
} else {
/* the old core protocol */
cli - > sec_mode = 0 ;
cli - > serverzone = TimeDiff ( time ( NULL ) ) ;
}
cli - > max_xmit = MIN ( cli - > max_xmit , CLI_BUFFER_SIZE ) ;
2001-02-21 06:40:20 +03:00
/* a way to force ascii SMB */
if ( getenv ( " CLI_FORCE_ASCII " ) ) {
cli - > capabilities & = ~ CAP_UNICODE ;
}
2001-02-20 11:09:06 +03:00
2000-04-25 18:04:06 +04:00
return True ;
}
/****************************************************************************
send a session request . see rfc1002 . txt 4.3 and 4.3 .2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_session_request ( struct cli_state * cli ,
struct nmb_name * calling , struct nmb_name * called )
{
char * p ;
int len = 4 ;
extern pstring user_socket_options ;
/* send a session request (RFC 1002) */
memcpy ( & ( cli - > calling ) , calling , sizeof ( * calling ) ) ;
memcpy ( & ( cli - > called ) , called , sizeof ( * called ) ) ;
/* put in the destination name */
p = cli - > outbuf + len ;
name_mangle ( cli - > called . name , p , cli - > called . name_type ) ;
len + = name_len ( p ) ;
/* and my name */
p = cli - > outbuf + len ;
name_mangle ( cli - > calling . name , p , cli - > calling . name_type ) ;
len + = name_len ( p ) ;
/* setup the packet length */
_smb_setlen ( cli - > outbuf , len ) ;
CVAL ( cli - > outbuf , 0 ) = 0x81 ;
# ifdef WITH_SSL
retry :
# endif /* WITH_SSL */
cli_send_smb ( cli ) ;
DEBUG ( 5 , ( " Sent session request \n " ) ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
if ( CVAL ( cli - > inbuf , 0 ) = = 0x84 ) {
/* C. Hoch 9/14/95 Start */
/* For information, here is the response structure.
* We do the byte - twiddling to for portability .
struct RetargetResponse {
unsigned char type ;
unsigned char flags ;
int16 length ;
int32 ip_addr ;
int16 port ;
} ;
*/
int port = ( CVAL ( cli - > inbuf , 8 ) < < 8 ) + CVAL ( cli - > inbuf , 9 ) ;
/* SESSION RETARGET */
putip ( ( char * ) & cli - > dest_ip , cli - > inbuf + 4 ) ;
cli - > fd = open_socket_out ( SOCK_STREAM , & cli - > dest_ip , port , LONG_CONNECT_TIMEOUT ) ;
if ( cli - > fd = = - 1 )
return False ;
DEBUG ( 3 , ( " Retargeted \n " ) ) ;
set_socket_options ( cli - > fd , user_socket_options ) ;
/* Try again */
{
static int depth ;
BOOL ret ;
if ( depth > 4 ) {
DEBUG ( 0 , ( " Retarget recursion - failing \n " ) ) ;
return False ;
}
depth + + ;
ret = cli_session_request ( cli , calling , called ) ;
depth - - ;
return ret ;
}
} /* C. Hoch 9/14/95 End */
# ifdef WITH_SSL
if ( CVAL ( cli - > inbuf , 0 ) = = 0x83 & & CVAL ( cli - > inbuf , 4 ) = = 0x8e ) { /* use ssl */
if ( ! sslutil_fd_is_ssl ( cli - > fd ) ) {
if ( sslutil_connect ( cli - > fd ) = = 0 )
goto retry ;
}
}
# endif /* WITH_SSL */
if ( CVAL ( cli - > inbuf , 0 ) ! = 0x82 ) {
/* This is the wrong place to put the error... JRA. */
cli - > rap_error = CVAL ( cli - > inbuf , 4 ) ;
return False ;
}
return ( True ) ;
}
/****************************************************************************
open the client sockets
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_connect ( struct cli_state * cli , const char * host , struct in_addr * ip )
{
extern struct in_addr ipzero ;
extern pstring user_socket_options ;
fstrcpy ( cli - > desthost , host ) ;
if ( ! ip | | ip_equal ( * ip , ipzero ) ) {
if ( ! resolve_name ( cli - > desthost , & cli - > dest_ip , 0x20 ) ) {
return False ;
}
if ( ip ) * ip = cli - > dest_ip ;
} else {
cli - > dest_ip = * ip ;
}
if ( cli - > port = = 0 ) cli - > port = 139 ; /* Set to default */
2001-06-22 19:14:45 +04:00
if ( getenv ( " LIBSMB_PROG " ) ) {
cli - > fd = sock_exec ( getenv ( " LIBSMB_PROG " ) ) ;
2001-06-25 04:46:34 +04:00
} else {
2001-06-22 19:14:45 +04:00
cli - > fd = open_socket_out ( SOCK_STREAM , & cli - > dest_ip ,
cli - > port , cli - > timeout ) ;
}
2000-04-25 18:04:06 +04:00
if ( cli - > fd = = - 1 )
return False ;
set_socket_options ( cli - > fd , user_socket_options ) ;
return True ;
}
/****************************************************************************
re - establishes a connection
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_reestablish_connection ( struct cli_state * cli )
{
struct nmb_name calling ;
struct nmb_name called ;
fstring dest_host ;
fstring share ;
fstring dev ;
BOOL do_tcon = False ;
int oldfd = cli - > fd ;
if ( ! cli - > initialised | | cli - > fd = = - 1 )
{
DEBUG ( 3 , ( " cli_reestablish_connection: not connected \n " ) ) ;
return False ;
}
/* copy the parameters necessary to re-establish the connection */
if ( cli - > cnum ! = 0 )
{
fstrcpy ( share , cli - > share ) ;
fstrcpy ( dev , cli - > dev ) ;
do_tcon = True ;
}
memcpy ( & called , & ( cli - > called ) , sizeof ( called ) ) ;
memcpy ( & calling , & ( cli - > calling ) , sizeof ( calling ) ) ;
fstrcpy ( dest_host , cli - > full_dest_host_name ) ;
DEBUG ( 5 , ( " cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s] \n " ,
nmb_namestr ( & calling ) , nmb_namestr ( & called ) ,
inet_ntoa ( cli - > dest_ip ) ,
cli - > user_name , cli - > domain ) ) ;
cli - > fd = - 1 ;
if ( cli_establish_connection ( cli ,
dest_host , & cli - > dest_ip ,
& calling , & called ,
share , dev , False , do_tcon ) ) {
2000-10-29 00:54:45 +04:00
if ( ( cli - > fd ! = oldfd ) & & ( oldfd ! = - 1 ) ) {
close ( oldfd ) ;
2000-04-25 18:04:06 +04:00
}
return True ;
}
return False ;
}
/****************************************************************************
establishes a connection right up to doing tconX , reading in a password .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_establish_connection ( struct cli_state * cli ,
char * dest_host , struct in_addr * dest_ip ,
struct nmb_name * calling , struct nmb_name * called ,
char * service , char * service_type ,
BOOL do_shutdown , BOOL do_tcon )
{
DEBUG ( 5 , ( " cli_establish_connection: %s connecting to %s (%s) - %s [%s] \n " ,
nmb_namestr ( calling ) , nmb_namestr ( called ) , inet_ntoa ( * dest_ip ) ,
cli - > user_name , cli - > domain ) ) ;
/* establish connection */
if ( ( ! cli - > initialised ) )
{
return False ;
}
if ( cli - > fd = = - 1 )
{
if ( ! cli_connect ( cli , dest_host , dest_ip ) )
{
DEBUG ( 1 , ( " cli_establish_connection: failed to connect to %s (%s) \n " ,
nmb_namestr ( calling ) , inet_ntoa ( * dest_ip ) ) ) ;
return False ;
}
}
if ( ! cli_session_request ( cli , calling , called ) )
{
DEBUG ( 1 , ( " failed session request \n " ) ) ;
if ( do_shutdown )
2001-03-14 23:22:57 +03:00
cli_shutdown ( cli ) ;
2000-04-25 18:04:06 +04:00
return False ;
}
if ( ! cli_negprot ( cli ) )
{
DEBUG ( 1 , ( " failed negprot \n " ) ) ;
if ( do_shutdown )
2000-07-07 10:20:46 +04:00
cli_shutdown ( cli ) ;
2000-04-25 18:04:06 +04:00
return False ;
}
if ( cli - > pwd . cleartext | | cli - > pwd . null_pwd )
{
fstring passwd ;
int pass_len ;
if ( cli - > pwd . null_pwd )
{
/* attempt null session */
passwd [ 0 ] = 0 ;
pass_len = 1 ;
}
else
{
/* attempt clear-text session */
pwd_get_cleartext ( & ( cli - > pwd ) , passwd ) ;
pass_len = strlen ( passwd ) ;
}
/* attempt clear-text session */
if ( ! cli_session_setup ( cli , cli - > user_name ,
passwd , pass_len ,
NULL , 0 ,
cli - > domain ) )
{
DEBUG ( 1 , ( " failed session setup \n " ) ) ;
if ( do_shutdown )
{
cli_shutdown ( cli ) ;
}
return False ;
}
if ( do_tcon )
{
if ( ! cli_send_tconX ( cli , service , service_type ,
( char * ) passwd , strlen ( passwd ) ) )
{
DEBUG ( 1 , ( " failed tcon_X \n " ) ) ;
if ( do_shutdown )
{
cli_shutdown ( cli ) ;
}
return False ;
}
}
}
else
{
/* attempt encrypted session */
unsigned char nt_sess_pwd [ 24 ] ;
unsigned char lm_sess_pwd [ 24 ] ;
/* creates (storing a copy of) and then obtains a 24 byte password OWF */
pwd_make_lm_nt_owf ( & ( cli - > pwd ) , cli - > cryptkey ) ;
pwd_get_lm_nt_owf ( & ( cli - > pwd ) , lm_sess_pwd , nt_sess_pwd ) ;
/* attempt encrypted session */
if ( ! cli_session_setup ( cli , cli - > user_name ,
( char * ) lm_sess_pwd , sizeof ( lm_sess_pwd ) ,
( char * ) nt_sess_pwd , sizeof ( nt_sess_pwd ) ,
cli - > domain ) )
{
DEBUG ( 1 , ( " failed session setup \n " ) ) ;
if ( do_shutdown )
2000-07-07 10:20:46 +04:00
cli_shutdown ( cli ) ;
2000-04-25 18:04:06 +04:00
return False ;
}
2000-07-07 10:20:46 +04:00
DEBUG ( 1 , ( " session setup ok \n " ) ) ;
if ( * cli - > server_domain | | * cli - > server_os | | * cli - > server_type )
{
DEBUG ( 1 , ( " Domain=[%s] OS=[%s] Server=[%s] \n " ,
cli - > server_domain ,
cli - > server_os ,
cli - > server_type ) ) ;
}
2000-04-25 18:04:06 +04:00
if ( do_tcon )
{
if ( ! cli_send_tconX ( cli , service , service_type ,
( char * ) nt_sess_pwd , sizeof ( nt_sess_pwd ) ) )
{
DEBUG ( 1 , ( " failed tcon_X \n " ) ) ;
if ( do_shutdown )
cli_shutdown ( cli ) ;
return False ;
}
}
}
if ( do_shutdown )
cli_shutdown ( cli ) ;
return True ;
}
/****************************************************************************
Attempt a NetBIOS session request , falling back to * SMBSERVER if needed .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL attempt_netbios_session_request ( struct cli_state * cli , char * srchost , char * desthost ,
struct in_addr * pdest_ip )
{
struct nmb_name calling , called ;
make_nmb_name ( & calling , srchost , 0x0 ) ;
/*
* If the called name is an IP address
* then use * SMBSERVER immediately .
*/
if ( is_ipaddress ( desthost ) )
make_nmb_name ( & called , " *SMBSERVER " , 0x20 ) ;
else
make_nmb_name ( & called , desthost , 0x20 ) ;
if ( ! cli_session_request ( cli , & calling , & called ) ) {
struct nmb_name smbservername ;
make_nmb_name ( & smbservername , " *SMBSERVER " , 0x20 ) ;
/*
* If the name wasn ' t * SMBSERVER then
* try with * SMBSERVER if the first name fails .
*/
if ( nmb_name_equal ( & called , & smbservername ) ) {
/*
* The name used was * SMBSERVER , don ' t bother with another name .
*/
DEBUG ( 0 , ( " attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
with error % s . \ n " , desthost, cli_errstr(cli) ));
cli_shutdown ( cli ) ;
return False ;
}
cli_shutdown ( cli ) ;
if ( ! cli_initialise ( cli ) | |
! cli_connect ( cli , desthost , pdest_ip ) | |
! cli_session_request ( cli , & calling , & smbservername ) ) {
DEBUG ( 0 , ( " attempt_netbios_session_request: %s rejected the session for \
name * SMBSERVER with error % s \ n " , desthost, cli_errstr(cli) ));
cli_shutdown ( cli ) ;
return False ;
}
}
return True ;
}