1997-10-21 13:12:41 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
SMB client generic functions
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
1997-10-21 13:12:41 +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
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# ifdef SYSLOG
# undef SYSLOG
# endif
# include "includes.h"
1997-11-23 08:55:44 +03:00
# include "trans2.h"
1997-10-21 13:12:41 +04:00
extern int DEBUGLEVEL ;
/****************************************************************************
setup basics in a outgoing packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-23 23:27:53 +04:00
static void cli_setup_packet ( struct cli_state * cli )
1997-10-21 13:12:41 +04:00
{
SSVAL ( cli - > outbuf , smb_pid , cli - > pid ) ;
SSVAL ( cli - > outbuf , smb_uid , cli - > uid ) ;
SSVAL ( cli - > outbuf , smb_mid , cli - > mid ) ;
if ( cli - > protocol > PROTOCOL_CORE ) {
SCVAL ( cli - > outbuf , smb_flg , 0x8 ) ;
SSVAL ( cli - > outbuf , smb_flg2 , 0x1 ) ;
}
}
/****************************************************************************
send a SMB trans or trans2 request
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_send_trans ( struct cli_state * cli ,
int trans , char * name , int fid , int flags ,
char * data , char * param , uint16 * setup , int ldata , int lparam ,
int lsetup , int mdata , int mparam , int msetup )
{
int i ;
int this_ldata , this_lparam ;
int tot_data = 0 , tot_param = 0 ;
char * outdata , * outparam ;
char * p ;
1997-11-23 08:55:44 +03:00
this_lparam = MIN ( lparam , cli - > max_xmit - ( 500 + lsetup * 2 ) ) ; /* hack */
this_ldata = MIN ( ldata , cli - > max_xmit - ( 500 + lsetup * 2 + this_lparam ) ) ;
1997-10-21 13:12:41 +04:00
bzero ( cli - > outbuf , smb_size ) ;
set_message ( cli - > outbuf , 14 + lsetup , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = trans ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
outparam = smb_buf ( cli - > outbuf ) + ( trans = = SMBtrans ? strlen ( name ) + 1 : 3 ) ;
outdata = outparam + this_lparam ;
/* primary request */
SSVAL ( cli - > outbuf , smb_tpscnt , lparam ) ; /* tpscnt */
SSVAL ( cli - > outbuf , smb_tdscnt , ldata ) ; /* tdscnt */
SSVAL ( cli - > outbuf , smb_mprcnt , mparam ) ; /* mprcnt */
SSVAL ( cli - > outbuf , smb_mdrcnt , mdata ) ; /* mdrcnt */
SCVAL ( cli - > outbuf , smb_msrcnt , msetup ) ; /* msrcnt */
SSVAL ( cli - > outbuf , smb_flags , flags ) ; /* flags */
SIVAL ( cli - > outbuf , smb_timeout , 0 ) ; /* timeout */
SSVAL ( cli - > outbuf , smb_pscnt , this_lparam ) ; /* pscnt */
SSVAL ( cli - > outbuf , smb_psoff , smb_offset ( outparam , cli - > outbuf ) ) ; /* psoff */
SSVAL ( cli - > outbuf , smb_dscnt , this_ldata ) ; /* dscnt */
SSVAL ( cli - > outbuf , smb_dsoff , smb_offset ( outdata , cli - > outbuf ) ) ; /* dsoff */
SCVAL ( cli - > outbuf , smb_suwcnt , lsetup ) ; /* suwcnt */
for ( i = 0 ; i < lsetup ; i + + ) /* setup[] */
1997-11-23 08:55:44 +03:00
SSVAL ( cli - > outbuf , smb_setup + i * 2 , setup [ i ] ) ;
1997-10-21 13:12:41 +04:00
p = smb_buf ( cli - > outbuf ) ;
if ( trans = = SMBtrans ) {
strcpy ( p , name ) ; /* name[] */
} else {
* p + + = 0 ; /* put in a null smb_name */
* p + + = ' D ' ; * p + + = ' ' ; /* observed in OS/2 */
}
if ( this_lparam ) /* param[] */
memcpy ( outparam , param , this_lparam ) ;
if ( this_ldata ) /* data[] */
memcpy ( outdata , data , this_ldata ) ;
set_message ( cli - > outbuf , 14 + lsetup , /* wcnt, bcc */
PTR_DIFF ( outdata + this_ldata , smb_buf ( cli - > outbuf ) ) , False ) ;
show_msg ( cli - > outbuf ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
if ( this_ldata < ldata | | this_lparam < lparam ) {
/* receive interim response */
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) | |
1997-11-10 22:23:17 +03:00
CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
1997-10-21 13:12:41 +04:00
return ( False ) ;
}
tot_data = this_ldata ;
tot_param = this_lparam ;
while ( tot_data < ldata | | tot_param < lparam ) {
this_lparam = MIN ( lparam - tot_param , cli - > max_xmit - 500 ) ; /* hack */
this_ldata = MIN ( ldata - tot_data , cli - > max_xmit - ( 500 + this_lparam ) ) ;
set_message ( cli - > outbuf , trans = = SMBtrans ? 8 : 9 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = trans = = SMBtrans ? SMBtranss : SMBtranss2 ;
outparam = smb_buf ( cli - > outbuf ) ;
outdata = outparam + this_lparam ;
/* secondary request */
SSVAL ( cli - > outbuf , smb_tpscnt , lparam ) ; /* tpscnt */
SSVAL ( cli - > outbuf , smb_tdscnt , ldata ) ; /* tdscnt */
SSVAL ( cli - > outbuf , smb_spscnt , this_lparam ) ; /* pscnt */
SSVAL ( cli - > outbuf , smb_spsoff , smb_offset ( outparam , cli - > outbuf ) ) ; /* psoff */
SSVAL ( cli - > outbuf , smb_spsdisp , tot_param ) ; /* psdisp */
SSVAL ( cli - > outbuf , smb_sdscnt , this_ldata ) ; /* dscnt */
SSVAL ( cli - > outbuf , smb_sdsoff , smb_offset ( outdata , cli - > outbuf ) ) ; /* dsoff */
SSVAL ( cli - > outbuf , smb_sdsdisp , tot_data ) ; /* dsdisp */
if ( trans = = SMBtrans2 )
1997-11-23 08:55:44 +03:00
SSVALS ( cli - > outbuf , smb_sfid , fid ) ; /* fid */
1997-10-21 13:12:41 +04:00
if ( this_lparam ) /* param[] */
memcpy ( outparam , param , this_lparam ) ;
if ( this_ldata ) /* data[] */
memcpy ( outdata , data , this_ldata ) ;
set_message ( cli - > outbuf , trans = = SMBtrans ? 8 : 9 , /* wcnt, bcc */
PTR_DIFF ( outdata + this_ldata , smb_buf ( cli - > outbuf ) ) , False ) ;
show_msg ( cli - > outbuf ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
tot_data + = this_ldata ;
tot_param + = this_lparam ;
}
}
return ( True ) ;
}
/****************************************************************************
receive a SMB trans or trans2 response allocating the necessary memory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_receive_trans ( struct cli_state * cli ,
int trans , int * data_len ,
int * param_len , char * * data , char * * param )
{
int total_data = 0 ;
int total_param = 0 ;
int this_data , this_param ;
* data_len = * param_len = 0 ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
show_msg ( cli - > inbuf ) ;
/* sanity check */
if ( CVAL ( cli - > inbuf , smb_com ) ! = trans ) {
DEBUG ( 0 , ( " Expected %s response, got command 0x%02x \n " ,
trans = = SMBtrans ? " SMBtrans " : " SMBtrans2 " ,
CVAL ( cli - > inbuf , smb_com ) ) ) ;
return ( False ) ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 )
return ( False ) ;
1997-10-21 13:12:41 +04:00
/* parse out the lengths */
total_data = SVAL ( cli - > inbuf , smb_tdrcnt ) ;
total_param = SVAL ( cli - > inbuf , smb_tprcnt ) ;
/* allocate it */
* data = Realloc ( * data , total_data ) ;
* param = Realloc ( * param , total_param ) ;
while ( 1 ) {
this_data = SVAL ( cli - > inbuf , smb_drcnt ) ;
this_param = SVAL ( cli - > inbuf , smb_prcnt ) ;
if ( this_data + * data_len > total_data | |
this_param + * param_len > total_param ) {
DEBUG ( 1 , ( " Data overflow in cli_receive_trans \n " ) ) ;
return False ;
}
if ( this_data )
memcpy ( * data + SVAL ( cli - > inbuf , smb_drdisp ) ,
smb_base ( cli - > inbuf ) + SVAL ( cli - > inbuf , smb_droff ) ,
this_data ) ;
if ( this_param )
memcpy ( * param + SVAL ( cli - > inbuf , smb_prdisp ) ,
smb_base ( cli - > inbuf ) + SVAL ( cli - > inbuf , smb_proff ) ,
this_param ) ;
* data_len + = this_data ;
* param_len + = this_param ;
/* parse out the total lengths again - they can shrink! */
total_data = SVAL ( cli - > inbuf , smb_tdrcnt ) ;
total_param = SVAL ( cli - > inbuf , smb_tprcnt ) ;
if ( total_data < = * data_len & & total_param < = * param_len )
break ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
show_msg ( cli - > inbuf ) ;
/* sanity check */
if ( CVAL ( cli - > inbuf , smb_com ) ! = trans ) {
DEBUG ( 0 , ( " Expected %s response, got command 0x%02x \n " ,
trans = = SMBtrans ? " SMBtrans " : " SMBtrans2 " ,
CVAL ( cli - > inbuf , smb_com ) ) ) ;
return ( False ) ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 )
return ( False ) ;
1997-10-21 13:12:41 +04:00
}
return ( True ) ;
}
/****************************************************************************
call a remote api
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_api ( struct cli_state * cli ,
int prcnt , int drcnt , int mprcnt , int mdrcnt , int * rprcnt ,
int * rdrcnt , char * param , char * data ,
char * * rparam , char * * rdata )
{
1997-11-23 08:55:44 +03:00
cli_send_trans ( cli , SMBtrans , PIPE_LANMAN , 0 , 0 ,
1997-10-21 13:12:41 +04:00
data , param , NULL ,
drcnt , prcnt , 0 ,
mdrcnt , mprcnt , 0 ) ;
return ( cli_receive_trans ( cli , SMBtrans ,
rdrcnt , rprcnt ,
rdata , rparam ) ) ;
}
/****************************************************************************
perform a NetWkstaUserLogon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_NetWkstaUserLogon ( struct cli_state * cli , char * user , char * workstation )
{
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
memset ( param , 0 , sizeof ( param ) ) ;
/* send a SMBtrans command with api NetWkstaUserLogon */
p = param ;
SSVAL ( p , 0 , 132 ) ; /* api number */
p + = 2 ;
strcpy ( p , " OOWb54WrLh " ) ;
p = skip_string ( p , 1 ) ;
strcpy ( p , " WB21BWDWWDDDDDDDzzzD " ) ;
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 1 ) ;
p + = 2 ;
strcpy ( p , user ) ;
strupper ( p ) ;
p + = 21 ; p + + ; p + = 15 ; p + + ;
strcpy ( p , workstation ) ;
strupper ( p ) ;
p + = 16 ;
SSVAL ( p , 0 , BUFFER_SIZE ) ;
p + = 2 ;
SSVAL ( p , 0 , BUFFER_SIZE ) ;
p + = 2 ;
cli - > error = - 1 ;
if ( cli_api ( cli , PTR_DIFF ( p , param ) , 0 ,
1024 , BUFFER_SIZE ,
& rprcnt , & rdrcnt ,
param , NULL ,
& rparam , & rdata ) ) {
cli - > error = SVAL ( rparam , 0 ) ;
p = rdata ;
if ( cli - > error = = 0 ) {
DEBUG ( 4 , ( " NetWkstaUserLogon success \n " ) ) ;
1997-11-10 22:23:17 +03:00
cli - > privilages = SVAL ( p , 24 ) ;
1997-10-21 13:12:41 +04:00
fstrcpy ( cli - > eff_name , p + 2 ) ;
} else {
DEBUG ( 1 , ( " NetwkstaUserLogon gave error %d \n " , cli - > error ) ) ;
}
}
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return cli - > error = = 0 ;
}
1997-10-26 10:32:02 +03:00
/****************************************************************************
call a NetServerEnum for the specified workgroup and servertype mask .
This function then calls the specified callback function for each name returned .
The callback function takes 3 arguments : the machine name , the server type and
the comment .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_NetServerEnum ( struct cli_state * cli , char * workgroup , uint32 stype ,
void ( * fn ) ( char * , uint32 , char * ) )
{
char * rparam = NULL ;
char * rdata = NULL ;
int rdrcnt , rprcnt ;
char * p ;
pstring param ;
int uLevel = 1 ;
int count = - 1 ;
/* send a SMBtrans command with api NetServerEnum */
p = param ;
SSVAL ( p , 0 , 0x68 ) ; /* api number */
p + = 2 ;
strcpy ( p , " WrLehDz " ) ;
p = skip_string ( p , 1 ) ;
strcpy ( p , " B16BBDz " ) ;
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , uLevel ) ;
SSVAL ( p , 2 , BUFFER_SIZE ) ;
p + = 4 ;
SIVAL ( p , 0 , stype ) ;
p + = 4 ;
pstrcpy ( p , workgroup ) ;
p = skip_string ( p , 1 ) ;
if ( cli_api ( cli ,
PTR_DIFF ( p , param ) , /* param count */
1997-11-11 05:38:54 +03:00
0 , /*data count */
8 , /* mprcount */
1997-10-26 10:32:02 +03:00
BUFFER_SIZE , /* mdrcount */
& rprcnt , & rdrcnt ,
param , NULL ,
& rparam , & rdata ) ) {
int res = SVAL ( rparam , 0 ) ;
int converter = SVAL ( rparam , 2 ) ;
int i ;
if ( res = = 0 ) {
count = SVAL ( rparam , 4 ) ;
p = rdata ;
for ( i = 0 ; i < count ; i + + , p + = 26 ) {
char * sname = p ;
1997-11-23 05:41:22 +03:00
int comment_offset = ( IVAL ( p , 22 ) & 0xFFFF ) - converter ;
char * cmnt = comment_offset ? ( rdata + comment_offset ) : " " ;
if ( comment_offset < 0 | | comment_offset > rdrcnt ) continue ;
1997-10-26 10:32:02 +03:00
stype = IVAL ( p , 18 ) & ~ SV_TYPE_LOCAL_LIST_ONLY ;
fn ( sname , stype , cmnt ) ;
}
}
}
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ( count > 0 ) ;
}
1997-10-21 13:12:41 +04:00
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 LM 0.12 " } ,
{ PROTOCOL_NT1 , " NT LANMAN 1.0 " } ,
{ - 1 , NULL }
} ;
/****************************************************************************
send a session setup
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_session_setup ( struct cli_state * cli ,
char * user ,
char * pass , int passlen ,
char * ntpass , int ntpasslen ,
char * workgroup )
{
char * p ;
fstring pword ;
if ( cli - > protocol < PROTOCOL_LANMAN1 )
1997-11-23 05:41:22 +03:00
return True ;
1997-10-21 13:12:41 +04:00
if ( passlen > sizeof ( pword ) - 1 ) {
return False ;
}
1998-03-19 23:06:47 +03:00
if ( ( cli - > sec_mode & 2 ) & & passlen ! = 24 ) {
1997-10-21 13:12:41 +04:00
passlen = 24 ;
SMBencrypt ( ( uchar * ) pass , ( uchar * ) cli - > cryptkey , ( uchar * ) pword ) ;
1997-11-10 22:23:17 +03:00
} else {
1997-10-21 13:12:41 +04:00
memcpy ( pword , pass , passlen ) ;
}
/* if in share level security then don't send a password now */
1997-11-10 22:23:17 +03:00
if ( ! ( cli - > sec_mode & 1 ) ) { fstrcpy ( pword , " " ) ; passlen = 1 ; }
1997-10-21 13:12:41 +04:00
/* send a session setup command */
bzero ( cli - > outbuf , smb_size ) ;
if ( cli - > protocol < PROTOCOL_NT1 ) {
set_message ( cli - > outbuf , 10 , 1 + strlen ( user ) + passlen , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBsesssetupX ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
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 ;
strcpy ( p , user ) ;
strupper ( p ) ;
} else {
set_message ( cli - > outbuf , 13 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBsesssetupX ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , 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 ) ;
p = smb_buf ( cli - > outbuf ) ;
memcpy ( p , pword , passlen ) ;
p + = SVAL ( cli - > outbuf , smb_vwv7 ) ;
memcpy ( p , ntpass , ntpasslen ) ;
p + = SVAL ( cli - > outbuf , smb_vwv8 ) ;
strcpy ( p , user ) ;
strupper ( p ) ;
p = skip_string ( p , 1 ) ;
strcpy ( p , workgroup ) ;
strupper ( p ) ;
p = skip_string ( p , 1 ) ;
strcpy ( p , " Unix " ) ; p = skip_string ( p , 1 ) ;
strcpy ( p , " Samba " ) ; p = skip_string ( p , 1 ) ;
set_message ( cli - > outbuf , 13 , PTR_DIFF ( p , smb_buf ( cli - > outbuf ) ) , False ) ;
}
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
show_msg ( cli - > inbuf ) ;
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-10-21 13:12:41 +04:00
/* use the returned uid from now on */
cli - > uid = SVAL ( cli - > inbuf , smb_uid ) ;
return True ;
}
/****************************************************************************
send a tconX
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_send_tconX ( struct cli_state * cli ,
1997-11-01 16:22:16 +03:00
char * share , char * dev , char * pass , int passlen )
1997-10-21 13:12:41 +04:00
{
1997-11-01 16:22:16 +03:00
fstring fullshare , pword ;
1997-10-21 13:12:41 +04:00
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
1997-11-10 22:23:17 +03:00
if ( cli - > sec_mode & 1 ) {
1997-11-01 16:22:16 +03:00
passlen = 1 ;
pass = " " ;
}
1997-11-10 22:23:17 +03:00
if ( ( cli - > sec_mode & 2 ) & & * pass & & passlen ! = 24 ) {
1997-11-01 16:22:16 +03:00
passlen = 24 ;
SMBencrypt ( ( uchar * ) pass , ( uchar * ) cli - > cryptkey , ( uchar * ) pword ) ;
} else {
memcpy ( pword , pass , passlen ) ;
}
1997-11-10 22:23:17 +03:00
sprintf ( fullshare , " \\ \\ %s \\ %s " , cli - > desthost , share ) ;
1997-11-01 16:22:16 +03:00
1997-10-21 13:12:41 +04:00
set_message ( cli - > outbuf , 4 ,
1997-11-01 16:22:16 +03:00
2 + strlen ( fullshare ) + passlen + strlen ( dev ) , True ) ;
1997-10-21 13:12:41 +04:00
CVAL ( cli - > outbuf , smb_com ) = SMBtconX ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
SSVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
SSVAL ( cli - > outbuf , smb_vwv3 , passlen ) ;
p = smb_buf ( cli - > outbuf ) ;
memcpy ( p , pword , passlen ) ;
p + = passlen ;
1997-11-01 16:22:16 +03:00
strcpy ( p , fullshare ) ;
1997-10-21 13:12:41 +04:00
p = skip_string ( p , 1 ) ;
strcpy ( p , dev ) ;
SCVAL ( cli - > inbuf , smb_rcls , 1 ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-10-21 13:12:41 +04:00
cli - > cnum = SVAL ( cli - > inbuf , smb_tid ) ;
return True ;
}
/****************************************************************************
send a tree disconnect
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_tdis ( struct cli_state * cli )
{
bzero ( cli - > outbuf , smb_size ) ;
set_message ( cli - > outbuf , 0 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBtdis ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
1997-11-10 22:23:17 +03:00
return CVAL ( cli - > inbuf , smb_rcls ) = = 0 ;
1997-10-21 13:12:41 +04:00
}
1997-11-30 05:58:34 +03:00
/****************************************************************************
rename a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_mv ( struct cli_state * cli , char * fname_src , char * fname_dst )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 1 , 4 + strlen ( fname_src ) + strlen ( fname_dst ) , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBmv ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , aSYSTEM | aHIDDEN ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
strcpy ( p , fname_src ) ;
p = skip_string ( p , 1 ) ;
* p + + = 4 ;
strcpy ( p , fname_dst ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-30 05:58:34 +03:00
return False ;
}
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
return True ;
}
1997-11-01 16:22:16 +03:00
/****************************************************************************
delete a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unlink ( struct cli_state * cli , char * fname )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 1 , 2 + strlen ( fname ) , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBunlink ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , aSYSTEM | aHIDDEN ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
strcpy ( p , fname ) ;
1997-11-24 16:44:52 +03:00
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-24 16:44:52 +03:00
return False ;
}
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
return True ;
}
/****************************************************************************
create a directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_mkdir ( struct cli_state * cli , char * dname )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 0 , 2 + strlen ( dname ) , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBmkdir ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
strcpy ( p , dname ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-24 16:44:52 +03:00
return False ;
}
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
return True ;
}
/****************************************************************************
remove a directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_rmdir ( struct cli_state * cli , char * dname )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 0 , 2 + strlen ( dname ) , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBrmdir ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
strcpy ( p , dname ) ;
1997-11-01 16:22:16 +03:00
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return False ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-01 16:22:16 +03:00
return True ;
}
/****************************************************************************
open a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_open ( struct cli_state * cli , char * fname , int flags , int share_mode )
{
char * p ;
unsigned openfn = 0 ;
unsigned accessmode = 0 ;
if ( flags & O_CREAT )
openfn | = ( 1 < < 4 ) ;
if ( ! ( flags & O_EXCL ) ) {
if ( flags & O_TRUNC )
openfn | = ( 1 < < 1 ) ;
else
openfn | = ( 1 < < 0 ) ;
}
accessmode = ( share_mode < < 4 ) ;
if ( ( flags & O_RDWR ) = = O_RDWR ) {
accessmode | = 2 ;
} else if ( ( flags & O_WRONLY ) = = O_WRONLY ) {
accessmode | = 1 ;
}
1998-04-12 06:48:52 +04:00
if ( ( flags & O_SYNC ) = = O_SYNC ) {
accessmode | = ( 1 < < 14 ) ;
}
1997-11-01 16:22:16 +03:00
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 15 , 1 + strlen ( fname ) , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBopenX ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
SSVAL ( cli - > outbuf , smb_vwv2 , 0 ) ; /* no additional info */
SSVAL ( cli - > outbuf , smb_vwv3 , accessmode ) ;
SSVAL ( cli - > outbuf , smb_vwv4 , aSYSTEM | aHIDDEN ) ;
1997-11-23 05:41:22 +03:00
SSVAL ( cli - > outbuf , smb_vwv5 , 0 ) ;
1997-11-01 16:22:16 +03:00
SSVAL ( cli - > outbuf , smb_vwv8 , openfn ) ;
p = smb_buf ( cli - > outbuf ) ;
strcpy ( p , fname ) ;
p = skip_string ( p , 1 ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return - 1 ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return - 1 ;
}
1997-11-01 16:22:16 +03:00
return SVAL ( cli - > inbuf , smb_vwv2 ) ;
}
/****************************************************************************
close a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_close ( struct cli_state * cli , int fnum )
{
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 3 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBclose ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , fnum ) ;
1997-11-23 05:41:22 +03:00
SIVALS ( cli - > outbuf , smb_vwv1 , - 1 ) ;
1997-11-01 16:22:16 +03:00
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return False ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-01 16:22:16 +03:00
return True ;
}
/****************************************************************************
lock a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_lock ( struct cli_state * cli , int fnum , uint32 offset , uint32 len , int timeout )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 8 , 10 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBlockingX ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
CVAL ( cli - > outbuf , smb_vwv3 ) = 0 ;
SIVALS ( cli - > outbuf , smb_vwv4 , timeout ) ;
SSVAL ( cli - > outbuf , smb_vwv6 , 0 ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , 1 ) ;
p = smb_buf ( cli - > outbuf ) ;
SSVAL ( p , 0 , cli - > pid ) ;
SIVAL ( p , 2 , offset ) ;
SIVAL ( p , 6 , len ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return False ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-01 16:22:16 +03:00
return True ;
}
/****************************************************************************
unlock a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unlock ( struct cli_state * cli , int fnum , uint32 offset , uint32 len , int timeout )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 8 , 10 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBlockingX ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
CVAL ( cli - > outbuf , smb_vwv3 ) = 0 ;
SIVALS ( cli - > outbuf , smb_vwv4 , timeout ) ;
SSVAL ( cli - > outbuf , smb_vwv6 , 1 ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , 0 ) ;
p = smb_buf ( cli - > outbuf ) ;
SSVAL ( p , 0 , cli - > pid ) ;
SIVAL ( p , 2 , offset ) ;
SIVAL ( p , 6 , len ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return False ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-01 16:22:16 +03:00
return True ;
}
/****************************************************************************
read from a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_read ( struct cli_state * cli , int fnum , char * buf , uint32 offset , uint16 size )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 10 , 0 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBreadX ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
SIVAL ( cli - > outbuf , smb_vwv3 , offset ) ;
SSVAL ( cli - > outbuf , smb_vwv5 , size ) ;
SSVAL ( cli - > outbuf , smb_vwv6 , size ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return - 1 ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return - 1 ;
}
1997-11-01 16:22:16 +03:00
size = SVAL ( cli - > inbuf , smb_vwv5 ) ;
p = smb_base ( cli - > inbuf ) + SVAL ( cli - > inbuf , smb_vwv6 ) ;
memcpy ( buf , p , size ) ;
return size ;
}
/****************************************************************************
write to a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_write ( struct cli_state * cli , int fnum , char * buf , uint32 offset , uint16 size )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 12 , size , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBwriteX ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
CVAL ( cli - > outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
SIVAL ( cli - > outbuf , smb_vwv3 , offset ) ;
SSVAL ( cli - > outbuf , smb_vwv10 , size ) ;
SSVAL ( cli - > outbuf , smb_vwv11 , smb_buf ( cli - > outbuf ) - smb_base ( cli - > outbuf ) ) ;
p = smb_base ( cli - > outbuf ) + SVAL ( cli - > outbuf , smb_vwv11 ) ;
memcpy ( p , buf , size ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-01 16:22:16 +03:00
return - 1 ;
}
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return - 1 ;
}
1997-11-01 16:22:16 +03:00
return SVAL ( cli - > inbuf , smb_vwv2 ) ;
}
1997-10-21 13:12:41 +04:00
1997-11-23 05:41:22 +03:00
/****************************************************************************
1997-11-23 06:09:59 +03:00
do a SMBgetatr call
1997-11-23 05:41:22 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-23 06:09:59 +03:00
BOOL cli_getatr ( struct cli_state * cli , char * fname ,
int * attr , uint32 * size , time_t * t )
1997-11-23 05:41:22 +03:00
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
set_message ( cli - > outbuf , 0 , strlen ( fname ) + 2 , True ) ;
CVAL ( cli - > outbuf , smb_com ) = SMBgetatr ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p = 4 ;
strcpy ( p + 1 , fname ) ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-23 05:41:22 +03:00
return False ;
}
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-23 06:09:59 +03:00
if ( size ) {
* size = IVAL ( cli - > inbuf , smb_vwv3 ) ;
}
if ( t ) {
* t = make_unix_date3 ( cli - > inbuf + smb_vwv1 ) ;
}
if ( attr ) {
* attr = SVAL ( cli - > inbuf , smb_vwv0 ) ;
}
return True ;
}
/****************************************************************************
do a SMBsetatr call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_setatr ( struct cli_state * cli , char * fname , int attr , time_t t )
{
char * p ;
bzero ( cli - > outbuf , smb_size ) ;
bzero ( cli - > inbuf , smb_size ) ;
1997-12-03 02:30:43 +03:00
set_message ( cli - > outbuf , 8 , strlen ( fname ) + 4 , True ) ;
1997-11-23 06:09:59 +03:00
CVAL ( cli - > outbuf , smb_com ) = SMBsetatr ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , attr ) ;
put_dos_date3 ( cli - > outbuf , smb_vwv1 , t ) ;
p = smb_buf ( cli - > outbuf ) ;
* p = 4 ;
strcpy ( p + 1 , fname ) ;
1997-12-03 02:30:43 +03:00
p = skip_string ( p , 1 ) ;
* p = 4 ;
1997-11-23 06:09:59 +03:00
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ) {
1997-11-23 06:09:59 +03:00
return False ;
}
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 ) {
return False ;
}
1997-11-23 05:41:22 +03:00
return True ;
}
1997-11-23 08:55:44 +03:00
/****************************************************************************
send a qpathinfo call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qpathinfo ( struct cli_state * cli , char * fname ,
time_t * c_time , time_t * a_time , time_t * m_time , uint32 * size )
{
int data_len = 0 ;
int param_len = 0 ;
uint16 setup = TRANSACT2_QPATHINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
param_len = strlen ( fname ) + 7 ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , SMB_INFO_STANDARD ) ;
pstrcpy ( & param [ 6 ] , fname ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 , NULL , - 1 , 0 ,
NULL , param , & setup ,
data_len , param_len , 1 ,
cli - > max_xmit , 10 , 0 ) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 , & data_len , & param_len ,
& rdata , & rparam ) ) {
return False ;
}
if ( ! rdata | | data_len < 22 ) {
return False ;
}
if ( c_time ) {
* c_time = make_unix_date2 ( rdata + 0 ) ;
}
if ( a_time ) {
* a_time = make_unix_date2 ( rdata + 4 ) ;
}
if ( m_time ) {
* m_time = make_unix_date2 ( rdata + 8 ) ;
}
if ( size ) {
* size = IVAL ( rdata , 12 ) ;
}
if ( rdata ) free ( rdata ) ;
if ( rparam ) free ( rparam ) ;
return True ;
}
1997-11-23 10:26:42 +03:00
/****************************************************************************
send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qpathinfo2 ( struct cli_state * cli , char * fname ,
time_t * c_time , time_t * a_time , time_t * m_time ,
time_t * w_time , uint32 * size )
{
int data_len = 0 ;
int param_len = 0 ;
uint16 setup = TRANSACT2_QPATHINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
param_len = strlen ( fname ) + 7 ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , SMB_QUERY_FILE_ALL_INFO ) ;
pstrcpy ( & param [ 6 ] , fname ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 , NULL , - 1 , 0 ,
NULL , param , & setup ,
data_len , param_len , 1 ,
cli - > max_xmit , 10 , 0 ) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 , & data_len , & param_len ,
& rdata , & rparam ) ) {
return False ;
}
if ( ! rdata | | data_len < 22 ) {
return False ;
}
if ( c_time ) {
* c_time = interpret_long_date ( rdata + 0 ) - cli - > serverzone ;
}
if ( a_time ) {
* a_time = interpret_long_date ( rdata + 8 ) - cli - > serverzone ;
}
if ( m_time ) {
* m_time = interpret_long_date ( rdata + 16 ) - cli - > serverzone ;
}
if ( w_time ) {
* w_time = interpret_long_date ( rdata + 24 ) - cli - > serverzone ;
}
if ( size ) {
* size = IVAL ( rdata , 40 ) ;
}
if ( rdata ) free ( rdata ) ;
if ( rparam ) free ( rparam ) ;
return True ;
}
1997-11-23 08:55:44 +03:00
/****************************************************************************
send a qfileinfo call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qfileinfo ( struct cli_state * cli , int fnum ,
time_t * c_time , time_t * a_time , time_t * m_time , uint32 * size )
{
int data_len = 0 ;
int param_len = 0 ;
uint16 setup = TRANSACT2_QFILEINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
param_len = 4 ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_INFO_STANDARD ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 , NULL , - 1 , 0 ,
NULL , param , & setup ,
data_len , param_len , 1 ,
cli - > max_xmit , 2 , 0 ) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 , & data_len , & param_len ,
& rdata , & rparam ) ) {
return False ;
}
if ( ! rdata | | data_len < 22 ) {
return False ;
}
if ( c_time ) {
* c_time = make_unix_date2 ( rdata + 0 ) ;
}
if ( a_time ) {
* a_time = make_unix_date2 ( rdata + 4 ) ;
}
if ( m_time ) {
* m_time = make_unix_date2 ( rdata + 8 ) ;
}
if ( size ) {
* size = IVAL ( rdata , 12 ) ;
}
if ( rdata ) free ( rdata ) ;
if ( rparam ) free ( rparam ) ;
return True ;
}
1998-03-19 23:06:47 +03:00
/****************************************************************************
Send a SamOEMChangePassword command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_oem_change_password ( struct cli_state * cli , char * user , char * new_password ,
char * old_password )
{
char param [ 16 + sizeof ( fstring ) ] ;
char data [ 532 ] ;
char * p = param ;
fstring upper_case_old_pw ;
fstring upper_case_new_pw ;
unsigned char old_pw_hash [ 16 ] ;
unsigned char new_pw_hash [ 16 ] ;
int data_len ;
int param_len = 0 ;
int new_pw_len = strlen ( new_password ) ;
char * rparam = NULL ;
char * rdata = NULL ;
int rprcnt , rdrcnt ;
cli - > error = - 1 ;
if ( strlen ( user ) > = sizeof ( fstring ) - 1 ) {
DEBUG ( 0 , ( " cli_oem_change_password: user name %s is too long. \n " , user ) ) ;
return False ;
}
if ( new_pw_len > 512 ) {
DEBUG ( 0 , ( " cli_oem_change_password: new password for user %s is too long. \n " , user ) ) ;
return False ;
}
SSVAL ( p , 0 , 214 ) ; /* SamOEMChangePassword command. */
p + = 2 ;
strcpy ( p , " zsT " ) ;
p = skip_string ( p , 1 ) ;
strcpy ( p , " B516B16 " ) ;
p = skip_string ( p , 1 ) ;
fstrcpy ( p , user ) ;
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 532 ) ;
p + = 2 ;
param_len = PTR_DIFF ( p , param ) ;
/*
* Now setup the data area .
*/
memset ( data , ' \0 ' , sizeof ( data ) ) ;
fstrcpy ( & data [ 512 - new_pw_len ] , new_password ) ;
SIVAL ( data , 512 , new_pw_len ) ;
/*
* Get the Lanman hash of the old password , we
* use this as the key to SamOEMHash ( ) .
*/
memset ( upper_case_old_pw , ' \0 ' , sizeof ( upper_case_old_pw ) ) ;
fstrcpy ( upper_case_old_pw , old_password ) ;
strupper ( upper_case_old_pw ) ;
E_P16 ( ( uchar * ) upper_case_old_pw , old_pw_hash ) ;
SamOEMhash ( ( unsigned char * ) data , ( unsigned char * ) old_pw_hash , True ) ;
/*
* Now place the old password hash in the data .
*/
memset ( upper_case_new_pw , ' \0 ' , sizeof ( upper_case_new_pw ) ) ;
fstrcpy ( upper_case_new_pw , new_password ) ;
strupper ( upper_case_new_pw ) ;
E_P16 ( ( uchar * ) upper_case_new_pw , new_pw_hash ) ;
1998-03-24 03:37:53 +03:00
E_old_pw_hash ( new_pw_hash , old_pw_hash , ( uchar * ) & data [ 516 ] ) ;
1998-03-19 23:06:47 +03:00
data_len = 532 ;
if ( cli_send_trans ( cli , SMBtrans , PIPE_LANMAN , 0 , 0 ,
data , param , NULL ,
data_len , param_len , 0 ,
0 , 2 , 0 ) = = False ) {
DEBUG ( 0 , ( " cli_oem_change_password: Failed to send password change for user %s \n " ,
user ) ) ;
return False ;
}
if ( cli_receive_trans ( cli , SMBtrans , & rdrcnt , & rprcnt , & rdata , & rparam ) ) {
if ( rparam )
cli - > error = SVAL ( rparam , 0 ) ;
}
if ( rparam )
free ( rparam ) ;
if ( rdata )
free ( rdata ) ;
return ( cli - > error = = 0 ) ;
}
1997-11-23 05:41:22 +03:00
1997-10-21 13:12:41 +04:00
/****************************************************************************
send a negprot command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_negprot ( struct cli_state * cli )
{
char * p ;
int numprots ;
int plength ;
bzero ( cli - > outbuf , 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 ;
strcpy ( p , prots [ numprots ] . name ) ;
p + = strlen ( p ) + 1 ;
}
CVAL ( cli - > outbuf , smb_com ) = SMBnegprot ;
1997-10-23 23:27:53 +04:00
cli_setup_packet ( cli ) ;
1997-10-21 13:12:41 +04:00
CVAL ( smb_buf ( cli - > outbuf ) , 0 ) = 2 ;
send_smb ( cli - > fd , cli - > outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
show_msg ( cli - > inbuf ) ;
1997-11-10 22:23:17 +03:00
if ( CVAL ( cli - > inbuf , smb_rcls ) ! = 0 | |
( ( int ) SVAL ( cli - > inbuf , smb_vwv0 ) > = numprots ) ) {
return ( False ) ;
}
1997-10-21 13:12:41 +04:00
cli - > protocol = prots [ SVAL ( cli - > inbuf , smb_vwv0 ) ] . prot ;
1997-11-23 05:41:22 +03:00
if ( cli - > protocol > = PROTOCOL_NT1 ) {
1997-10-21 13:12:41 +04:00
/* NT protocol */
cli - > sec_mode = CVAL ( cli - > inbuf , smb_vwv1 ) ;
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 ) * 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 ) ;
if ( IVAL ( cli - > inbuf , smb_vwv9 + 1 ) & 1 )
cli - > readbraw_supported =
cli - > writebraw_supported = True ;
1997-11-23 05:41:22 +03: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 ) * 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 ) ) ;
1997-10-21 13:12:41 +04:00
}
return True ;
}
/****************************************************************************
1997-11-10 22:23:17 +03:00
send a session request
1997-10-21 13:12:41 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-10 22:23:17 +03:00
BOOL cli_session_request ( struct cli_state * cli , char * host , int name_type ,
char * myname )
1997-10-21 13:12:41 +04:00
{
1997-11-10 22:23:17 +03:00
fstring dest ;
1997-10-21 13:12:41 +04:00
char * p ;
int len = 4 ;
/* send a session request (RFC 1002) */
1997-11-10 22:23:17 +03:00
fstrcpy ( dest , host ) ;
1997-10-21 13:12:41 +04:00
1997-11-10 22:23:17 +03:00
p = strchr ( dest , ' . ' ) ;
1997-10-21 13:12:41 +04:00
if ( p ) * p = 0 ;
1997-11-10 22:23:17 +03:00
fstrcpy ( cli - > desthost , dest ) ;
1997-10-21 13:12:41 +04:00
/* put in the destination name */
p = cli - > outbuf + len ;
1997-11-10 22:23:17 +03:00
name_mangle ( dest , p , name_type ) ;
1997-10-21 13:12:41 +04:00
len + = name_len ( p ) ;
/* and my name */
p = cli - > outbuf + len ;
1997-11-10 22:23:17 +03:00
name_mangle ( myname , p , 0 ) ;
1997-10-21 13:12:41 +04:00
len + = name_len ( p ) ;
/* setup the packet length */
_smb_setlen ( cli - > outbuf , len ) ;
CVAL ( cli - > outbuf , 0 ) = 0x81 ;
send_smb ( cli - > fd , cli - > outbuf ) ;
DEBUG ( 5 , ( " Sent session request \n " ) ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) )
1997-10-21 13:12:41 +04:00
return False ;
if ( CVAL ( cli - > inbuf , 0 ) ! = 0x82 ) {
cli - > error = CVAL ( cli - > inbuf , 0 ) ;
return False ;
}
return ( True ) ;
}
/****************************************************************************
open the client sockets
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_connect ( struct cli_state * cli , char * host , struct in_addr * ip )
{
struct in_addr dest_ip ;
1997-11-10 22:23:17 +03:00
fstrcpy ( cli - > desthost , host ) ;
1997-10-21 13:12:41 +04:00
1997-11-10 22:23:17 +03:00
if ( ! ip ) {
1998-03-16 23:59:47 +03:00
if ( ! resolve_name ( cli - > desthost , & dest_ip ) ) {
return False ;
}
1997-10-21 13:12:41 +04:00
} else {
dest_ip = * ip ;
}
1997-11-10 22:23:17 +03:00
1997-10-21 13:12:41 +04:00
cli - > fd = open_socket_out ( SOCK_STREAM , & dest_ip , 139 , cli - > timeout ) ;
1997-11-10 22:23:17 +03:00
if ( cli - > fd = = - 1 )
return False ;
1997-10-21 13:12:41 +04:00
1997-11-10 22:23:17 +03:00
return True ;
1997-10-21 13:12:41 +04:00
}
/****************************************************************************
initialise a client structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_initialise ( struct cli_state * cli )
{
if ( cli - > initialised ) cli_shutdown ( cli ) ;
memset ( cli , 0 , sizeof ( * cli ) ) ;
cli - > fd = - 1 ;
cli - > cnum = - 1 ;
cli - > pid = getpid ( ) ;
cli - > mid = 1 ;
cli - > uid = getuid ( ) ;
cli - > protocol = PROTOCOL_NT1 ;
cli - > timeout = 20000 ;
cli - > bufsize = 0x10000 ;
cli - > max_xmit = cli - > bufsize - 4 ;
cli - > outbuf = ( char * ) malloc ( cli - > bufsize ) ;
cli - > inbuf = ( char * ) malloc ( cli - > bufsize ) ;
if ( ! cli - > outbuf | | ! cli - > inbuf ) return False ;
cli - > initialised = 1 ;
return True ;
}
/****************************************************************************
shutdown a client structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void cli_shutdown ( struct cli_state * cli )
{
if ( cli - > outbuf ) free ( cli - > outbuf ) ;
if ( cli - > inbuf ) free ( cli - > inbuf ) ;
if ( cli - > fd ! = - 1 ) close ( cli - > fd ) ;
memset ( cli , 0 , sizeof ( * cli ) ) ;
}
1997-11-01 16:22:16 +03:00
/****************************************************************************
return a description of the error
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cli_errstr ( struct cli_state * cli )
{
return smb_errstr ( cli - > inbuf ) ;
}
/****************************************************************************
return error codes for the last packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-10 22:23:17 +03:00
void cli_error ( struct cli_state * cli , int * eclass , int * num )
1997-11-01 16:22:16 +03:00
{
1997-11-10 22:23:17 +03:00
* eclass = CVAL ( cli - > inbuf , smb_rcls ) ;
* num = SVAL ( cli - > inbuf , smb_err ) ;
1997-11-01 16:22:16 +03:00
}
/****************************************************************************
set socket options on a open connection
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void cli_sockopt ( struct cli_state * cli , char * options )
{
set_socket_options ( cli - > fd , options ) ;
}
1997-11-08 07:02:05 +03:00
/****************************************************************************
set the PID to use for smb messages . Return the old pid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_setpid ( struct cli_state * cli , int pid )
{
int ret = cli - > pid ;
cli - > pid = pid ;
return ret ;
}