2000-04-25 18:04:06 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-04-25 18:04:06 +04:00
client RAP calls
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"
/****************************************************************************
Call a remote api on an arbitrary pipe . takes param , data and setup buffers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-01-03 11:28:12 +03:00
BOOL cli_api_pipe ( struct cli_state * cli , const char * pipe_name ,
2000-04-25 18:04:06 +04:00
uint16 * setup , uint32 setup_count , uint32 max_setup_count ,
char * params , uint32 param_count , uint32 max_param_count ,
char * data , uint32 data_count , uint32 max_data_count ,
char * * rparam , uint32 * rparam_count ,
char * * rdata , uint32 * rdata_count )
{
cli_send_trans ( cli , SMBtrans ,
2001-02-20 13:11:40 +03:00
pipe_name ,
2000-04-25 18:04:06 +04:00
0 , 0 , /* fid, flags */
setup , setup_count , max_setup_count ,
params , param_count , max_param_count ,
data , data_count , max_data_count ) ;
return ( cli_receive_trans ( cli , SMBtrans ,
2003-03-13 03:51:05 +03:00
rparam , ( unsigned int * ) rparam_count ,
rdata , ( unsigned int * ) rdata_count ) ) ;
2000-04-25 18:04:06 +04:00
}
/****************************************************************************
call a remote api
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_api ( struct cli_state * cli ,
char * param , int prcnt , int mprcnt ,
char * data , int drcnt , int mdrcnt ,
2003-03-13 03:51:05 +03:00
char * * rparam , unsigned int * rprcnt ,
char * * rdata , unsigned int * rdrcnt )
2000-04-25 18:04:06 +04:00
{
cli_send_trans ( cli , SMBtrans ,
2001-02-20 13:11:40 +03:00
PIPE_LANMAN , /* Name */
0 , 0 , /* fid, flags */
2000-04-25 18:04:06 +04:00
NULL , 0 , 0 , /* Setup, length, max */
param , prcnt , mprcnt , /* Params, length, max */
data , drcnt , mdrcnt /* Data, length, max */
) ;
return ( cli_receive_trans ( cli , SMBtrans ,
rparam , rprcnt ,
rdata , rdrcnt ) ) ;
}
/****************************************************************************
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 ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , " OOWb54WrLh " , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , " WB21BWDWWDDDDDDDzzzD " , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 1 ) ;
p + = 2 ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , user , param ) ;
2000-04-25 18:04:06 +04:00
strupper ( p ) ;
p + = 21 ;
p + + ;
p + = 15 ;
p + + ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , workstation , param ) ;
2000-04-25 18:04:06 +04:00
strupper ( p ) ;
p + = 16 ;
SSVAL ( p , 0 , CLI_BUFFER_SIZE ) ;
p + = 2 ;
SSVAL ( p , 0 , CLI_BUFFER_SIZE ) ;
p + = 2 ;
if ( cli_api ( cli ,
param , PTR_DIFF ( p , param ) , 1024 , /* param, length, max */
NULL , 0 , CLI_BUFFER_SIZE , /* data, length, max */
& rparam , & rprcnt , /* return params, return size */
& rdata , & rdrcnt /* return data, return size */
) ) {
2000-04-30 19:13:15 +04:00
cli - > rap_error = rparam ? SVAL ( rparam , 0 ) : - 1 ;
2000-04-25 18:04:06 +04:00
p = rdata ;
if ( cli - > rap_error = = 0 ) {
DEBUG ( 4 , ( " NetWkstaUserLogon success \n " ) ) ;
cli - > privileges = SVAL ( p , 24 ) ;
2002-07-15 14:35:28 +04:00
/* The cli->eff_name field used to be set here
but it wasn ' t used anywhere else . */
2000-04-25 18:04:06 +04:00
} else {
DEBUG ( 1 , ( " NetwkstaUserLogon gave error %d \n " , cli - > rap_error ) ) ;
}
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rparam ) ;
SAFE_FREE ( rdata ) ;
2000-04-25 18:04:06 +04:00
return ( cli - > rap_error = = 0 ) ;
}
/****************************************************************************
call a NetShareEnum - try and browse available connections on a host
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-04 14:35:55 +03:00
int cli_RNetShareEnum ( struct cli_state * cli , void ( * fn ) ( const char * , uint32 , const char * , void * ) , void * state )
2000-04-25 18:04:06 +04:00
{
2000-04-30 19:13:15 +04:00
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
int count = - 1 ;
2000-04-25 18:04:06 +04:00
2000-04-30 19:13:15 +04:00
/* now send a SMBtrans command with api RNetShareEnum */
p = param ;
SSVAL ( p , 0 , 0 ) ; /* api number */
p + = 2 ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , " WrLeh " , param ) ;
2000-04-30 19:13:15 +04:00
p = skip_string ( p , 1 ) ;
2003-03-10 19:54:57 +03:00
pstrcpy_base ( p , " B13BWz " , param ) ;
2000-04-30 19:13:15 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 1 ) ;
/*
* Win2k needs a * smaller * buffer than 0xFFFF here -
* it returns " out of server memory " with 0xFFFF ! ! ! JRA .
*/
SSVAL ( p , 2 , 0xFFE0 ) ;
p + = 4 ;
if ( cli_api ( cli ,
param , PTR_DIFF ( p , param ) , 1024 , /* Param, length, maxlen */
NULL , 0 , 0xFFE0 , /* data, length, maxlen - Win2k needs a small buffer here too ! */
& rparam , & rprcnt , /* return params, length */
& rdata , & rdrcnt ) ) /* return data, length */
{
int res = rparam ? SVAL ( rparam , 0 ) : - 1 ;
if ( res = = 0 | | res = = ERRmoredata ) {
int converter = SVAL ( rparam , 2 ) ;
int i ;
count = SVAL ( rparam , 4 ) ;
p = rdata ;
for ( i = 0 ; i < count ; i + + , p + = 20 ) {
char * sname = p ;
int type = SVAL ( p , 14 ) ;
int comment_offset = IVAL ( p , 16 ) & 0xFFFF ;
2003-01-03 11:28:12 +03:00
const char * cmnt = comment_offset ? ( rdata + comment_offset - converter ) : " " ;
2001-06-21 05:01:15 +04:00
pstring s1 , s2 ;
2001-07-04 11:15:53 +04:00
pull_ascii_pstring ( s1 , sname ) ;
pull_ascii_pstring ( s2 , cmnt ) ;
2001-06-21 05:01:15 +04:00
fn ( s1 , type , s2 , state ) ;
2000-04-30 19:13:15 +04:00
}
} else {
DEBUG ( 4 , ( " NetShareEnum res=%d \n " , res ) ) ;
}
} else {
DEBUG ( 4 , ( " NetShareEnum failed \n " ) ) ;
}
2000-04-25 18:04:06 +04:00
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rparam ) ;
SAFE_FREE ( rdata ) ;
2000-04-30 19:13:15 +04:00
return count ;
2000-04-25 18:04:06 +04:00
}
/****************************************************************************
2001-07-03 08:09:09 +04:00
call a NetServerEnum for the specified workgroup and servertype mask . This
function then calls the specified callback function for each name returned .
2000-04-25 18:04:06 +04:00
2001-07-03 08:09:09 +04:00
The callback function takes 4 arguments : the machine name , the server type ,
the comment and a state pointer .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_NetServerEnum ( struct cli_state * cli , char * workgroup , uint32 stype ,
2001-01-04 14:35:55 +03:00
void ( * fn ) ( const char * , uint32 , const char * , void * ) ,
void * state )
2000-04-25 18:04:06 +04:00
{
char * rparam = NULL ;
char * rdata = NULL ;
int rdrcnt , rprcnt ;
char * p ;
pstring param ;
int uLevel = 1 ;
int count = - 1 ;
2001-01-04 14:35:55 +03:00
2000-04-25 18:04:06 +04:00
/* send a SMBtrans command with api NetServerEnum */
p = param ;
SSVAL ( p , 0 , 0x68 ) ; /* api number */
p + = 2 ;
2003-03-18 01:40:37 +03:00
pstrcpy_base ( p , " WrLehDz " , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
2003-03-18 01:40:37 +03:00
pstrcpy_base ( p , " B16BBDz " , param ) ;
2001-01-04 14:35:55 +03:00
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , uLevel ) ;
SSVAL ( p , 2 , CLI_BUFFER_SIZE ) ;
p + = 4 ;
SIVAL ( p , 0 , stype ) ;
p + = 4 ;
2001-02-20 16:16:01 +03:00
2003-05-26 23:47:53 +04:00
p + = push_ascii ( p , workgroup , sizeof ( pstring ) - PTR_DIFF ( p , param ) - 1 , STR_TERMINATE | STR_UPPER ) ;
2000-04-25 18:04:06 +04:00
if ( cli_api ( cli ,
param , PTR_DIFF ( p , param ) , 8 , /* params, length, max */
NULL , 0 , CLI_BUFFER_SIZE , /* data, length, max */
& rparam , & rprcnt , /* return params, return size */
& rdata , & rdrcnt /* return data, return size */
) ) {
2000-04-30 19:13:15 +04:00
int res = rparam ? SVAL ( rparam , 0 ) : - 1 ;
2000-04-25 18:04:06 +04:00
if ( res = = 0 | | res = = ERRmoredata ) {
2000-04-30 19:13:15 +04:00
int i ;
int converter = SVAL ( rparam , 2 ) ;
2000-04-25 18:04:06 +04:00
count = SVAL ( rparam , 4 ) ;
p = rdata ;
2001-02-21 05:52:41 +03:00
for ( i = 0 ; i < count ; i + + , p + = 26 ) {
char * sname = p ;
int comment_offset = ( IVAL ( p , 22 ) & 0xFFFF ) - converter ;
2003-01-03 11:28:12 +03:00
const char * cmnt = comment_offset ? ( rdata + comment_offset ) : " " ;
2001-06-21 05:01:15 +04:00
pstring s1 , s2 ;
2001-02-21 05:52:41 +03:00
if ( comment_offset < 0 | | comment_offset > rdrcnt ) continue ;
2001-01-04 14:35:55 +03:00
2001-02-21 05:52:41 +03:00
stype = IVAL ( p , 18 ) & ~ SV_TYPE_LOCAL_LIST_ONLY ;
2001-01-04 14:35:55 +03:00
2001-07-04 11:15:53 +04:00
pull_ascii_pstring ( s1 , sname ) ;
pull_ascii_pstring ( s2 , cmnt ) ;
2001-06-21 05:01:15 +04:00
fn ( s1 , stype , s2 , state ) ;
2000-04-25 18:04:06 +04:00
}
}
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rparam ) ;
SAFE_FREE ( rdata ) ;
2000-04-25 18:04:06 +04:00
return ( count > 0 ) ;
}
/****************************************************************************
Send a SamOEMChangePassword command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_oem_change_password ( struct cli_state * cli , const char * user , const char * new_password ,
const char * old_password )
{
2003-03-18 01:40:37 +03:00
pstring param ;
2000-04-25 18:04:06 +04:00
char data [ 532 ] ;
char * p = param ;
unsigned char old_pw_hash [ 16 ] ;
unsigned char new_pw_hash [ 16 ] ;
2003-03-13 03:51:05 +03:00
unsigned int data_len ;
unsigned int param_len = 0 ;
2000-04-25 18:04:06 +04:00
char * rparam = NULL ;
char * rdata = NULL ;
int rprcnt , rdrcnt ;
pstring dos_new_password ;
if ( strlen ( user ) > = sizeof ( fstring ) - 1 ) {
DEBUG ( 0 , ( " cli_oem_change_password: user name %s is too long. \n " , user ) ) ;
return False ;
}
SSVAL ( p , 0 , 214 ) ; /* SamOEMChangePassword command. */
p + = 2 ;
2003-03-18 01:40:37 +03:00
pstrcpy_base ( p , " zsT " , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
2003-03-18 01:40:37 +03:00
pstrcpy_base ( p , " B516B16 " , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
2003-03-18 01:40:37 +03:00
pstrcpy_base ( p , user , param ) ;
2000-04-25 18:04:06 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 532 ) ;
p + = 2 ;
param_len = PTR_DIFF ( p , param ) ;
/*
* Get the Lanman hash of the old password , we
* use this as the key to make_oem_passwd_hash ( ) .
*/
2002-07-15 14:35:28 +04:00
E_deshash ( old_password , old_pw_hash ) ;
2000-04-25 18:04:06 +04:00
2003-03-18 01:40:37 +03:00
clistr_push ( cli , dos_new_password , new_password , sizeof ( dos_new_password ) , STR_TERMINATE | STR_ASCII ) ;
2000-04-25 18:04:06 +04:00
2001-08-10 10:00:33 +04:00
if ( ! make_oem_passwd_hash ( data , dos_new_password , old_pw_hash , False ) )
2000-04-25 18:04:06 +04:00
return False ;
/*
* Now place the old password hash in the data .
*/
2002-07-15 14:35:28 +04:00
E_deshash ( new_password , new_pw_hash ) ;
2000-04-25 18:04:06 +04:00
E_old_pw_hash ( new_pw_hash , old_pw_hash , ( uchar * ) & data [ 516 ] ) ;
data_len = 532 ;
if ( cli_send_trans ( cli , SMBtrans ,
2001-02-20 13:11:40 +03:00
PIPE_LANMAN , /* name */
2000-04-25 18:04:06 +04:00
0 , 0 , /* fid, flags */
NULL , 0 , 0 , /* setup, length, max */
param , param_len , 2 , /* param, length, max */
data , data_len , 0 /* data, length, max */
) = = False ) {
DEBUG ( 0 , ( " cli_oem_change_password: Failed to send password change for user %s \n " ,
user ) ) ;
return False ;
}
2002-10-26 06:20:59 +04:00
if ( ! cli_receive_trans ( cli , SMBtrans ,
2000-04-25 18:04:06 +04:00
& rparam , & rprcnt ,
& rdata , & rdrcnt ) ) {
2002-10-26 06:20:59 +04:00
DEBUG ( 0 , ( " cli_oem_change_password: Failed to recieve reply to password change for user %s \n " ,
user ) ) ;
return False ;
2000-04-25 18:04:06 +04:00
}
2002-10-26 06:20:59 +04:00
if ( rparam )
cli - > rap_error = SVAL ( rparam , 0 ) ;
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rparam ) ;
SAFE_FREE ( rdata ) ;
2000-04-25 18:04:06 +04:00
return ( cli - > rap_error = = 0 ) ;
}
/****************************************************************************
send a qpathinfo call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qpathinfo ( struct cli_state * cli , const char * fname ,
time_t * c_time , time_t * a_time , time_t * m_time ,
size_t * size , uint16 * mode )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
unsigned int rparam_len , rdata_len ;
2000-04-25 18:04:06 +04:00
uint16 setup = TRANSACT2_QPATHINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
int count = 8 ;
BOOL ret ;
time_t ( * date_fn ) ( void * ) ;
2001-02-21 07:14:28 +03:00
char * p ;
2000-04-25 18:04:06 +04:00
2001-02-21 07:14:28 +03:00
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_INFO_STANDARD ) ;
p + = 6 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
2000-04-25 18:04:06 +04:00
2001-02-21 07:14:28 +03:00
param_len = PTR_DIFF ( p , param ) ;
2000-04-25 18:04:06 +04:00
do {
ret = ( cli_send_trans ( cli , SMBtrans2 ,
2001-02-20 13:11:40 +03:00
NULL , /* Name */
2000-04-25 18:04:06 +04:00
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 10 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) & &
cli_receive_trans ( cli , SMBtrans2 ,
2002-02-05 04:30:02 +03:00
& rparam , & rparam_len ,
& rdata , & rdata_len ) ) ;
if ( ! cli_is_dos_error ( cli ) ) break ;
if ( ! ret ) {
2000-04-25 18:04:06 +04:00
/* we need to work around a Win95 bug - sometimes
it gives ERRSRV / ERRerror temprarily */
uint8 eclass ;
uint32 ecode ;
2001-08-10 10:00:33 +04:00
cli_dos_error ( cli , & eclass , & ecode ) ;
2000-04-25 18:04:06 +04:00
if ( eclass ! = ERRSRV | | ecode ! = ERRerror ) break ;
msleep ( 100 ) ;
}
} while ( count - - & & ret = = False ) ;
2002-02-05 04:30:02 +03:00
if ( ! ret | | ! rdata | | rdata_len < 22 ) {
2000-04-25 18:04:06 +04:00
return False ;
}
if ( cli - > win95 ) {
date_fn = make_unix_date ;
} else {
date_fn = make_unix_date2 ;
}
if ( c_time ) {
* c_time = date_fn ( rdata + 0 ) ;
}
if ( a_time ) {
* a_time = date_fn ( rdata + 4 ) ;
}
if ( m_time ) {
* m_time = date_fn ( rdata + 8 ) ;
}
if ( size ) {
* size = IVAL ( rdata , 12 ) ;
}
if ( mode ) {
* mode = SVAL ( rdata , l1_attrFile ) ;
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
2000-04-25 18:04:06 +04:00
return True ;
}
/****************************************************************************
send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qpathinfo2 ( struct cli_state * cli , const char * fname ,
time_t * c_time , time_t * a_time , time_t * m_time ,
time_t * w_time , size_t * size , uint16 * mode ,
SMB_INO_T * ino )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2000-04-25 18:04:06 +04:00
uint16 setup = TRANSACT2_QPATHINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
2001-02-21 07:14:28 +03:00
char * p ;
2000-04-25 18:04:06 +04:00
2001-02-21 07:14:28 +03:00
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_QUERY_FILE_ALL_INFO ) ;
p + = 6 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
2000-04-25 18:04:06 +04:00
2001-02-21 07:14:28 +03:00
param_len = PTR_DIFF ( p , param ) ;
2000-04-25 18:04:06 +04:00
if ( ! cli_send_trans ( cli , SMBtrans2 ,
2001-02-20 13:11:40 +03:00
NULL , /* name */
2000-04-25 18:04:06 +04:00
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 10 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
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 ( mode ) {
* mode = SVAL ( rdata , 32 ) ;
}
if ( size ) {
* size = IVAL ( rdata , 48 ) ;
}
if ( ino ) {
* ino = IVAL ( rdata , 64 ) ;
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
2000-04-25 18:04:06 +04:00
return True ;
}
2002-02-21 07:25:17 +03:00
/****************************************************************************
send a qfileinfo QUERY_FILE_NAME_INFO call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qfilename ( struct cli_state * cli , int fnum ,
pstring name )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2002-02-21 07:25:17 +03:00
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_QUERY_FILE_NAME_INFO ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 ,
NULL , /* name */
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 2 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
if ( ! rdata | | data_len < 4 ) {
return False ;
}
clistr_pull ( cli , name , rdata + 4 , sizeof ( pstring ) , IVAL ( rdata , 0 ) , STR_UNICODE ) ;
return True ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
send a qfileinfo call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qfileinfo ( struct cli_state * cli , int fnum ,
uint16 * mode , size_t * size ,
time_t * c_time , time_t * a_time , time_t * m_time ,
time_t * w_time , SMB_INO_T * ino )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2000-04-25 18:04:06 +04:00
uint16 setup = TRANSACT2_QFILEINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
/* if its a win95 server then fail this - win95 totally screws it
up */
if ( cli - > win95 ) return False ;
param_len = 4 ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_QUERY_FILE_ALL_INFO ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 ,
2001-02-20 13:11:40 +03:00
NULL , /* name */
2000-04-25 18:04:06 +04:00
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 2 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
if ( ! rdata | | data_len < 68 ) {
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 ( mode ) {
* mode = SVAL ( rdata , 32 ) ;
}
if ( size ) {
* size = IVAL ( rdata , 48 ) ;
}
if ( ino ) {
* ino = IVAL ( rdata , 64 ) ;
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
2000-04-25 18:04:06 +04:00
return True ;
}
2001-06-19 03:31:22 +04:00
/****************************************************************************
send a qfileinfo call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_qfileinfo_test ( struct cli_state * cli , int fnum , int level , char * outdata )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2001-06-19 03:31:22 +04:00
uint16 setup = TRANSACT2_QFILEINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
/* if its a win95 server then fail this - win95 totally screws it
up */
if ( cli - > win95 ) return False ;
param_len = 4 ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , level ) ;
if ( ! cli_send_trans ( cli , SMBtrans2 ,
NULL , /* name */
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 2 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
memcpy ( outdata , rdata , data_len ) ;
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
2001-06-19 03:31:22 +04:00
return True ;
}
2001-09-25 08:25:49 +04:00
/****************************************************************************
send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS cli_qpathinfo_alt_name ( struct cli_state * cli , const char * fname , fstring alt_name )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2001-09-25 08:25:49 +04:00
uint16 setup = TRANSACT2_QPATHINFO ;
pstring param ;
char * rparam = NULL , * rdata = NULL ;
int count = 8 ;
char * p ;
BOOL ret ;
2003-03-18 01:40:37 +03:00
unsigned int len ;
2001-09-25 08:25:49 +04:00
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_QUERY_FILE_ALT_NAME_INFO ) ;
p + = 6 ;
p + = clistr_push ( cli , p , fname , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
do {
ret = ( cli_send_trans ( cli , SMBtrans2 ,
NULL , /* Name */
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 10 , /* param, length, max */
NULL , data_len , cli - > max_xmit /* data, length, max */
) & &
cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) ;
if ( ! ret & & cli_is_dos_error ( cli ) ) {
/* we need to work around a Win95 bug - sometimes
it gives ERRSRV / ERRerror temprarily */
uint8 eclass ;
uint32 ecode ;
cli_dos_error ( cli , & eclass , & ecode ) ;
if ( eclass ! = ERRSRV | | ecode ! = ERRerror ) break ;
msleep ( 100 ) ;
}
} while ( count - - & & ret = = False ) ;
if ( ! ret | | ! rdata | | data_len < 4 ) {
return NT_STATUS_UNSUCCESSFUL ;
}
len = IVAL ( rdata , 0 ) ;
if ( len > data_len - 4 ) {
return NT_STATUS_INVALID_NETWORK_RESPONSE ;
}
2003-01-14 06:02:18 +03:00
clistr_pull ( cli , alt_name , rdata + 4 , sizeof ( fstring ) , len , STR_UNICODE ) ;
2001-09-25 08:25:49 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return NT_STATUS_OK ;
}