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 file operations
Copyright ( C ) Andrew Tridgell 1994 - 1998
2002-01-16 23:13:28 +03:00
Copyright ( C ) Jeremy Allison 2001 - 2002
2000-04-25 18:04:06 +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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2000-04-25 18:04:06 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2002-01-16 23:13:28 +03:00
/****************************************************************************
Hard / Symlink a file ( UNIX extensions ) .
2004-04-07 03:01:09 +04:00
Creates new name ( sym ) linked to oldname .
2002-01-16 23:13:28 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-04-07 03:01:09 +04:00
static BOOL cli_link_internal ( struct cli_state * cli , const char * oldname , const char * newname , BOOL hard_link )
2002-01-16 23:13:28 +03:00
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2002-01-16 23:13:28 +03:00
uint16 setup = TRANSACT2_SETPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
pstring data ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
2004-04-07 03:01:09 +04:00
size_t oldlen = 2 * ( strlen ( oldname ) + 1 ) ;
size_t newlen = 2 * ( strlen ( newname ) + 1 ) ;
2002-01-16 23:13:28 +03:00
memset ( param , 0 , sizeof ( param ) ) ;
SSVAL ( param , 0 , hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK ) ;
p = & param [ 6 ] ;
2004-04-07 03:01:09 +04:00
p + = clistr_push ( cli , p , newname , MIN ( newlen , sizeof ( param ) - 6 ) , STR_TERMINATE ) ;
2002-01-16 23:13:28 +03:00
param_len = PTR_DIFF ( p , param ) ;
p = data ;
2004-04-07 03:01:09 +04:00
p + = clistr_push ( cli , p , oldname , MIN ( oldlen , sizeof ( data ) ) , STR_TERMINATE ) ;
2002-01-16 23:13:28 +03:00
data_len = PTR_DIFF ( p , data ) ;
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 */
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
/****************************************************************************
Map standard UNIX permissions onto wire representations .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-09-26 10:27:54 +04:00
uint32 unix_perms_to_wire ( mode_t perms )
2002-01-16 23:13:28 +03:00
{
2002-07-15 14:35:28 +04:00
unsigned int ret = 0 ;
2002-01-16 23:13:28 +03:00
ret | = ( ( perms & S_IXOTH ) ? UNIX_X_OTH : 0 ) ;
ret | = ( ( perms & S_IWOTH ) ? UNIX_W_OTH : 0 ) ;
ret | = ( ( perms & S_IROTH ) ? UNIX_R_OTH : 0 ) ;
ret | = ( ( perms & S_IXGRP ) ? UNIX_X_GRP : 0 ) ;
ret | = ( ( perms & S_IWGRP ) ? UNIX_W_GRP : 0 ) ;
ret | = ( ( perms & S_IRGRP ) ? UNIX_R_GRP : 0 ) ;
ret | = ( ( perms & S_IXUSR ) ? UNIX_X_USR : 0 ) ;
ret | = ( ( perms & S_IWUSR ) ? UNIX_W_USR : 0 ) ;
ret | = ( ( perms & S_IRUSR ) ? UNIX_R_USR : 0 ) ;
# ifdef S_ISVTX
ret | = ( ( perms & S_ISVTX ) ? UNIX_STICKY : 0 ) ;
# endif
# ifdef S_ISGID
ret | = ( ( perms & S_ISGID ) ? UNIX_SET_GID : 0 ) ;
# endif
# ifdef S_ISUID
2002-09-25 19:19:00 +04:00
ret | = ( ( perms & S_ISUID ) ? UNIX_SET_UID : 0 ) ;
2002-01-16 23:13:28 +03:00
# endif
return ret ;
}
2004-09-26 10:27:54 +04:00
/****************************************************************************
Map wire permissions to standard UNIX .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
mode_t wire_perms_to_unix ( uint32 perms )
{
mode_t ret = ( mode_t ) 0 ;
ret | = ( ( perms & UNIX_X_OTH ) ? S_IXOTH : 0 ) ;
ret | = ( ( perms & UNIX_W_OTH ) ? S_IWOTH : 0 ) ;
ret | = ( ( perms & UNIX_R_OTH ) ? S_IROTH : 0 ) ;
ret | = ( ( perms & UNIX_X_GRP ) ? S_IXGRP : 0 ) ;
ret | = ( ( perms & UNIX_W_GRP ) ? S_IWGRP : 0 ) ;
ret | = ( ( perms & UNIX_R_GRP ) ? S_IRGRP : 0 ) ;
ret | = ( ( perms & UNIX_X_USR ) ? S_IXUSR : 0 ) ;
ret | = ( ( perms & UNIX_W_USR ) ? S_IWUSR : 0 ) ;
ret | = ( ( perms & UNIX_R_USR ) ? S_IRUSR : 0 ) ;
# ifdef S_ISVTX
ret | = ( ( perms & UNIX_STICKY ) ? S_ISVTX : 0 ) ;
# endif
# ifdef S_ISGID
ret | = ( ( perms & UNIX_SET_GID ) ? S_ISGID : 0 ) ;
# endif
# ifdef S_ISUID
ret | = ( ( perms & UNIX_SET_UID ) ? S_ISUID : 0 ) ;
# endif
return ret ;
}
/****************************************************************************
Return the file type from the wire filetype for UNIX extensions .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static mode_t unix_filetype_from_wire ( uint32 wire_type )
{
switch ( wire_type ) {
case UNIX_TYPE_FILE :
return S_IFREG ;
case UNIX_TYPE_DIR :
return S_IFDIR ;
# ifdef S_IFLNK
case UNIX_TYPE_SYMLINK :
return S_IFLNK ;
# endif
# ifdef S_IFCHR
case UNIX_TYPE_CHARDEV :
return S_IFCHR ;
# endif
# ifdef S_IFBLK
case UNIX_TYPE_BLKDEV :
return S_IFBLK ;
# endif
# ifdef S_IFIFO
case UNIX_TYPE_FIFO :
return S_IFIFO ;
# endif
# ifdef S_IFSOCK
case UNIX_TYPE_SOCKET :
return S_IFSOCK ;
# endif
default :
return ( mode_t ) 0 ;
}
}
2004-11-13 02:42:12 +03:00
/****************************************************************************
Do a POSIX getfacl ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-11-13 03:35:31 +03:00
BOOL cli_unix_getfacl ( struct cli_state * cli , const char * name , size_t * prb_size , char * * retbuf )
2004-11-13 02:42:12 +03:00
{
unsigned int param_len = 0 ;
unsigned int data_len = 0 ;
uint16 setup = TRANSACT2_QPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_QUERY_POSIX_ACL ) ;
p + = 6 ;
p + = clistr_push ( cli , p , name , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
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 , 0 , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
if ( data_len < 6 ) {
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return False ;
}
SAFE_FREE ( rparam ) ;
* retbuf = rdata ;
2004-11-13 03:35:31 +03:00
* prb_size = ( size_t ) data_len ;
2004-11-13 02:42:12 +03:00
return True ;
}
2004-09-26 10:27:54 +04:00
/****************************************************************************
Stat a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unix_stat ( struct cli_state * cli , const char * name , SMB_STRUCT_STAT * sbuf )
{
unsigned int param_len = 0 ;
unsigned int data_len = 0 ;
uint16 setup = TRANSACT2_QPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
ZERO_STRUCTP ( sbuf ) ;
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_QUERY_FILE_UNIX_BASIC ) ;
p + = 6 ;
p + = clistr_push ( cli , p , name , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
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 , 0 , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
2004-09-27 02:16:00 +04:00
}
if ( data_len < 96 ) {
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return False ;
2004-09-26 10:27:54 +04:00
}
sbuf - > st_size = IVAL2_TO_SMB_BIG_UINT ( rdata , 0 ) ; /* total size, in bytes */
sbuf - > st_blocks = IVAL2_TO_SMB_BIG_UINT ( rdata , 8 ) ; /* number of blocks allocated */
2005-07-06 18:46:36 +04:00
# if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
2004-09-26 10:27:54 +04:00
sbuf - > st_blocks / = STAT_ST_BLOCKSIZE ;
2005-07-06 18:46:36 +04:00
# else
/* assume 512 byte blocks */
sbuf - > st_blocks / = 512 ;
# endif
2006-08-24 20:44:00 +04:00
set_ctimespec ( sbuf , interpret_long_date ( rdata + 16 ) ) ; /* time of last change */
set_atimespec ( sbuf , interpret_long_date ( rdata + 24 ) ) ; /* time of last access */
set_mtimespec ( sbuf , interpret_long_date ( rdata + 32 ) ) ; /* time of last modification */
2005-04-19 23:23:49 +04:00
sbuf - > st_uid = ( uid_t ) IVAL ( rdata , 40 ) ; /* user ID of owner */
sbuf - > st_gid = ( gid_t ) IVAL ( rdata , 48 ) ; /* group ID of owner */
2004-09-26 10:27:54 +04:00
sbuf - > st_mode | = unix_filetype_from_wire ( IVAL ( rdata , 56 ) ) ;
# if defined(HAVE_MAKEDEV)
{
uint32 dev_major = IVAL ( rdata , 60 ) ;
uint32 dev_minor = IVAL ( rdata , 68 ) ;
sbuf - > st_rdev = makedev ( dev_major , dev_minor ) ;
}
# endif
sbuf - > st_ino = ( SMB_INO_T ) IVAL2_TO_SMB_BIG_UINT ( rdata , 76 ) ; /* inode */
sbuf - > st_mode | = wire_perms_to_unix ( IVAL ( rdata , 84 ) ) ; /* protection */
sbuf - > st_nlink = IVAL ( rdata , 92 ) ; /* number of hard links */
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
2002-01-16 23:13:28 +03:00
/****************************************************************************
Symlink a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-04-07 03:01:09 +04:00
BOOL cli_unix_symlink ( struct cli_state * cli , const char * oldname , const char * newname )
2002-01-16 23:13:28 +03:00
{
2004-04-07 03:01:09 +04:00
return cli_link_internal ( cli , oldname , newname , False ) ;
2002-01-16 23:13:28 +03:00
}
/****************************************************************************
Hard a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-04-07 03:01:09 +04:00
BOOL cli_unix_hardlink ( struct cli_state * cli , const char * oldname , const char * newname )
2002-01-16 23:13:28 +03:00
{
2004-04-07 03:01:09 +04:00
return cli_link_internal ( cli , oldname , newname , True ) ;
2002-01-16 23:13:28 +03:00
}
/****************************************************************************
Chmod or chown a file internal ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_unix_chmod_chown_internal ( struct cli_state * cli , const char * fname , uint32 mode , uint32 uid , uint32 gid )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
2002-01-16 23:13:28 +03:00
uint16 setup = TRANSACT2_SETPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
char data [ 100 ] ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
memset ( param , 0 , sizeof ( param ) ) ;
memset ( data , 0 , sizeof ( data ) ) ;
SSVAL ( param , 0 , SMB_SET_FILE_UNIX_BASIC ) ;
p = & param [ 6 ] ;
p + = clistr_push ( cli , p , fname , - 1 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
2007-03-01 01:29:14 +03:00
memset ( data , 0xff , 40 ) ; /* Set all sizes/times to no change. */
2002-01-16 23:13:28 +03:00
SIVAL ( data , 40 , uid ) ;
SIVAL ( data , 48 , gid ) ;
SIVAL ( data , 84 , mode ) ;
data_len = 100 ;
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 */
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
/****************************************************************************
chmod a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unix_chmod ( struct cli_state * cli , const char * fname , mode_t mode )
{
return cli_unix_chmod_chown_internal ( cli , fname ,
2002-01-17 02:32:10 +03:00
unix_perms_to_wire ( mode ) , SMB_UID_NO_CHANGE , SMB_GID_NO_CHANGE ) ;
2002-01-16 23:13:28 +03:00
}
/****************************************************************************
chown a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unix_chown ( struct cli_state * cli , const char * fname , uid_t uid , gid_t gid )
{
2002-01-17 02:32:10 +03:00
return cli_unix_chmod_chown_internal ( cli , fname , SMB_MODE_NO_CHANGE , ( uint32 ) uid , ( uint32 ) gid ) ;
2002-01-16 23:13:28 +03:00
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Rename a file .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_rename ( struct cli_state * cli , const char * fname_src , const char * fname_dst )
2000-04-25 18:04:06 +04:00
{
2001-11-04 03:14:08 +03:00
char * p ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2000-04-25 18:04:06 +04:00
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 1 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBmv ) ;
2001-11-04 03:14:08 +03:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
SSVAL ( cli - > outbuf , smb_vwv0 , aSYSTEM | aHIDDEN | aDIR ) ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_src , - 1 , STR_TERMINATE ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_dst , - 1 , STR_TERMINATE ) ;
2001-02-20 15:45:50 +03:00
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
if ( cli_is_error ( cli ) )
return False ;
2000-04-25 18:04:06 +04:00
2001-11-04 03:14:08 +03:00
return True ;
2000-04-25 18:04:06 +04:00
}
2004-03-03 23:55:59 +03:00
/****************************************************************************
NT Rename a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_ntrename ( struct cli_state * cli , const char * fname_src , const char * fname_dst )
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 4 , 0 , True ) ;
2004-03-03 23:55:59 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBntrename ) ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , aSYSTEM | aHIDDEN | aDIR ) ;
SSVAL ( cli - > outbuf , smb_vwv1 , RENAME_FLAG_RENAME ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_src , - 1 , STR_TERMINATE ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_dst , - 1 , STR_TERMINATE ) ;
cli_setup_bcc ( cli , p ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
if ( cli_is_error ( cli ) )
return False ;
return True ;
}
2004-03-04 02:14:23 +03:00
/****************************************************************************
NT hardlink a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_nt_hardlink ( struct cli_state * cli , const char * fname_src , const char * fname_dst )
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 4 , 0 , True ) ;
2004-03-04 02:14:23 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBntrename ) ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , aSYSTEM | aHIDDEN | aDIR ) ;
SSVAL ( cli - > outbuf , smb_vwv1 , RENAME_FLAG_HARD_LINK ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_src , - 1 , STR_TERMINATE ) ;
* p + + = 4 ;
p + = clistr_push ( cli , p , fname_dst , - 1 , STR_TERMINATE ) ;
cli_setup_bcc ( cli , p ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) )
return False ;
if ( cli_is_error ( cli ) )
return False ;
return True ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Delete a file .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2007-03-07 22:45:22 +03:00
BOOL cli_unlink_full ( struct cli_state * cli , const char * fname , uint16 attrs )
2000-04-25 18:04:06 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 1 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBunlink ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2007-03-07 22:45:22 +03:00
SSVAL ( cli - > outbuf , smb_vwv0 , attrs ) ;
2000-04-25 18:04:06 +04:00
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , - 1 , STR_TERMINATE ) ;
2000-04-25 18:04:06 +04:00
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 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
}
2007-03-07 22:45:22 +03:00
/****************************************************************************
Delete a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_unlink ( struct cli_state * cli , const char * fname )
{
return cli_unlink_full ( cli , fname , aSYSTEM | aHIDDEN ) ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Create a directory .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_mkdir ( struct cli_state * cli , const char * dname )
2000-04-25 18:04:06 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 0 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBmkdir ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
2001-08-21 07:50:31 +04:00
p + = clistr_push ( cli , p , dname , - 1 , STR_TERMINATE ) ;
2001-02-20 13:19:02 +03:00
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 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Remove a directory .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_rmdir ( struct cli_state * cli , const char * dname )
2000-04-25 18:04:06 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 0 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBrmdir ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , dname , - 1 , STR_TERMINATE ) ;
2001-02-20 15:30:01 +03:00
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 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
This is a big, rather ugly patch. Whilst investigating the files not truncated
when copying to a full disk problem, I discovered that we were not allowing
the delete on close flag to be set properly, this led to other things, and
after investigation of the proper delete on close semantics and their relationship
to the file_share_delete flag I discovered there were some cases where we
weren't doing the deny modes properly. And this after only 5 years working
on them..... :-) :-).
So here's the latest attempt. I realised the delete on close flag needs to
be set across all smbds with a dev/ino pair open - in addition, the delete
on close flag, allow share delete and delete access requested all need to
be stored in the share mode tdb.
The "delete_on_close" entry in the fsp struct is now redundant and should
really be removed. This may also mean we can get rid of the "iterate_fsp"
calls that I didn't like adding in the first place. Whilst doing this patch,
I also discovered we needed to do the se_map_generic() call for file opens
and POSIX ACL mapping, so I added that also.
This code, although ugly, now passes the deny mode torture tests plus the
delete on close tests I added. I do need to add one more multiple connection
delete on close test to make sure I got the semantics exactly right, plus we
should also (as Andrew suggested) move to random testing here.
The good news is that NT should now correctly delete the file on disk
full error when copying to a disk :-).
Jeremy.
(This used to be commit 51987684bd231c744da2e5f3705fd236d5616173)
2001-03-30 12:57:24 +04:00
}
/****************************************************************************
2001-03-29 06:58:47 +04:00
Set or clear the delete on close flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_nt_delete_on_close ( struct cli_state * cli , int fnum , BOOL flag )
{
2003-03-13 03:51:05 +03:00
unsigned int data_len = 1 ;
unsigned int param_len = 6 ;
2001-03-29 06:58:47 +04:00
uint16 setup = TRANSACT2_SETFILEINFO ;
pstring param ;
unsigned char data ;
char * rparam = NULL , * rdata = NULL ;
memset ( param , 0 , param_len ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_SET_FILE_DISPOSITION_INFO ) ;
data = flag ? 1 : 0 ;
if ( ! cli_send_trans ( cli , SMBtrans2 ,
This is a big, rather ugly patch. Whilst investigating the files not truncated
when copying to a full disk problem, I discovered that we were not allowing
the delete on close flag to be set properly, this led to other things, and
after investigation of the proper delete on close semantics and their relationship
to the file_share_delete flag I discovered there were some cases where we
weren't doing the deny modes properly. And this after only 5 years working
on them..... :-) :-).
So here's the latest attempt. I realised the delete on close flag needs to
be set across all smbds with a dev/ino pair open - in addition, the delete
on close flag, allow share delete and delete access requested all need to
be stored in the share mode tdb.
The "delete_on_close" entry in the fsp struct is now redundant and should
really be removed. This may also mean we can get rid of the "iterate_fsp"
calls that I didn't like adding in the first place. Whilst doing this patch,
I also discovered we needed to do the se_map_generic() call for file opens
and POSIX ACL mapping, so I added that also.
This code, although ugly, now passes the deny mode torture tests plus the
delete on close tests I added. I do need to add one more multiple connection
delete on close test to make sure I got the semantics exactly right, plus we
should also (as Andrew suggested) move to random testing here.
The good news is that NT should now correctly delete the file on disk
full error when copying to a disk :-).
Jeremy.
(This used to be commit 51987684bd231c744da2e5f3705fd236d5616173)
2001-03-30 12:57:24 +04:00
NULL , /* name */
2001-03-29 06:58:47 +04:00
- 1 , 0 , /* fid, flags */
& setup , 1 , 0 , /* setup, length, max */
param , param_len , 2 , /* param, length, max */
2001-05-17 08:09:08 +04:00
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
2001-03-29 06:58:47 +04:00
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
2001-09-17 07:33:37 +04:00
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
2001-03-29 06:58:47 +04:00
return True ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Open a file - exposing the full horror of the NT API : - ) .
2001-03-29 04:58:52 +04:00
Used in smbtorture .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-29 04:58:52 +04:00
2003-04-15 23:51:17 +04:00
int cli_nt_create_full ( struct cli_state * cli , const char * fname ,
uint32 CreatFlags , uint32 DesiredAccess ,
2001-03-29 04:58:52 +04:00
uint32 FileAttributes , uint32 ShareAccess ,
2003-04-15 23:51:17 +04:00
uint32 CreateDisposition , uint32 CreateOptions ,
uint8 SecuityFlags )
2000-04-25 18:04:06 +04:00
{
char * p ;
2001-02-21 02:52:27 +03:00
int len ;
2000-04-25 18:04:06 +04:00
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 24 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBntcreateX ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
2000-11-16 03:59:18 +03:00
if ( cli - > use_oplocks )
2003-04-15 23:51:17 +04:00
CreatFlags | = ( REQUEST_OPLOCK | REQUEST_BATCH_OPLOCK ) ;
SIVAL ( cli - > outbuf , smb_ntcreate_Flags , CreatFlags ) ;
2000-04-25 18:04:06 +04:00
SIVAL ( cli - > outbuf , smb_ntcreate_RootDirectoryFid , 0x0 ) ;
2000-12-04 10:26:56 +03:00
SIVAL ( cli - > outbuf , smb_ntcreate_DesiredAccess , DesiredAccess ) ;
2001-03-29 04:58:52 +04:00
SIVAL ( cli - > outbuf , smb_ntcreate_FileAttributes , FileAttributes ) ;
SIVAL ( cli - > outbuf , smb_ntcreate_ShareAccess , ShareAccess ) ;
SIVAL ( cli - > outbuf , smb_ntcreate_CreateDisposition , CreateDisposition ) ;
SIVAL ( cli - > outbuf , smb_ntcreate_CreateOptions , CreateOptions ) ;
2000-04-25 18:04:06 +04:00
SIVAL ( cli - > outbuf , smb_ntcreate_ImpersonationLevel , 0x02 ) ;
2003-04-15 23:51:17 +04:00
SCVAL ( cli - > outbuf , smb_ntcreate_SecurityFlags , SecuityFlags ) ;
2000-04-25 18:04:06 +04:00
p = smb_buf ( cli - > outbuf ) ;
2001-02-21 02:52:27 +03:00
/* this alignment and termination is critical for netapp filers. Don't change */
2001-07-04 11:15:53 +04:00
p + = clistr_align_out ( cli , p , 0 ) ;
len = clistr_push ( cli , p , fname , - 1 , 0 ) ;
2001-02-21 02:52:27 +03:00
p + = len ;
SSVAL ( cli - > outbuf , smb_ntcreate_NameLength , len ) ;
2001-02-22 06:38:21 +03:00
/* sigh. this copes with broken netapp filer behaviour */
2001-03-10 14:35:25 +03:00
p + = clistr_push ( cli , p , " " , - 1 , STR_TERMINATE ) ;
2001-02-20 15:49:55 +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 - 1 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return - 1 ;
}
return SVAL ( cli - > inbuf , smb_vwv2 + 1 ) ;
}
2001-03-29 04:58:52 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Open a file .
2001-03-29 04:58:52 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 02:34:24 +03:00
int cli_nt_create ( struct cli_state * cli , const char * fname , uint32 DesiredAccess )
2001-03-29 04:58:52 +04:00
{
2003-04-15 23:51:17 +04:00
return cli_nt_create_full ( cli , fname , 0 , DesiredAccess , 0 ,
2005-07-08 08:51:27 +04:00
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 ) ;
2001-03-29 04:58:52 +04:00
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Open a file
WARNING : if you open with O_WRONLY then getattrE won ' t work !
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2001-11-04 02:34:24 +03:00
int cli_open ( struct cli_state * cli , const char * fname , int flags , int share_mode )
2000-04-25 18:04:06 +04:00
{
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_ACCMODE ) = = O_RDWR ) {
accessmode | = 2 ;
} else if ( ( flags & O_ACCMODE ) = = O_WRONLY ) {
accessmode | = 1 ;
}
# if defined(O_SYNC)
if ( ( flags & O_SYNC ) = = O_SYNC ) {
accessmode | = ( 1 < < 14 ) ;
}
# endif /* O_SYNC */
if ( share_mode = = DENY_FCB ) {
accessmode = 0xFF ;
}
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 15 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBopenX ) ;
2000-04-25 18:04:06 +04:00
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 ) ;
SSVAL ( cli - > outbuf , smb_vwv5 , 0 ) ;
SSVAL ( cli - > outbuf , smb_vwv8 , openfn ) ;
if ( cli - > use_oplocks ) {
/* if using oplocks then ask for a batch oplock via
core and extended methods */
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_flg , CVAL ( cli - > outbuf , smb_flg ) |
FLAG_REQUEST_OPLOCK | FLAG_REQUEST_BATCH_OPLOCK ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_vwv2 , SVAL ( cli - > outbuf , smb_vwv2 ) | 6 ) ;
}
p = smb_buf ( cli - > outbuf ) ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , - 1 , STR_TERMINATE ) ;
2001-02-20 15:30:01 +03:00
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 - 1 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return - 1 ;
}
return SVAL ( cli - > inbuf , smb_vwv2 ) ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Close a file .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-04-25 18:04:06 +04:00
BOOL cli_close ( struct cli_state * cli , int fnum )
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 3 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBclose ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , fnum ) ;
SIVALS ( cli - > outbuf , smb_vwv1 , - 1 ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
2001-09-05 15:32:59 +04:00
return ! cli_is_error ( cli ) ;
2000-04-25 18:04:06 +04:00
}
2002-03-11 04:33:06 +03:00
/****************************************************************************
send a lock with a specified locktype
this is used for testing LOCKING_ANDX_CANCEL_LOCK
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-04-10 19:33:04 +04:00
2002-03-11 04:33:06 +03:00
NTSTATUS cli_locktype ( struct cli_state * cli , int fnum ,
uint32 offset , uint32 len , int timeout , unsigned char locktype )
{
char * p ;
int saved_timeout = cli - > timeout ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2002-03-11 04:33:06 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBlockingX ) ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SCVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
SCVAL ( cli - > outbuf , smb_vwv3 , locktype ) ;
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 ) ;
p + = 10 ;
cli_setup_bcc ( cli , p ) ;
cli_send_smb ( cli ) ;
if ( timeout ! = 0 ) {
cli - > timeout = ( timeout = = - 1 ) ? 0x7FFFFFFF : ( timeout + 2 * 1000 ) ;
}
if ( ! cli_receive_smb ( cli ) ) {
cli - > timeout = saved_timeout ;
return NT_STATUS_UNSUCCESSFUL ;
}
cli - > timeout = saved_timeout ;
return cli_nt_error ( cli ) ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Lock a file .
2003-06-10 18:02:46 +04:00
note that timeout is in units of 2 milliseconds
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-04-10 19:33:04 +04:00
2000-04-25 18:04:06 +04:00
BOOL cli_lock ( struct cli_state * cli , int fnum ,
uint32 offset , uint32 len , int timeout , enum brl_type lock_type )
{
char * p ;
2001-11-04 03:14:08 +03:00
int saved_timeout = cli - > timeout ;
2000-04-25 18:04:06 +04:00
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBlockingX ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv3 , ( lock_type = = READ_LOCK ? 1 : 0 ) ) ;
2000-04-25 18:04:06 +04:00
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 ) ;
2001-02-20 16:16:01 +03:00
p + = 10 ;
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
cli_send_smb ( cli ) ;
2002-03-11 02:16:15 +03:00
if ( timeout ! = 0 ) {
2003-06-10 18:02:46 +04:00
cli - > timeout = ( timeout = = - 1 ) ? 0x7FFFFFFF : ( timeout * 2 + 5 * 1000 ) ;
2002-03-11 02:16:15 +03:00
}
2000-04-25 18:04:06 +04:00
if ( ! cli_receive_smb ( cli ) ) {
2001-11-04 03:14:08 +03:00
cli - > timeout = saved_timeout ;
2000-04-25 18:04:06 +04:00
return False ;
}
cli - > timeout = saved_timeout ;
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Unlock a file .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-04-25 18:04:06 +04:00
BOOL cli_unlock ( struct cli_state * cli , int fnum , uint32 offset , uint32 len )
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBlockingX ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv3 , 0 ) ;
2000-04-25 18:04:06 +04:00
SIVALS ( cli - > outbuf , smb_vwv4 , 0 ) ;
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 ) ;
2001-02-20 16:16:01 +03:00
p + = 10 ;
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
}
2000-09-29 08:41:52 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Lock a file with 64 bit offsets .
2000-09-29 08:41:52 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-09-29 08:41:52 +04:00
BOOL cli_lock64 ( struct cli_state * cli , int fnum ,
SMB_BIG_UINT offset , SMB_BIG_UINT len , int timeout , enum brl_type lock_type )
{
char * p ;
int saved_timeout = cli - > timeout ;
int ltype ;
2001-08-24 03:15:18 +04:00
if ( ! ( cli - > capabilities & CAP_LARGE_FILES ) ) {
return cli_lock ( cli , fnum , offset , len , timeout , lock_type ) ;
}
2000-09-29 08:41:52 +04:00
ltype = ( lock_type = = READ_LOCK ? 1 : 0 ) ;
ltype | = LOCKING_ANDX_LARGE_FILES ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2000-09-29 08:41:52 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBlockingX ) ;
2000-09-29 08:41:52 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
2000-09-29 08:41:52 +04:00
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv3 , ltype ) ;
2000-09-29 08:41:52 +04:00
SIVALS ( cli - > outbuf , smb_vwv4 , timeout ) ;
SSVAL ( cli - > outbuf , smb_vwv6 , 0 ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , 1 ) ;
p = smb_buf ( cli - > outbuf ) ;
SIVAL ( p , 0 , cli - > pid ) ;
2001-04-22 06:54:04 +04:00
SOFF_T_R ( p , 4 , offset ) ;
SOFF_T_R ( p , 12 , len ) ;
2001-02-20 16:16:01 +03:00
p + = 20 ;
cli_setup_bcc ( cli , p ) ;
2000-09-29 08:41:52 +04:00
cli_send_smb ( cli ) ;
2002-03-11 02:16:15 +03:00
if ( timeout ! = 0 ) {
cli - > timeout = ( timeout = = - 1 ) ? 0x7FFFFFFF : ( timeout + 5 * 1000 ) ;
}
2000-09-29 08:41:52 +04:00
if ( ! cli_receive_smb ( cli ) ) {
cli - > timeout = saved_timeout ;
return False ;
}
cli - > timeout = saved_timeout ;
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-09-29 08:41:52 +04:00
return False ;
}
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Unlock a file with 64 bit offsets .
2000-09-29 08:41:52 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-09-29 08:41:52 +04:00
BOOL cli_unlock64 ( struct cli_state * cli , int fnum , SMB_BIG_UINT offset , SMB_BIG_UINT len )
{
char * p ;
2001-08-24 03:15:18 +04:00
if ( ! ( cli - > capabilities & CAP_LARGE_FILES ) ) {
return cli_unlock ( cli , fnum , offset , len ) ;
}
2000-09-29 08:41:52 +04:00
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2000-09-29 08:41:52 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBlockingX ) ;
2000-09-29 08:41:52 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv0 , 0xFF ) ;
2000-09-29 08:41:52 +04:00
SSVAL ( cli - > outbuf , smb_vwv2 , fnum ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_vwv3 , LOCKING_ANDX_LARGE_FILES ) ;
2000-09-29 08:41:52 +04:00
SIVALS ( cli - > outbuf , smb_vwv4 , 0 ) ;
SSVAL ( cli - > outbuf , smb_vwv6 , 1 ) ;
SSVAL ( cli - > outbuf , smb_vwv7 , 0 ) ;
p = smb_buf ( cli - > outbuf ) ;
SIVAL ( p , 0 , cli - > pid ) ;
2001-04-22 06:54:04 +04:00
SOFF_T_R ( p , 4 , offset ) ;
SOFF_T_R ( p , 12 , len ) ;
2001-02-20 16:16:01 +03:00
p + = 20 ;
cli_setup_bcc ( cli , p ) ;
2000-09-29 08:41:52 +04:00
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-09-29 08:41:52 +04:00
return False ;
}
return True ;
}
2006-04-10 19:33:04 +04:00
/****************************************************************************
Get / unlock a POSIX lock on a file - internal function .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_posix_lock_internal ( struct cli_state * cli , int fnum ,
SMB_BIG_UINT offset , SMB_BIG_UINT len , BOOL wait_lock , enum brl_type lock_type )
{
unsigned int param_len = 4 ;
unsigned int data_len = POSIX_LOCK_DATA_SIZE ;
uint16 setup = TRANSACT2_SETFILEINFO ;
char param [ 4 ] ;
unsigned char data [ POSIX_LOCK_DATA_SIZE ] ;
char * rparam = NULL , * rdata = NULL ;
int saved_timeout = cli - > timeout ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_SET_POSIX_LOCK ) ;
switch ( lock_type ) {
case READ_LOCK :
SSVAL ( data , POSIX_LOCK_TYPE_OFFSET , POSIX_LOCK_TYPE_READ ) ;
break ;
case WRITE_LOCK :
SSVAL ( data , POSIX_LOCK_TYPE_OFFSET , POSIX_LOCK_TYPE_WRITE ) ;
break ;
case UNLOCK_LOCK :
SSVAL ( data , POSIX_LOCK_TYPE_OFFSET , POSIX_LOCK_TYPE_UNLOCK ) ;
break ;
default :
return False ;
}
if ( wait_lock ) {
SSVAL ( data , POSIX_LOCK_FLAGS_OFFSET , POSIX_LOCK_FLAG_WAIT ) ;
cli - > timeout = 0x7FFFFFFF ;
} else {
SSVAL ( data , POSIX_LOCK_FLAGS_OFFSET , POSIX_LOCK_FLAG_NOWAIT ) ;
}
SIVAL ( data , POSIX_LOCK_PID_OFFSET , cli - > pid ) ;
SOFF_T ( data , POSIX_LOCK_START_OFFSET , offset ) ;
SOFF_T ( data , POSIX_LOCK_LEN_OFFSET , len ) ;
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 */
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
) ) {
cli - > timeout = saved_timeout ;
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
cli - > timeout = saved_timeout ;
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return False ;
}
cli - > timeout = saved_timeout ;
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
/****************************************************************************
POSIX Lock a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_posix_lock ( struct cli_state * cli , int fnum ,
SMB_BIG_UINT offset , SMB_BIG_UINT len ,
BOOL wait_lock , enum brl_type lock_type )
{
2006-04-11 03:32:05 +04:00
if ( lock_type ! = READ_LOCK & & lock_type ! = WRITE_LOCK ) {
2006-04-10 19:33:04 +04:00
return False ;
}
return cli_posix_lock_internal ( cli , fnum , offset , len , wait_lock , lock_type ) ;
}
/****************************************************************************
POSIX Unlock a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_posix_unlock ( struct cli_state * cli , int fnum , SMB_BIG_UINT offset , SMB_BIG_UINT len )
{
return cli_posix_lock_internal ( cli , fnum , offset , len , False , UNLOCK_LOCK ) ;
}
/****************************************************************************
POSIX Get any lock covering a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_posix_getlock ( struct cli_state * cli , int fnum , SMB_BIG_UINT * poffset , SMB_BIG_UINT * plen )
{
return True ;
}
2002-03-11 04:33:06 +03:00
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Do a SMBgetattrE call .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-04-25 18:04:06 +04:00
BOOL cli_getattrE ( struct cli_state * cli , int fd ,
2005-03-23 00:17:01 +03:00
uint16 * attr , SMB_OFF_T * size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
time_t * change_time ,
time_t * access_time ,
time_t * write_time )
2000-04-25 18:04:06 +04:00
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 1 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBgetattrE ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , fd ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
if ( size ) {
* size = IVAL ( cli - > inbuf , smb_vwv6 ) ;
}
if ( attr ) {
* attr = SVAL ( cli - > inbuf , smb_vwv10 ) ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
if ( change_time ) {
* change_time = cli_make_unix_date2 ( cli , cli - > inbuf + smb_vwv0 ) ;
2000-04-25 18:04:06 +04:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
if ( access_time ) {
* access_time = cli_make_unix_date2 ( cli , cli - > inbuf + smb_vwv2 ) ;
2000-04-25 18:04:06 +04:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
if ( write_time ) {
* write_time = cli_make_unix_date2 ( cli , cli - > inbuf + smb_vwv4 ) ;
2000-04-25 18:04:06 +04:00
}
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Do a SMBgetatr call
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_getatr ( struct cli_state * cli , const char * fname ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
uint16 * attr , SMB_OFF_T * size , time_t * write_time )
2000-04-25 18:04:06 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 0 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBgetatr ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
2001-02-20 15:49:55 +03:00
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , - 1 , STR_TERMINATE ) ;
2001-02-20 15:49:55 +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 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
if ( size ) {
* size = IVAL ( cli - > inbuf , smb_vwv3 ) ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
if ( write_time ) {
* write_time = cli_make_unix_date3 ( cli , cli - > inbuf + smb_vwv1 ) ;
2000-04-25 18:04:06 +04:00
}
if ( attr ) {
* attr = SVAL ( cli - > inbuf , smb_vwv0 ) ;
}
return True ;
}
2004-08-21 00:07:17 +04:00
/****************************************************************************
Do a SMBsetattrE call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_setattrE ( struct cli_state * cli , int fd ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
time_t change_time ,
time_t access_time ,
time_t write_time )
2004-08-21 00:07:17 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 7 , 0 , True ) ;
2004-08-21 00:07:17 +04:00
SCVAL ( cli - > outbuf , smb_com , SMBsetattrE ) ;
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , fd ) ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-03 01:47:56 +04:00
cli_put_dos_date2 ( cli , cli - > outbuf , smb_vwv1 , change_time ) ;
cli_put_dos_date2 ( cli , cli - > outbuf , smb_vwv3 , access_time ) ;
cli_put_dos_date2 ( cli , cli - > outbuf , smb_vwv5 , write_time ) ;
2004-08-21 00:07:17 +04:00
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
cli_setup_bcc ( cli , p ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
if ( cli_is_error ( cli ) ) {
return False ;
}
return True ;
}
2000-04-25 18:04:06 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Do a SMBsetatr call .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_setatr ( struct cli_state * cli , const char * fname , uint16 attr , time_t t )
2000-04-25 18:04:06 +04:00
{
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 8 , 0 , True ) ;
2000-04-25 18:04:06 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBsetatr ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , attr ) ;
2005-11-05 07:21:55 +03:00
cli_put_dos_date3 ( cli , cli - > outbuf , smb_vwv1 , t ) ;
2000-04-25 18:04:06 +04:00
p = smb_buf ( cli - > outbuf ) ;
2001-02-20 16:16:01 +03:00
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , fname , - 1 , STR_TERMINATE ) ;
2001-02-20 16:16:01 +03:00
* p + + = 4 ;
cli_setup_bcc ( cli , p ) ;
2000-04-25 18:04:06 +04:00
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2000-04-25 18:04:06 +04:00
return False ;
}
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Check for existance of a dir .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
BOOL cli_chkpath ( struct cli_state * cli , const char * path )
2000-04-25 18:04:06 +04:00
{
pstring path2 ;
char * p ;
2003-03-18 14:22:52 +03:00
pstrcpy ( path2 , path ) ;
2003-09-05 23:59:55 +04:00
trim_char ( path2 , ' \0 ' , ' \\ ' ) ;
if ( ! * path2 )
* path2 = ' \\ ' ;
2000-04-25 18:04:06 +04:00
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 0 , 0 , True ) ;
2007-01-14 01:26:46 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBcheckpath ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , path2 , - 1 , STR_TERMINATE ) ;
2001-02-20 15:25:42 +03:00
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 ;
}
2001-08-10 10:00:33 +04:00
if ( cli_is_error ( cli ) ) return False ;
2000-04-25 18:04:06 +04:00
return True ;
}
/****************************************************************************
2001-11-04 03:14:08 +03:00
Query disk space .
2000-04-25 18:04:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
2000-04-25 18:04:06 +04:00
BOOL cli_dskattr ( struct cli_state * cli , int * bsize , int * total , int * avail )
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 0 , 0 , True ) ;
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBdskattr ) ;
2000-04-25 18:04:06 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return False ;
}
* bsize = SVAL ( cli - > inbuf , smb_vwv1 ) * SVAL ( cli - > inbuf , smb_vwv2 ) ;
* total = SVAL ( cli - > inbuf , smb_vwv0 ) ;
* avail = SVAL ( cli - > inbuf , smb_vwv3 ) ;
return True ;
}
2001-04-22 06:54:04 +04:00
/****************************************************************************
2001-11-04 03:14:08 +03:00
Create and open a temporary file .
2001-04-22 06:54:04 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 03:14:08 +03:00
int cli_ctemp ( struct cli_state * cli , const char * path , char * * tmp_path )
2001-04-22 06:54:04 +04:00
{
2001-09-17 08:23:48 +04:00
int len ;
2001-04-22 06:54:04 +04:00
char * p ;
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 3 , 0 , True ) ;
2001-04-22 06:54:04 +04:00
2002-01-11 22:10:25 +03:00
SCVAL ( cli - > outbuf , smb_com , SMBctemp ) ;
2001-04-22 06:54:04 +04:00
SSVAL ( cli - > outbuf , smb_tid , cli - > cnum ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , 0 ) ;
2001-09-17 08:23:48 +04:00
SIVALS ( cli - > outbuf , smb_vwv1 , - 1 ) ;
2001-04-22 06:54:04 +04:00
p = smb_buf ( cli - > outbuf ) ;
* p + + = 4 ;
2001-07-04 11:15:53 +04:00
p + = clistr_push ( cli , p , path , - 1 , STR_TERMINATE ) ;
2001-04-22 06:54:04 +04:00
2001-06-21 09:38:28 +04:00
cli_setup_bcc ( cli , p ) ;
2001-04-22 06:54:04 +04:00
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return - 1 ;
}
2001-09-05 15:32:59 +04:00
if ( cli_is_error ( cli ) ) {
2001-04-22 06:54:04 +04:00
return - 1 ;
}
2001-09-17 08:23:48 +04:00
/* despite the spec, the result has a -1, followed by
length , followed by name */
p = smb_buf ( cli - > inbuf ) ;
p + = 4 ;
len = smb_buflen ( cli - > inbuf ) - 4 ;
if ( len < = 0 ) return - 1 ;
2001-04-22 06:54:04 +04:00
if ( tmp_path ) {
pstring path2 ;
2001-09-17 08:23:48 +04:00
clistr_pull ( cli , path2 , p ,
sizeof ( path2 ) , len , STR_ASCII ) ;
2004-12-07 21:25:53 +03:00
* tmp_path = SMB_STRDUP ( path2 ) ;
2001-04-22 06:54:04 +04:00
}
return SVAL ( cli - > inbuf , smb_vwv0 ) ;
}
2003-04-23 12:12:34 +04:00
/*
send a raw ioctl - used by the torture code
*/
NTSTATUS cli_raw_ioctl ( struct cli_state * cli , int fnum , uint32 code , DATA_BLOB * blob )
{
memset ( cli - > outbuf , ' \0 ' , smb_size ) ;
memset ( cli - > inbuf , ' \0 ' , smb_size ) ;
2007-04-20 02:40:32 +04:00
set_message ( NULL , cli - > outbuf , 3 , 0 , True ) ;
2003-04-23 12:12:34 +04:00
SCVAL ( cli - > outbuf , smb_com , SMBioctl ) ;
cli_setup_packet ( cli ) ;
SSVAL ( cli - > outbuf , smb_vwv0 , fnum ) ;
SSVAL ( cli - > outbuf , smb_vwv1 , code > > 16 ) ;
SSVAL ( cli - > outbuf , smb_vwv2 , ( code & 0xFFFF ) ) ;
cli_send_smb ( cli ) ;
if ( ! cli_receive_smb ( cli ) ) {
return NT_STATUS_UNEXPECTED_NETWORK_ERROR ;
}
if ( cli_is_error ( cli ) ) {
return cli_nt_error ( cli ) ;
}
2007-05-14 16:16:20 +04:00
* blob = data_blob_null ;
2003-04-23 12:12:34 +04:00
return NT_STATUS_OK ;
}
2004-03-24 06:48:08 +03:00
/*********************************************************
2004-03-30 02:21:47 +04:00
Set an extended attribute utility fn .
2004-03-24 06:48:08 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-30 02:21:47 +04:00
static BOOL cli_set_ea ( struct cli_state * cli , uint16 setup , char * param , unsigned int param_len ,
const char * ea_name , const char * ea_val , size_t ea_len )
{
2004-03-24 06:48:08 +03:00
unsigned int data_len = 0 ;
char * data = NULL ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
size_t ea_namelen = strlen ( ea_name ) ;
2005-10-31 23:11:58 +03:00
if ( ea_namelen = = 0 & & ea_len = = 0 ) {
data_len = 4 ;
2006-07-31 07:53:39 +04:00
data = ( char * ) SMB_MALLOC ( data_len ) ;
2005-10-31 23:11:58 +03:00
if ( ! data ) {
return False ;
}
p = data ;
SIVAL ( p , 0 , data_len ) ;
} else {
data_len = 4 + 4 + ea_namelen + 1 + ea_len ;
2006-07-31 07:53:39 +04:00
data = ( char * ) SMB_MALLOC ( data_len ) ;
2005-10-31 23:11:58 +03:00
if ( ! data ) {
return False ;
}
p = data ;
SIVAL ( p , 0 , data_len ) ;
p + = 4 ;
SCVAL ( p , 0 , 0 ) ; /* EA flags. */
SCVAL ( p , 1 , ea_namelen ) ;
SSVAL ( p , 2 , ea_len ) ;
memcpy ( p + 4 , ea_name , ea_namelen + 1 ) ; /* Copy in the name. */
memcpy ( p + 4 + ea_namelen + 1 , ea_val , ea_len ) ;
2004-03-24 06:48:08 +03:00
}
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 */
2004-03-27 05:13:58 +03:00
data , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
SAFE_FREE ( data ) ;
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
/*********************************************************
2004-03-30 02:21:47 +04:00
Set an extended attribute on a pathname .
2004-03-27 05:13:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-30 02:21:47 +04:00
BOOL cli_set_ea_path ( struct cli_state * cli , const char * path , const char * ea_name , const char * ea_val , size_t ea_len )
2004-03-27 05:13:58 +03:00
{
2004-03-30 02:21:47 +04:00
uint16 setup = TRANSACT2_SETPATHINFO ;
unsigned int param_len = 0 ;
char param [ sizeof ( pstring ) + 6 ] ;
size_t srclen = 2 * ( strlen ( path ) + 1 ) ;
2004-03-27 05:13:58 +03:00
char * p ;
memset ( param , 0 , sizeof ( param ) ) ;
2004-03-30 02:21:47 +04:00
SSVAL ( param , 0 , SMB_INFO_SET_EA ) ;
p = & param [ 6 ] ;
2004-03-27 05:13:58 +03:00
2004-03-30 02:21:47 +04:00
p + = clistr_push ( cli , p , path , MIN ( srclen , sizeof ( param ) - 6 ) , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
2004-03-27 05:13:58 +03:00
2004-03-30 02:21:47 +04:00
return cli_set_ea ( cli , setup , param , param_len , ea_name , ea_val , ea_len ) ;
}
2004-03-24 06:48:08 +03:00
2004-03-30 02:21:47 +04:00
/*********************************************************
Set an extended attribute on an fnum .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-24 06:48:08 +03:00
2004-03-30 02:21:47 +04:00
BOOL cli_set_ea_fnum ( struct cli_state * cli , int fnum , const char * ea_name , const char * ea_val , size_t ea_len )
{
char param [ 6 ] ;
uint16 setup = TRANSACT2_SETFILEINFO ;
2004-03-24 06:48:08 +03:00
2004-03-30 02:21:47 +04:00
memset ( param , 0 , 6 ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_INFO_SET_EA ) ;
return cli_set_ea ( cli , setup , param , 6 , ea_name , ea_val , ea_len ) ;
2004-03-24 06:48:08 +03:00
}
2004-03-30 02:21:47 +04:00
/*********************************************************
Get an extended attribute list tility fn .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_get_ea_list ( struct cli_state * cli ,
uint16 setup , char * param , unsigned int param_len ,
2004-03-27 05:13:58 +03:00
TALLOC_CTX * ctx ,
size_t * pnum_eas ,
2004-03-30 02:21:47 +04:00
struct ea_struct * * pea_list )
2004-03-24 06:48:08 +03:00
{
2004-03-27 05:13:58 +03:00
unsigned int data_len = 0 ;
unsigned int rparam_len , rdata_len ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
2004-03-30 02:21:47 +04:00
size_t ea_size ;
size_t num_eas ;
BOOL ret = False ;
struct ea_struct * ea_list ;
* pnum_eas = 0 ;
2006-08-29 05:11:02 +04:00
if ( pea_list ) {
* pea_list = NULL ;
}
2004-03-30 02:21:47 +04:00
2004-03-27 05:13:58 +03:00
if ( ! 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 */
) ) {
return False ;
}
2004-03-30 02:21:47 +04:00
2004-03-27 05:13:58 +03:00
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & rparam_len ,
& rdata , & rdata_len ) ) {
return False ;
}
2004-03-30 02:21:47 +04:00
2004-03-27 05:13:58 +03:00
if ( ! rdata | | rdata_len < 4 ) {
2004-03-30 02:21:47 +04:00
goto out ;
2004-03-27 05:13:58 +03:00
}
2004-03-30 02:21:47 +04:00
ea_size = ( size_t ) IVAL ( rdata , 0 ) ;
if ( ea_size > rdata_len ) {
goto out ;
}
2004-03-30 22:38:21 +04:00
if ( ea_size = = 0 ) {
/* No EA's present. */
ret = True ;
goto out ;
}
2004-03-30 02:21:47 +04:00
p = rdata + 4 ;
ea_size - = 4 ;
/* Validate the EA list and count it. */
for ( num_eas = 0 ; ea_size > = 4 ; num_eas + + ) {
unsigned int ea_namelen = CVAL ( p , 1 ) ;
unsigned int ea_valuelen = SVAL ( p , 2 ) ;
if ( ea_namelen = = 0 ) {
goto out ;
}
if ( 4 + ea_namelen + 1 + ea_valuelen > ea_size ) {
goto out ;
}
ea_size - = 4 + ea_namelen + 1 + ea_valuelen ;
p + = 4 + ea_namelen + 1 + ea_valuelen ;
}
if ( num_eas = = 0 ) {
ret = True ;
goto out ;
}
* pnum_eas = num_eas ;
if ( ! pea_list ) {
/* Caller only wants number of EA's. */
ret = True ;
goto out ;
}
2007-06-05 03:31:34 +04:00
ea_list = TALLOC_ARRAY ( ctx , struct ea_struct , num_eas ) ;
if ( ! ea_list ) {
goto out ;
2004-03-30 02:21:47 +04:00
}
ea_size = ( size_t ) IVAL ( rdata , 0 ) ;
p = rdata + 4 ;
for ( num_eas = 0 ; num_eas < * pnum_eas ; num_eas + + ) {
struct ea_struct * ea = & ea_list [ num_eas ] ;
fstring unix_ea_name ;
unsigned int ea_namelen = CVAL ( p , 1 ) ;
unsigned int ea_valuelen = SVAL ( p , 2 ) ;
ea - > flags = CVAL ( p , 0 ) ;
unix_ea_name [ 0 ] = ' \0 ' ;
pull_ascii_fstring ( unix_ea_name , p + 4 ) ;
ea - > name = talloc_strdup ( ctx , unix_ea_name ) ;
/* Ensure the value is null terminated (in case it's a string). */
ea - > value = data_blob_talloc ( ctx , NULL , ea_valuelen + 1 ) ;
if ( ! ea - > value . data ) {
goto out ;
}
if ( ea_valuelen ) {
memcpy ( ea - > value . data , p + 4 + ea_namelen + 1 , ea_valuelen ) ;
}
ea - > value . data [ ea_valuelen ] = 0 ;
ea - > value . length - - ;
p + = 4 + ea_namelen + 1 + ea_valuelen ;
}
* pea_list = ea_list ;
ret = True ;
out :
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return ret ;
}
/*********************************************************
Get an extended attribute list from a pathname .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_get_ea_list_path ( struct cli_state * cli , const char * path ,
TALLOC_CTX * ctx ,
size_t * pnum_eas ,
struct ea_struct * * pea_list )
{
uint16 setup = TRANSACT2_QPATHINFO ;
unsigned int param_len = 0 ;
char param [ sizeof ( pstring ) + 6 ] ;
char * p ;
p = param ;
memset ( p , 0 , 6 ) ;
SSVAL ( p , 0 , SMB_INFO_QUERY_ALL_EAS ) ;
p + = 6 ;
p + = clistr_push ( cli , p , path , sizeof ( pstring ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
return cli_get_ea_list ( cli , setup , param , param_len , ctx , pnum_eas , pea_list ) ;
}
/*********************************************************
Get an extended attribute list from an fnum .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_get_ea_list_fnum ( struct cli_state * cli , int fnum ,
TALLOC_CTX * ctx ,
size_t * pnum_eas ,
struct ea_struct * * pea_list )
{
uint16 setup = TRANSACT2_QFILEINFO ;
char param [ 6 ] ;
memset ( param , 0 , 6 ) ;
SSVAL ( param , 0 , fnum ) ;
SSVAL ( param , 2 , SMB_INFO_SET_EA ) ;
return cli_get_ea_list ( cli , setup , param , 6 , ctx , pnum_eas , pea_list ) ;
2004-03-24 06:48:08 +03:00
}
2007-03-02 00:05:29 +03:00
/****************************************************************************
Convert open " flags " arg to uint32 on wire .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 open_flags_to_wire ( int flags )
{
int open_mode = flags & O_ACCMODE ;
uint32 ret = 0 ;
switch ( open_mode ) {
case O_WRONLY :
ret | = SMB_O_WRONLY ;
break ;
case O_RDWR :
ret | = SMB_O_RDWR ;
break ;
default :
2007-03-02 01:15:30 +03:00
case O_RDONLY :
2007-03-02 00:05:29 +03:00
ret | = SMB_O_RDONLY ;
break ;
}
if ( flags & O_CREAT ) {
ret | = SMB_O_CREAT ;
}
if ( flags & O_EXCL ) {
ret | = SMB_O_EXCL ;
}
if ( flags & O_TRUNC ) {
ret | = SMB_O_TRUNC ;
}
2007-03-05 20:02:20 +03:00
# if defined(O_SYNC)
2007-03-02 00:05:29 +03:00
if ( flags & O_SYNC ) {
ret | = SMB_O_SYNC ;
}
2007-03-05 20:02:20 +03:00
# endif /* O_SYNC */
2007-03-02 00:05:29 +03:00
if ( flags & O_APPEND ) {
ret | = SMB_O_APPEND ;
}
2007-03-02 00:36:05 +03:00
# if defined(O_DIRECT)
2007-03-02 00:05:29 +03:00
if ( flags & O_DIRECT ) {
ret | = SMB_O_DIRECT ;
}
2007-03-02 00:36:05 +03:00
# endif
# if defined(O_DIRECTORY)
2007-03-02 00:05:29 +03:00
if ( flags & O_DIRECTORY ) {
2007-03-02 01:15:30 +03:00
ret & = ~ ( SMB_O_RDONLY | SMB_O_RDWR | SMB_O_WRONLY ) ;
2007-03-02 00:05:29 +03:00
ret | = SMB_O_DIRECTORY ;
}
2007-03-02 00:36:05 +03:00
# endif
2007-03-02 00:05:29 +03:00
return ret ;
}
/****************************************************************************
Open a file - POSIX semantics . Returns fnum . Doesn ' t request oplock .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-03-02 01:44:02 +03:00
static int cli_posix_open_internal ( struct cli_state * cli , const char * fname , int flags , mode_t mode , BOOL is_dir )
2007-03-02 00:05:29 +03:00
{
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
uint16 setup = TRANSACT2_SETPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
2007-03-09 21:33:16 +03:00
char data [ 18 ] ;
2007-03-02 00:05:29 +03:00
char * rparam = NULL , * rdata = NULL ;
char * p ;
int fnum = - 1 ;
2007-03-02 01:44:02 +03:00
uint32 wire_flags = open_flags_to_wire ( flags ) ;
2007-03-02 00:05:29 +03:00
memset ( param , 0 , sizeof ( param ) ) ;
SSVAL ( param , 0 , SMB_POSIX_PATH_OPEN ) ;
p = & param [ 6 ] ;
p + = clistr_push ( cli , p , fname , sizeof ( param ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
2007-03-02 01:44:02 +03:00
if ( is_dir ) {
wire_flags & = ~ ( SMB_O_RDONLY | SMB_O_RDWR | SMB_O_WRONLY ) ;
wire_flags | = SMB_O_DIRECTORY ;
}
2007-03-02 00:05:29 +03:00
p = data ;
SIVAL ( p , 0 , 0 ) ; /* No oplock. */
2007-03-02 01:44:02 +03:00
SIVAL ( p , 4 , wire_flags ) ;
2007-03-02 00:05:29 +03:00
SIVAL ( p , 8 , unix_perms_to_wire ( mode ) ) ;
2007-03-09 21:33:16 +03:00
SIVAL ( p , 12 , 0 ) ; /* Top bits of perms currently undefined. */
SSVAL ( p , 16 , SMB_NO_INFO_LEVEL_RETURNED ) ; /* No info level returned. */
2007-03-02 00:05:29 +03:00
2007-03-09 21:33:16 +03:00
data_len = 18 ;
2007-03-02 00:05:29 +03:00
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 */
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
) ) {
return - 1 ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return - 1 ;
}
fnum = SVAL ( rdata , 2 ) ;
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return fnum ;
}
2007-03-02 01:44:02 +03:00
/****************************************************************************
open - POSIX semantics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_posix_open ( struct cli_state * cli , const char * fname , int flags , mode_t mode )
{
return cli_posix_open_internal ( cli , fname , flags , mode , False ) ;
}
2007-03-02 00:05:29 +03:00
/****************************************************************************
mkdir - POSIX semantics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_posix_mkdir ( struct cli_state * cli , const char * fname , mode_t mode )
{
2007-03-02 01:44:02 +03:00
return ( cli_posix_open_internal ( cli , fname , O_CREAT , mode , True ) = = - 1 ) ? - 1 : 0 ;
2007-03-02 00:05:29 +03:00
}
/****************************************************************************
unlink or rmdir - POSIX semantics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL cli_posix_unlink_internal ( struct cli_state * cli , const char * fname , BOOL is_dir )
{
unsigned int data_len = 0 ;
unsigned int param_len = 0 ;
uint16 setup = TRANSACT2_SETPATHINFO ;
char param [ sizeof ( pstring ) + 6 ] ;
char data [ 2 ] ;
char * rparam = NULL , * rdata = NULL ;
char * p ;
memset ( param , 0 , sizeof ( param ) ) ;
SSVAL ( param , 0 , SMB_POSIX_PATH_UNLINK ) ;
p = & param [ 6 ] ;
p + = clistr_push ( cli , p , fname , sizeof ( param ) - 6 , STR_TERMINATE ) ;
param_len = PTR_DIFF ( p , param ) ;
SSVAL ( data , 0 , is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET :
SMB_POSIX_UNLINK_FILE_TARGET ) ;
data_len = 2 ;
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 */
( char * ) & data , data_len , cli - > max_xmit /* data, length, max */
) ) {
return False ;
}
if ( ! cli_receive_trans ( cli , SMBtrans2 ,
& rparam , & param_len ,
& rdata , & data_len ) ) {
return False ;
}
SAFE_FREE ( rdata ) ;
SAFE_FREE ( rparam ) ;
return True ;
}
/****************************************************************************
unlink - POSIX semantics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cli_posix_unlink ( struct cli_state * cli , const char * fname )
{
return cli_posix_unlink_internal ( cli , fname , False ) ;
}
/****************************************************************************
rmdir - POSIX semantics .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cli_posix_rmdir ( struct cli_state * cli , const char * fname )
{
return cli_posix_unlink_internal ( cli , fname , True ) ;
}