2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
client file operations
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Jeremy Allison 2001 - 2002
Copyright ( C ) James Myers 2003
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 .
*/
# include "includes.h"
/****************************************************************************
Hard / Symlink a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
static NTSTATUS cli_link_internal ( struct cli_tree * tree ,
const char * fname_src ,
const char * fname_dst , BOOL hard_link )
2003-08-13 05:53:07 +04:00
{
union smb_setfileinfo parms ;
NTSTATUS status ;
if ( hard_link ) {
2003-08-15 22:33:43 +04:00
parms . generic . level = RAW_SFILEINFO_UNIX_HLINK ;
2003-08-13 05:53:07 +04:00
parms . unix_hlink . file . fname = fname_src ;
parms . unix_hlink . in . link_dest = fname_dst ;
} else {
2003-08-15 22:33:43 +04:00
parms . generic . level = RAW_SFILEINFO_UNIX_LINK ;
2003-08-13 05:53:07 +04:00
parms . unix_link . file . fname = fname_src ;
parms . unix_link . in . link_dest = fname_dst ;
}
2004-02-08 03:51:07 +03:00
status = smb_raw_setpathinfo ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Map standard UNIX permissions onto wire representations .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-05-25 20:24:13 +04:00
static uint32_t unix_perms_to_wire ( mode_t perms )
2003-08-13 05:53:07 +04:00
{
unsigned int ret = 0 ;
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
ret | = ( ( perms & S_ISUID ) ? UNIX_SET_UID : 0 ) ;
# endif
return ret ;
}
/****************************************************************************
Symlink a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unix_symlink ( struct cli_tree * tree , const char * fname_src ,
const char * fname_dst )
2003-08-13 05:53:07 +04:00
{
2004-02-08 03:51:07 +03:00
return cli_link_internal ( tree , fname_src , fname_dst , False ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Hard a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unix_hardlink ( struct cli_tree * tree , const char * fname_src ,
const char * fname_dst )
2003-08-13 05:53:07 +04:00
{
2004-02-08 03:51:07 +03:00
return cli_link_internal ( tree , fname_src , fname_dst , True ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Chmod or chown a file internal ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
static NTSTATUS cli_unix_chmod_chown_internal ( struct cli_tree * tree ,
const char * fname ,
2004-05-25 20:24:13 +04:00
uint32_t mode , uint32_t uid ,
uint32_t gid )
2003-08-13 05:53:07 +04:00
{
union smb_setfileinfo parms ;
NTSTATUS status ;
parms . generic . level = SMB_SFILEINFO_UNIX_BASIC ;
parms . unix_basic . file . fname = fname ;
parms . unix_basic . in . uid = uid ;
parms . unix_basic . in . gid = gid ;
parms . unix_basic . in . mode = mode ;
2004-02-08 03:51:07 +03:00
status = smb_raw_setpathinfo ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
chmod a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unix_chmod ( struct cli_tree * tree , const char * fname , mode_t mode )
2003-08-13 05:53:07 +04:00
{
2004-02-08 03:51:07 +03:00
return cli_unix_chmod_chown_internal ( tree , fname ,
unix_perms_to_wire ( mode ) ,
SMB_UID_NO_CHANGE ,
SMB_GID_NO_CHANGE ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
chown a file ( UNIX extensions ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unix_chown ( struct cli_tree * tree , const char * fname , uid_t uid ,
gid_t gid )
2003-08-13 05:53:07 +04:00
{
2004-02-08 03:51:07 +03:00
return cli_unix_chmod_chown_internal ( tree , fname , SMB_MODE_NO_CHANGE ,
2004-05-25 20:24:13 +04:00
( uint32_t ) uid , ( uint32_t ) gid ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Rename a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_rename ( struct cli_tree * tree , const char * fname_src ,
const char * fname_dst )
2003-08-13 05:53:07 +04:00
{
2003-08-13 20:04:21 +04:00
union smb_rename parms ;
2003-08-13 05:53:07 +04:00
2003-08-13 20:04:21 +04:00
parms . generic . level = RAW_RENAME_RENAME ;
parms . rename . in . attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY ;
parms . rename . in . pattern1 = fname_src ;
parms . rename . in . pattern2 = fname_dst ;
2004-02-10 14:33:35 +03:00
return smb_raw_rename ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Delete a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unlink ( struct cli_tree * tree , const char * fname )
2003-08-13 05:53:07 +04:00
{
struct smb_unlink parms ;
parms . in . pattern = fname ;
if ( strchr ( fname , ' * ' ) ) {
parms . in . attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
} else {
parms . in . attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY ;
}
2004-02-10 14:33:35 +03:00
return smb_raw_unlink ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Create a directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_mkdir ( struct cli_tree * tree , const char * dname )
2003-08-13 05:53:07 +04:00
{
union smb_mkdir parms ;
parms . mkdir . level = RAW_MKDIR_MKDIR ;
parms . mkdir . in . path = dname ;
2004-02-10 14:33:35 +03:00
return smb_raw_mkdir ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Remove a directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_rmdir ( struct cli_tree * tree , const char * dname )
2003-08-13 05:53:07 +04:00
{
struct smb_rmdir parms ;
parms . in . path = dname ;
2004-02-10 14:33:35 +03:00
return smb_raw_rmdir ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Set or clear the delete on close flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_nt_delete_on_close ( struct cli_tree * tree , int fnum , BOOL flag )
2003-08-13 05:53:07 +04:00
{
union smb_setfileinfo parms ;
NTSTATUS status ;
parms . disposition_info . level = RAW_SFILEINFO_DISPOSITION_INFO ;
parms . disposition_info . file . fnum = fnum ;
parms . disposition_info . in . delete_on_close = flag ;
2004-02-08 03:51:07 +03:00
status = smb_raw_setfileinfo ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Create / open a file - exposing the full horror of the NT API : - ) .
Used in CIFS - on - CIFS NTVFS .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-08 03:51:07 +03:00
int cli_nt_create_full ( struct cli_tree * tree , const char * fname ,
2004-05-25 20:24:13 +04:00
uint32_t CreatFlags , uint32_t DesiredAccess ,
uint32_t FileAttributes , uint32_t ShareAccess ,
uint32_t CreateDisposition , uint32_t CreateOptions ,
2004-02-08 03:51:07 +03:00
uint8 SecurityFlags )
2003-08-13 05:53:07 +04:00
{
union smb_open open_parms ;
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
mem_ctx = talloc_init ( " raw_open " ) ;
if ( ! mem_ctx ) return - 1 ;
open_parms . ntcreatex . level = RAW_OPEN_NTCREATEX ;
open_parms . ntcreatex . in . flags = CreatFlags ;
open_parms . ntcreatex . in . root_fid = 0 ;
open_parms . ntcreatex . in . access_mask = DesiredAccess ;
open_parms . ntcreatex . in . file_attr = FileAttributes ;
open_parms . ntcreatex . in . alloc_size = 0 ;
open_parms . ntcreatex . in . share_access = ShareAccess ;
open_parms . ntcreatex . in . open_disposition = CreateDisposition ;
open_parms . ntcreatex . in . create_options = CreateOptions ;
open_parms . ntcreatex . in . impersonation = 0 ;
open_parms . ntcreatex . in . security_flags = SecurityFlags ;
open_parms . ntcreatex . in . fname = fname ;
2004-02-08 03:51:07 +03:00
status = smb_raw_open ( tree , mem_ctx , & open_parms ) ;
2003-08-13 05:53:07 +04:00
talloc_destroy ( mem_ctx ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return open_parms . ntcreatex . out . fnum ;
}
return - 1 ;
}
/****************************************************************************
Open a file ( using SMBopenx )
WARNING : if you open with O_WRONLY then getattrE won ' t work !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-08 03:51:07 +03:00
int cli_open ( struct cli_tree * tree , const char * fname , int flags ,
int share_mode )
2003-08-13 05:53:07 +04:00
{
union smb_open open_parms ;
unsigned openfn = 0 ;
unsigned accessmode = 0 ;
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
mem_ctx = talloc_init ( " raw_open " ) ;
if ( ! mem_ctx ) return - 1 ;
if ( flags & O_CREAT ) {
openfn | = OPENX_OPEN_FUNC_CREATE ;
}
if ( ! ( flags & O_EXCL ) ) {
if ( flags & O_TRUNC ) {
openfn | = OPENX_OPEN_FUNC_TRUNC ;
} else {
openfn | = OPENX_OPEN_FUNC_OPEN ;
}
}
accessmode = ( share_mode < < OPENX_MODE_DENY_SHIFT ) ;
if ( ( flags & O_ACCMODE ) = = O_RDWR ) {
accessmode | = OPENX_MODE_ACCESS_RDWR ;
} else if ( ( flags & O_ACCMODE ) = = O_WRONLY ) {
accessmode | = OPENX_MODE_ACCESS_WRITE ;
}
# if defined(O_SYNC)
if ( ( flags & O_SYNC ) = = O_SYNC ) {
accessmode | = OPENX_MODE_WRITE_THRU ;
}
# endif
if ( share_mode = = DENY_FCB ) {
accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB ;
}
open_parms . openx . level = RAW_OPEN_OPENX ;
open_parms . openx . in . flags = 0 ;
open_parms . openx . in . open_mode = accessmode ;
open_parms . openx . in . search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
open_parms . openx . in . file_attrs = 0 ;
open_parms . openx . in . write_time = 0 ;
open_parms . openx . in . open_func = openfn ;
open_parms . openx . in . size = 0 ;
open_parms . openx . in . timeout = 0 ;
open_parms . openx . in . fname = fname ;
2004-02-08 03:51:07 +03:00
status = smb_raw_open ( tree , mem_ctx , & open_parms ) ;
2003-08-13 05:53:07 +04:00
talloc_destroy ( mem_ctx ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return open_parms . openx . out . fnum ;
}
return - 1 ;
}
/****************************************************************************
Close a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_close ( struct cli_tree * tree , int fnum )
2003-08-13 05:53:07 +04:00
{
union smb_close close_parms ;
NTSTATUS status ;
close_parms . close . level = RAW_CLOSE_CLOSE ;
close_parms . close . in . fnum = fnum ;
close_parms . close . in . write_time = 0 ;
2004-02-08 03:51:07 +03:00
status = smb_raw_close ( tree , & close_parms ) ;
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
send a lock with a specified locktype
this is used for testing LOCKING_ANDX_CANCEL_LOCK
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-08 03:51:07 +03:00
NTSTATUS cli_locktype ( struct cli_tree * tree , int fnum ,
2004-05-25 20:24:13 +04:00
uint32_t offset , uint32_t len , int timeout ,
2004-02-10 14:33:35 +03:00
unsigned char locktype )
2003-08-13 05:53:07 +04:00
{
union smb_lock parms ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
parms . lockx . level = RAW_LOCK_LOCKX ;
parms . lockx . in . fnum = fnum ;
parms . lockx . in . mode = locktype ;
parms . lockx . in . timeout = timeout ;
parms . lockx . in . ulock_cnt = 0 ;
parms . lockx . in . lock_cnt = 1 ;
2004-02-08 03:51:07 +03:00
lock [ 0 ] . pid = tree - > session - > pid ;
2003-08-13 05:53:07 +04:00
lock [ 0 ] . offset = offset ;
lock [ 0 ] . count = len ;
parms . lockx . in . locks = & lock [ 0 ] ;
2004-02-08 03:51:07 +03:00
status = smb_raw_lock ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
return status ;
}
/****************************************************************************
Lock a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_lock ( struct cli_tree * tree , int fnum ,
2004-05-25 20:24:13 +04:00
uint32_t offset , uint32_t len , int timeout ,
2004-02-10 14:33:35 +03:00
enum brl_type lock_type )
2003-08-13 05:53:07 +04:00
{
union smb_lock parms ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
parms . lockx . level = RAW_LOCK_LOCKX ;
parms . lockx . in . fnum = fnum ;
parms . lockx . in . mode = ( lock_type = = READ_LOCK ? 1 : 0 ) ;
parms . lockx . in . timeout = timeout ;
parms . lockx . in . ulock_cnt = 0 ;
parms . lockx . in . lock_cnt = 1 ;
2004-02-08 03:51:07 +03:00
lock [ 0 ] . pid = tree - > session - > pid ;
2003-08-13 05:53:07 +04:00
lock [ 0 ] . offset = offset ;
lock [ 0 ] . count = len ;
parms . lockx . in . locks = & lock [ 0 ] ;
2004-02-08 03:51:07 +03:00
status = smb_raw_lock ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Unlock a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-05-25 20:24:13 +04:00
NTSTATUS cli_unlock ( struct cli_tree * tree , int fnum , uint32_t offset , uint32_t len )
2003-08-13 05:53:07 +04:00
{
union smb_lock parms ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
parms . lockx . level = RAW_LOCK_LOCKX ;
parms . lockx . in . fnum = fnum ;
parms . lockx . in . mode = 0 ;
parms . lockx . in . timeout = 0 ;
parms . lockx . in . ulock_cnt = 1 ;
parms . lockx . in . lock_cnt = 0 ;
2004-02-08 03:51:07 +03:00
lock [ 0 ] . pid = tree - > session - > pid ;
2003-08-13 05:53:07 +04:00
lock [ 0 ] . offset = offset ;
lock [ 0 ] . count = len ;
parms . lockx . in . locks = & lock [ 0 ] ;
2004-02-08 03:51:07 +03:00
status = smb_raw_lock ( tree , & parms ) ;
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Lock a file with 64 bit offsets .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_lock64 ( struct cli_tree * tree , int fnum ,
SMB_OFF_T offset , SMB_OFF_T len , int timeout ,
enum brl_type lock_type )
2003-08-13 05:53:07 +04:00
{
union smb_lock parms ;
int ltype ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
2004-02-08 03:51:07 +03:00
if ( ! ( tree - > session - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
return cli_lock ( tree , fnum , offset , len , timeout , lock_type ) ;
2003-08-13 05:53:07 +04:00
}
parms . lockx . level = RAW_LOCK_LOCKX ;
parms . lockx . in . fnum = fnum ;
ltype = ( lock_type = = READ_LOCK ? 1 : 0 ) ;
ltype | = LOCKING_ANDX_LARGE_FILES ;
parms . lockx . in . mode = ltype ;
parms . lockx . in . timeout = timeout ;
parms . lockx . in . ulock_cnt = 0 ;
parms . lockx . in . lock_cnt = 1 ;
2004-02-08 03:51:07 +03:00
lock [ 0 ] . pid = tree - > session - > pid ;
2003-08-13 05:53:07 +04:00
lock [ 0 ] . offset = offset ;
lock [ 0 ] . count = len ;
parms . lockx . in . locks = & lock [ 0 ] ;
2004-02-08 03:51:07 +03:00
status = smb_raw_lock ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Unlock a file with 64 bit offsets .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_unlock64 ( struct cli_tree * tree , int fnum , SMB_OFF_T offset ,
SMB_OFF_T len )
2003-08-13 05:53:07 +04:00
{
union smb_lock parms ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
2004-02-08 03:51:07 +03:00
if ( ! ( tree - > session - > transport - > negotiate . capabilities & CAP_LARGE_FILES ) ) {
return cli_unlock ( tree , fnum , offset , len ) ;
2003-08-13 05:53:07 +04:00
}
parms . lockx . level = RAW_LOCK_LOCKX ;
parms . lockx . in . fnum = fnum ;
parms . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
parms . lockx . in . timeout = 0 ;
parms . lockx . in . ulock_cnt = 1 ;
parms . lockx . in . lock_cnt = 0 ;
2004-02-08 03:51:07 +03:00
lock [ 0 ] . pid = tree - > session - > pid ;
2003-08-13 05:53:07 +04:00
lock [ 0 ] . offset = offset ;
lock [ 0 ] . count = len ;
parms . lockx . in . locks = & lock [ 0 ] ;
2004-02-08 03:51:07 +03:00
status = smb_raw_lock ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Do a SMBgetattrE call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-21 14:23:51 +03:00
NTSTATUS cli_getattrE ( struct cli_tree * tree , int fnum ,
2004-02-10 14:33:35 +03:00
uint16 * attr , size_t * size ,
time_t * c_time , time_t * a_time , time_t * m_time )
2003-08-13 05:53:07 +04:00
{
union smb_fileinfo parms ;
NTSTATUS status ;
parms . getattre . level = RAW_FILEINFO_GETATTRE ;
2004-02-21 14:23:51 +03:00
parms . getattre . in . fnum = fnum ;
2003-08-13 05:53:07 +04:00
2004-02-08 03:51:07 +03:00
status = smb_raw_fileinfo ( tree , NULL , & parms ) ;
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) )
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
if ( size ) {
* size = parms . getattre . out . size ;
}
if ( attr ) {
* attr = parms . getattre . out . attrib ;
}
if ( c_time ) {
* c_time = parms . getattre . out . create_time ;
}
if ( a_time ) {
2003-08-15 01:56:26 +04:00
* a_time = parms . getattre . out . access_time ;
2003-08-13 05:53:07 +04:00
}
if ( m_time ) {
2003-08-15 01:56:26 +04:00
* m_time = parms . getattre . out . write_time ;
2003-08-13 05:53:07 +04:00
}
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Do a SMBgetatr call
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_getatr ( struct cli_tree * tree , const char * fname ,
uint16 * attr , size_t * size , time_t * t )
2003-08-13 05:53:07 +04:00
{
union smb_fileinfo parms ;
NTSTATUS status ;
parms . getattr . level = RAW_FILEINFO_GETATTR ;
parms . getattr . in . fname = fname ;
2004-02-08 03:51:07 +03:00
status = smb_raw_pathinfo ( tree , NULL , & parms ) ;
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
if ( size ) {
* size = parms . getattr . out . size ;
}
if ( t ) {
* t = parms . getattr . out . write_time ;
}
if ( attr ) {
* attr = parms . getattr . out . attrib ;
}
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Do a SMBsetatr call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_setatr ( struct cli_tree * tree , const char * fname , uint16 mode ,
time_t t )
2003-08-13 05:53:07 +04:00
{
union smb_setfileinfo parms ;
NTSTATUS status ;
parms . setattr . level = RAW_SFILEINFO_SETATTR ;
parms . setattr . in . attrib = mode ;
parms . setattr . in . write_time = t ;
parms . setattr . file . fname = fname ;
2004-02-08 03:51:07 +03:00
status = smb_raw_setpathinfo ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Check for existence of a dir .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_chkpath ( struct cli_tree * tree , const char * path )
2003-08-13 05:53:07 +04:00
{
struct smb_chkpath parms ;
char * path2 ;
NTSTATUS status ;
path2 = strdup ( path ) ;
trim_string ( path2 , NULL , " \\ " ) ;
if ( ! * path2 ) {
free ( path2 ) ;
path2 = strdup ( " \\ " ) ;
}
parms . in . path = path2 ;
2004-02-08 03:51:07 +03:00
status = smb_raw_chkpath ( tree , & parms ) ;
2003-08-13 05:53:07 +04:00
free ( path2 ) ;
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Query disk space .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-10 14:33:35 +03:00
NTSTATUS cli_dskattr ( struct cli_tree * tree , int * bsize , int * total , int * avail )
2003-08-13 05:53:07 +04:00
{
union smb_fsinfo fsinfo_parms ;
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
mem_ctx = talloc_init ( " cli_dskattr " ) ;
fsinfo_parms . dskattr . level = RAW_QFS_DSKATTR ;
2004-02-08 03:51:07 +03:00
status = smb_raw_fsinfo ( tree , mem_ctx , & fsinfo_parms ) ;
2003-08-13 05:53:07 +04:00
if ( NT_STATUS_IS_OK ( status ) ) {
* bsize = fsinfo_parms . dskattr . out . block_size ;
* total = fsinfo_parms . dskattr . out . units_total ;
* avail = fsinfo_parms . dskattr . out . units_free ;
}
talloc_destroy ( mem_ctx ) ;
2004-02-10 14:33:35 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
Create and open a temporary file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-08 03:51:07 +03:00
int cli_ctemp ( struct cli_tree * tree , const char * path , char * * tmp_path )
2003-08-13 05:53:07 +04:00
{
union smb_open open_parms ;
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
mem_ctx = talloc_init ( " raw_open " ) ;
if ( ! mem_ctx ) return - 1 ;
open_parms . openx . level = RAW_OPEN_CTEMP ;
open_parms . ctemp . in . attrib = 0 ;
open_parms . ctemp . in . directory = path ;
2004-02-08 03:51:07 +03:00
status = smb_raw_open ( tree , mem_ctx , & open_parms ) ;
2003-08-13 05:53:07 +04:00
if ( tmp_path ) {
* tmp_path = strdup ( open_parms . ctemp . out . name ) ;
}
talloc_destroy ( mem_ctx ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return open_parms . ctemp . out . fnum ;
}
return - 1 ;
}