2000-11-15 00:56:32 +03:00
/*
2002-03-19 05:32:39 +03:00
Unix SMB / Netbios implementation .
Version 1.9 .
2000-02-03 08:10:09 +03:00
VFS initialisation and support functions
Copyright ( C ) Tim Potter 1999
2002-08-17 19:27:10 +04:00
Copyright ( C ) Alexander Bokovoy 2002
2006-07-11 22:01:26 +04:00
Copyright ( C ) James Peach 2006
2009-07-24 21:21:45 +04:00
Copyright ( C ) Volker Lendecke 2009
2000-11-15 00:56:32 +03:00
2000-02-03 08:10:09 +03: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-02-03 08:10:09 +03:00
( at your option ) any later version .
2000-11-15 00:56:32 +03:00
2000-02-03 08:10:09 +03:00
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 .
2000-11-15 00:56:32 +03:00
2000-02-03 08:10:09 +03:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2002-08-17 19:27:10 +04:00
This work was sponsored by Optifacio Software Services , Inc .
2000-02-03 08:10:09 +03:00
*/
# include "includes.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2010-08-18 14:24:35 +04:00
# include "memcache.h"
2000-02-03 08:10:09 +03:00
2002-09-25 19:19:00 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
2006-04-26 19:41:25 +04:00
static_decl_vfs ;
2003-04-16 18:45:11 +04:00
struct vfs_init_function_entry {
2003-05-12 03:34:18 +04:00
char * name ;
struct vfs_init_function_entry * prev , * next ;
2009-07-24 04:28:58 +04:00
const struct vfs_fn_pointers * fns ;
2003-04-16 18:45:11 +04:00
} ;
/****************************************************************************
maintain the list of available backends
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct vfs_init_function_entry * vfs_find_backend_entry ( const char * name )
{
2003-05-12 03:34:18 +04:00
struct vfs_init_function_entry * entry = backends ;
2007-10-28 13:58:26 +03:00
DEBUG ( 10 , ( " vfs_find_backend_entry called for %s \n " , name ) ) ;
2009-07-18 20:27:28 +04:00
2003-05-12 03:34:18 +04:00
while ( entry ) {
2003-05-16 10:20:57 +04:00
if ( strcmp ( entry - > name , name ) = = 0 ) return entry ;
2003-05-12 03:34:18 +04:00
entry = entry - > next ;
}
2003-04-16 18:45:11 +04:00
2003-05-12 03:34:18 +04:00
return NULL ;
2003-04-16 18:45:11 +04:00
}
2009-07-24 04:28:58 +04:00
NTSTATUS smb_register_vfs ( int version , const char * name ,
const struct vfs_fn_pointers * fns )
2003-04-16 18:45:11 +04:00
{
2003-05-12 03:34:18 +04:00
struct vfs_init_function_entry * entry = backends ;
if ( ( version ! = SMB_VFS_INTERFACE_VERSION ) ) {
DEBUG ( 0 , ( " Failed to register vfs module. \n "
" The module was compiled against SMB_VFS_INTERFACE_VERSION %d, \n "
" current SMB_VFS_INTERFACE_VERSION is %d. \n "
" Please recompile against the current Samba Version! \n " ,
version , SMB_VFS_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
2009-07-24 04:28:58 +04:00
if ( ! name | | ! name [ 0 ] ) {
2003-05-12 03:34:18 +04:00
DEBUG ( 0 , ( " smb_register_vfs() called with NULL pointer or empty name! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
if ( vfs_find_backend_entry ( name ) ) {
DEBUG ( 0 , ( " VFS module %s already loaded! \n " , name ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
2004-12-07 21:25:53 +03:00
entry = SMB_XMALLOC_P ( struct vfs_init_function_entry ) ;
2003-05-12 03:34:18 +04:00
entry - > name = smb_xstrdup ( name ) ;
2009-07-24 04:28:58 +04:00
entry - > fns = fns ;
2003-05-12 03:34:18 +04:00
DLIST_ADD ( backends , entry ) ;
DEBUG ( 5 , ( " Successfully added vfs backend '%s' \n " , name ) ) ;
return NT_STATUS_OK ;
2003-04-16 18:45:11 +04:00
}
2000-02-03 08:10:09 +03:00
/****************************************************************************
initialise default vfs hooks
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-06-30 02:32:24 +04:00
2002-08-17 19:27:10 +04:00
static void vfs_init_default ( connection_struct * conn )
2000-02-03 08:10:09 +03:00
{
2002-03-27 06:00:39 +03:00
DEBUG ( 3 , ( " Initialising default vfs hooks \n " ) ) ;
2006-07-11 22:01:26 +04:00
vfs_init_custom ( conn , DEFAULT_VFS_MODULE_NAME ) ;
2003-04-16 18:45:11 +04:00
}
/****************************************************************************
initialise custom vfs hooks
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool vfs_init_custom ( connection_struct * conn , const char * vfs_object )
2003-04-16 18:45:11 +04:00
{
2007-10-28 13:58:26 +03:00
char * module_path = NULL ;
2003-05-12 03:34:18 +04:00
char * module_name = NULL ;
char * module_param = NULL , * p ;
vfs_handle_struct * handle ;
2007-12-27 22:00:13 +03:00
const struct vfs_init_function_entry * entry ;
2009-07-18 20:27:28 +04:00
2003-05-12 03:34:18 +04:00
if ( ! conn | | ! vfs_object | | ! vfs_object [ 0 ] ) {
2010-03-28 16:21:49 +04:00
DEBUG ( 0 , ( " vfs_init_custom() called with NULL pointer or "
" empty vfs_object! \n " ) ) ;
2003-05-12 03:34:18 +04:00
return False ;
}
2003-04-16 18:45:11 +04:00
2005-05-06 17:26:54 +04:00
if ( ! backends ) {
static_init_vfs ;
}
2003-04-16 18:45:11 +04:00
2003-05-12 03:34:18 +04:00
DEBUG ( 3 , ( " Initialising custom vfs hooks from [%s] \n " , vfs_object ) ) ;
2007-10-28 13:58:26 +03:00
module_path = smb_xstrdup ( vfs_object ) ;
2003-05-12 03:34:18 +04:00
2007-10-28 13:58:26 +03:00
p = strchr_m ( module_path , ' : ' ) ;
2003-05-12 03:34:18 +04:00
if ( p ) {
* p = 0 ;
module_param = p + 1 ;
2003-09-05 23:59:55 +04:00
trim_char ( module_param , ' ' , ' ' ) ;
2003-05-12 03:34:18 +04:00
}
2007-10-28 13:58:26 +03:00
trim_char ( module_path , ' ' , ' ' ) ;
module_name = smb_xstrdup ( module_path ) ;
if ( ( module_name [ 0 ] = = ' / ' ) & &
( strcmp ( module_path , DEFAULT_VFS_MODULE_NAME ) ! = 0 ) ) {
/*
* Extract the module name from the path . Just use the base
* name of the last path component .
*/
SAFE_FREE ( module_name ) ;
module_name = smb_xstrdup ( strrchr_m ( module_path , ' / ' ) + 1 ) ;
p = strchr_m ( module_name , ' . ' ) ;
if ( p ! = NULL ) {
* p = ' \0 ' ;
}
}
2003-05-12 03:34:18 +04:00
2003-04-16 18:45:11 +04:00
/* First, try to load the module with the new module system */
2009-04-29 18:33:45 +04:00
entry = vfs_find_backend_entry ( module_name ) ;
if ( ! entry ) {
NTSTATUS status ;
DEBUG ( 5 , ( " vfs module [%s] not loaded - trying to load... \n " ,
vfs_object ) ) ;
status = smb_probe_module ( " vfs " , module_path ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " error probing vfs module '%s': %s \n " ,
module_path , nt_errstr ( status ) ) ) ;
goto fail ;
}
entry = vfs_find_backend_entry ( module_name ) ;
if ( ! entry ) {
DEBUG ( 0 , ( " Can't find a vfs module [%s] \n " , vfs_object ) ) ;
2007-10-28 13:58:26 +03:00
goto fail ;
2009-04-29 18:33:45 +04:00
}
}
DEBUGADD ( 5 , ( " Successfully loaded vfs module [%s] with the new modules system \n " , vfs_object ) ) ;
2003-05-12 03:34:18 +04:00
2008-04-28 12:31:49 +04:00
handle = TALLOC_ZERO_P ( conn , vfs_handle_struct ) ;
2003-05-12 03:34:18 +04:00
if ( ! handle ) {
2007-04-28 03:18:41 +04:00
DEBUG ( 0 , ( " TALLOC_ZERO() failed! \n " ) ) ;
2007-10-28 13:58:26 +03:00
goto fail ;
2003-05-12 03:34:18 +04:00
}
handle - > conn = conn ;
2009-07-24 04:28:58 +04:00
handle - > fns = entry - > fns ;
2003-05-12 03:34:18 +04:00
if ( module_param ) {
2008-04-28 12:31:49 +04:00
handle - > param = talloc_strdup ( conn , module_param ) ;
2003-04-16 18:45:11 +04:00
}
2003-05-12 03:34:18 +04:00
DLIST_ADD ( conn - > vfs_handles , handle ) ;
2003-04-16 18:45:11 +04:00
2007-10-28 13:58:26 +03:00
SAFE_FREE ( module_path ) ;
2003-05-12 03:34:18 +04:00
SAFE_FREE ( module_name ) ;
2002-03-27 06:00:39 +03:00
return True ;
2007-10-28 13:58:26 +03:00
fail :
SAFE_FREE ( module_path ) ;
SAFE_FREE ( module_name ) ;
return False ;
2000-02-03 08:10:09 +03:00
}
2006-07-11 22:01:26 +04:00
/*****************************************************************
Allow VFS modules to extend files_struct with VFS - specific state .
This will be ok for small numbers of extensions , but might need to
be refactored if it becomes more widely used .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
2009-02-01 07:51:04 +03:00
void * vfs_add_fsp_extension_notype ( vfs_handle_struct * handle ,
files_struct * fsp , size_t ext_size ,
void ( * destroy_fn ) ( void * p_data ) )
2006-07-11 22:01:26 +04:00
{
struct vfs_fsp_data * ext ;
void * ext_data ;
/* Prevent VFS modules adding multiple extensions. */
if ( ( ext_data = vfs_fetch_fsp_extension ( handle , fsp ) ) ) {
return ext_data ;
}
2006-08-01 01:40:25 +04:00
ext = ( struct vfs_fsp_data * ) TALLOC_ZERO (
2008-04-28 12:31:49 +04:00
handle - > conn , sizeof ( struct vfs_fsp_data ) + ext_size ) ;
2006-07-11 22:01:26 +04:00
if ( ext = = NULL ) {
return NULL ;
}
ext - > owner = handle ;
ext - > next = fsp - > vfs_extension ;
2009-02-01 07:51:04 +03:00
ext - > destroy = destroy_fn ;
2006-07-11 22:01:26 +04:00
fsp - > vfs_extension = ext ;
return EXT_DATA_AREA ( ext ) ;
}
void vfs_remove_fsp_extension ( vfs_handle_struct * handle , files_struct * fsp )
{
struct vfs_fsp_data * curr ;
struct vfs_fsp_data * prev ;
for ( curr = fsp - > vfs_extension , prev = NULL ;
curr ;
prev = curr , curr = curr - > next ) {
if ( curr - > owner = = handle ) {
if ( prev ) {
prev - > next = curr - > next ;
} else {
fsp - > vfs_extension = curr - > next ;
}
2009-02-01 07:51:04 +03:00
if ( curr - > destroy ) {
curr - > destroy ( EXT_DATA_AREA ( curr ) ) ;
}
2006-07-11 22:01:26 +04:00
TALLOC_FREE ( curr ) ;
return ;
}
}
}
2007-10-16 01:01:12 +04:00
void * vfs_memctx_fsp_extension ( vfs_handle_struct * handle , files_struct * fsp )
2006-07-11 22:01:26 +04:00
{
struct vfs_fsp_data * head ;
for ( head = fsp - > vfs_extension ; head ; head = head - > next ) {
if ( head - > owner = = handle ) {
2007-10-16 01:01:12 +04:00
return head ;
2006-07-11 22:01:26 +04:00
}
}
return NULL ;
}
2007-10-16 01:01:12 +04:00
void * vfs_fetch_fsp_extension ( vfs_handle_struct * handle , files_struct * fsp )
{
struct vfs_fsp_data * head ;
2007-12-20 22:59:44 +03:00
head = ( struct vfs_fsp_data * ) vfs_memctx_fsp_extension ( handle , fsp ) ;
2007-10-16 01:01:12 +04:00
if ( head ! = NULL ) {
return EXT_DATA_AREA ( head ) ;
}
return NULL ;
}
2006-07-11 22:01:26 +04:00
# undef EXT_DATA_AREA
2001-06-30 02:32:24 +04:00
/*****************************************************************
Generic VFS init .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool smbd_vfs_init ( connection_struct * conn )
2001-06-30 02:32:24 +04:00
{
2003-04-16 18:45:11 +04:00
const char * * vfs_objects ;
unsigned int i = 0 ;
int j = 0 ;
2009-07-18 20:27:28 +04:00
2002-08-17 19:27:10 +04:00
/* Normal share - initialise with disk access functions */
vfs_init_default ( conn ) ;
2003-05-12 03:34:18 +04:00
vfs_objects = lp_vfs_objects ( SNUM ( conn ) ) ;
2002-08-17 19:27:10 +04:00
2003-04-21 23:43:25 +04:00
/* Override VFS functions if 'vfs object' was not specified*/
if ( ! vfs_objects | | ! vfs_objects [ 0 ] )
2003-04-16 18:45:11 +04:00
return True ;
2009-07-18 20:27:28 +04:00
2003-05-12 03:34:18 +04:00
for ( i = 0 ; vfs_objects [ i ] ; ) {
i + + ;
2003-04-16 18:45:11 +04:00
}
for ( j = i - 1 ; j > = 0 ; j - - ) {
2003-05-12 03:34:18 +04:00
if ( ! vfs_init_custom ( conn , vfs_objects [ j ] ) ) {
DEBUG ( 0 , ( " smbd_vfs_init: vfs_init_custom failed for %s \n " , vfs_objects [ j ] ) ) ;
2003-04-16 18:45:11 +04:00
return False ;
2001-06-30 02:32:24 +04:00
}
}
2002-08-17 19:27:10 +04:00
return True ;
}
2002-01-05 00:11:35 +03:00
/*******************************************************************
Check if a file exists in the vfs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-06-10 21:37:57 +04:00
NTSTATUS vfs_file_exist ( connection_struct * conn , struct smb_filename * smb_fname )
2002-01-05 00:11:35 +03:00
{
2009-06-10 21:37:57 +04:00
/* Only return OK if stat was successful and S_ISREG */
2009-06-23 02:26:56 +04:00
if ( ( SMB_VFS_STAT ( conn , smb_fname ) ! = - 1 ) & &
S_ISREG ( smb_fname - > st . st_ex_mode ) ) {
return NT_STATUS_OK ;
2009-06-10 21:37:57 +04:00
}
2009-06-23 02:26:56 +04:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2000-02-03 08:10:09 +03:00
}
2000-11-15 00:56:32 +03:00
/****************************************************************************
Read data from fsp on the vfs . ( note : EINTR re - read differs from vfs_write_data )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ssize_t vfs_read_data ( files_struct * fsp , char * buf , size_t byte_count )
{
size_t total = 0 ;
while ( total < byte_count )
{
2008-01-10 17:33:51 +03:00
ssize_t ret = SMB_VFS_READ ( fsp , buf + total ,
byte_count - total ) ;
2000-11-15 00:56:32 +03:00
if ( ret = = 0 ) return total ;
if ( ret = = - 1 ) {
if ( errno = = EINTR )
continue ;
else
return - 1 ;
}
total + = ret ;
}
return ( ssize_t ) total ;
}
2004-01-06 04:22:14 +03:00
ssize_t vfs_pread_data ( files_struct * fsp , char * buf ,
size_t byte_count , SMB_OFF_T offset )
{
size_t total = 0 ;
while ( total < byte_count )
{
2008-01-07 02:14:19 +03:00
ssize_t ret = SMB_VFS_PREAD ( fsp , buf + total ,
2004-01-06 04:22:14 +03:00
byte_count - total , offset + total ) ;
if ( ret = = 0 ) return total ;
if ( ret = = - 1 ) {
if ( errno = = EINTR )
continue ;
else
return - 1 ;
}
total + = ret ;
}
return ( ssize_t ) total ;
}
2000-02-03 08:10:09 +03:00
/****************************************************************************
2000-09-27 23:09:59 +04:00
Write data to a fd on the vfs .
2000-02-03 08:10:09 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-09-27 23:09:59 +04:00
2007-10-31 02:22:24 +03:00
ssize_t vfs_write_data ( struct smb_request * req ,
files_struct * fsp ,
const char * buffer ,
size_t N )
2000-02-03 08:10:09 +03:00
{
2001-11-12 04:00:54 +03:00
size_t total = 0 ;
ssize_t ret ;
2000-02-03 08:10:09 +03:00
2007-10-31 02:22:24 +03:00
if ( req & & req - > unread_bytes ) {
SMB_ASSERT ( req - > unread_bytes = = N ) ;
2007-11-01 00:01:35 +03:00
/* VFS_RECVFILE must drain the socket
* before returning . */
req - > unread_bytes = 0 ;
2010-08-15 01:14:16 +04:00
return SMB_VFS_RECVFILE ( req - > sconn - > sock ,
2007-10-31 02:22:24 +03:00
fsp ,
( SMB_OFF_T ) - 1 ,
N ) ;
}
2001-11-12 04:00:54 +03:00
while ( total < N ) {
2008-01-10 17:49:35 +03:00
ret = SMB_VFS_WRITE ( fsp , buffer + total , N - total ) ;
2000-02-03 08:10:09 +03:00
2001-11-12 04:00:54 +03:00
if ( ret = = - 1 )
return - 1 ;
if ( ret = = 0 )
return total ;
2000-02-03 08:10:09 +03:00
2001-11-12 04:00:54 +03:00
total + = ret ;
}
return ( ssize_t ) total ;
2000-02-03 08:10:09 +03:00
}
2007-10-31 02:22:24 +03:00
ssize_t vfs_pwrite_data ( struct smb_request * req ,
files_struct * fsp ,
const char * buffer ,
size_t N ,
SMB_OFF_T offset )
2004-01-06 04:22:14 +03:00
{
size_t total = 0 ;
ssize_t ret ;
2007-10-31 02:22:24 +03:00
if ( req & & req - > unread_bytes ) {
SMB_ASSERT ( req - > unread_bytes = = N ) ;
2007-11-01 00:01:35 +03:00
/* VFS_RECVFILE must drain the socket
* before returning . */
req - > unread_bytes = 0 ;
2010-08-15 01:14:26 +04:00
return SMB_VFS_RECVFILE ( req - > sconn - > sock ,
2007-10-31 02:22:24 +03:00
fsp ,
offset ,
N ) ;
}
2004-01-06 04:22:14 +03:00
while ( total < N ) {
2008-01-07 11:23:04 +03:00
ret = SMB_VFS_PWRITE ( fsp , buffer + total , N - total ,
offset + total ) ;
2004-01-06 04:22:14 +03:00
if ( ret = = - 1 )
return - 1 ;
if ( ret = = 0 )
return total ;
total + = ret ;
}
return ( ssize_t ) total ;
}
2001-08-02 02:13:50 +04:00
/****************************************************************************
An allocate file space call using the vfs interface .
Allocates space for a file from a filedescriptor .
Returns 0 on success , - 1 on failure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-10-14 03:59:36 +04:00
int vfs_allocate_file_space ( files_struct * fsp , uint64_t len )
2001-08-02 02:13:50 +04:00
{
int ret ;
2001-11-12 04:00:54 +03:00
connection_struct * conn = fsp - > conn ;
2008-10-14 03:59:36 +04:00
uint64_t space_avail ;
uint64_t bsize , dfree , dsize ;
2010-12-14 06:17:57 +03:00
NTSTATUS status ;
2001-08-02 02:13:50 +04:00
/*
* Actually try and commit the space on disk . . . .
*/
2009-07-11 01:50:37 +04:00
DEBUG ( 10 , ( " vfs_allocate_file_space: file %s, len %.0f \n " ,
fsp_str_dbg ( fsp ) , ( double ) len ) ) ;
2001-08-02 02:13:50 +04:00
2002-12-04 06:12:09 +03:00
if ( ( ( SMB_OFF_T ) len ) < 0 ) {
2009-07-11 01:50:37 +04:00
DEBUG ( 0 , ( " vfs_allocate_file_space: %s negative len "
" requested. \n " , fsp_str_dbg ( fsp ) ) ) ;
2007-01-31 01:20:55 +03:00
errno = EINVAL ;
2002-12-04 06:12:09 +03:00
return - 1 ;
}
2010-12-14 06:17:57 +03:00
status = vfs_stat_fsp ( fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
2001-08-02 02:13:50 +04:00
2010-12-14 06:17:57 +03:00
if ( len = = ( uint64_t ) fsp - > fsp_name - > st . st_ex_size )
2001-08-02 02:13:50 +04:00
return 0 ;
2010-12-14 06:17:57 +03:00
if ( len < ( uint64_t ) fsp - > fsp_name - > st . st_ex_size ) {
2001-08-02 02:13:50 +04:00
/* Shrink - use ftruncate. */
2009-07-11 01:50:37 +04:00
DEBUG ( 10 , ( " vfs_allocate_file_space: file %s, shrink. Current "
" size %.0f \n " , fsp_str_dbg ( fsp ) ,
2010-12-14 06:17:57 +03:00
( double ) fsp - > fsp_name - > st . st_ex_size ) ) ;
2001-08-02 02:13:50 +04:00
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_ALLOC_SHRINK ) ;
2002-01-20 03:04:15 +03:00
flush_write_cache ( fsp , SIZECHANGE_FLUSH ) ;
2008-01-07 17:55:09 +03:00
if ( ( ret = SMB_VFS_FTRUNCATE ( fsp , ( SMB_OFF_T ) len ) ) ! = - 1 ) {
2001-08-02 02:13:50 +04:00
set_filelen_write_cache ( fsp , len ) ;
}
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_ALLOC_SHRINK ) ;
2001-08-02 02:13:50 +04:00
return ret ;
}
2010-12-21 03:53:16 +03:00
if ( ! lp_strict_allocate ( SNUM ( fsp - > conn ) ) )
return 0 ;
2001-11-12 04:00:54 +03:00
/* Grow - we need to test if we have enough space. */
2001-08-02 02:13:50 +04:00
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_ALLOC_GROW ) ;
2010-12-21 03:53:16 +03:00
/* See if we have a syscall that will allocate beyond end-of-file
without changing EOF . */
ret = SMB_VFS_FALLOCATE ( fsp , VFS_FALLOCATE_KEEP_SIZE , 0 , len ) ;
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_ALLOC_GROW ) ;
2010-12-21 03:53:16 +03:00
if ( ret = = 0 ) {
/* We changed the allocation size on disk, but not
EOF - exactly as required . We ' re done ! */
2001-11-12 05:03:44 +03:00
return 0 ;
2010-12-21 03:53:16 +03:00
}
2001-11-12 05:03:44 +03:00
2010-12-14 06:17:57 +03:00
len - = fsp - > fsp_name - > st . st_ex_size ;
2001-11-12 04:00:54 +03:00
len / = 1024 ; /* Len is now number of 1k blocks needed. */
2009-07-11 01:50:37 +04:00
space_avail = get_dfree_info ( conn , fsp - > fsp_name - > base_name , false ,
& bsize , & dfree , & dsize ) ;
2008-10-14 03:59:36 +04:00
if ( space_avail = = ( uint64_t ) - 1 ) {
2005-03-16 05:11:44 +03:00
return - 1 ;
}
2001-08-02 02:13:50 +04:00
2009-07-11 01:50:37 +04:00
DEBUG ( 10 , ( " vfs_allocate_file_space: file %s, grow. Current size %.0f, "
" needed blocks = %.0f, space avail = %.0f \n " ,
2010-12-14 06:17:57 +03:00
fsp_str_dbg ( fsp ) , ( double ) fsp - > fsp_name - > st . st_ex_size , ( double ) len ,
2009-07-11 01:50:37 +04:00
( double ) space_avail ) ) ;
2001-08-02 02:13:50 +04:00
2001-11-12 04:00:54 +03:00
if ( len > space_avail ) {
errno = ENOSPC ;
return - 1 ;
2001-08-02 02:13:50 +04:00
}
2001-11-12 04:00:54 +03:00
2001-08-02 02:13:50 +04:00
return 0 ;
}
2000-11-16 03:59:18 +03:00
/****************************************************************************
A vfs set_filelen call .
set the length of a file from a filedescriptor .
Returns 0 on success , - 1 on failure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int vfs_set_filelen ( files_struct * fsp , SMB_OFF_T len )
{
int ret ;
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_SET_FILE_LEN ) ;
2009-07-11 01:50:37 +04:00
DEBUG ( 10 , ( " vfs_set_filelen: ftruncate %s to len %.0f \n " ,
fsp_str_dbg ( fsp ) , ( double ) len ) ) ;
2002-01-20 03:04:15 +03:00
flush_write_cache ( fsp , SIZECHANGE_FLUSH ) ;
2008-01-07 17:55:09 +03:00
if ( ( ret = SMB_VFS_FTRUNCATE ( fsp , len ) ) ! = - 1 ) {
2000-11-16 03:59:18 +03:00
set_filelen_write_cache ( fsp , len ) ;
2007-02-03 19:53:52 +03:00
notify_fname ( fsp - > conn , NOTIFY_ACTION_MODIFIED ,
FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_ATTRIBUTES ,
2009-07-11 01:50:37 +04:00
fsp - > fsp_name - > base_name ) ;
2007-02-03 19:53:52 +03:00
}
2000-11-16 03:59:18 +03:00
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_SET_FILE_LEN ) ;
2000-11-16 03:59:18 +03:00
return ret ;
}
2010-12-03 04:26:00 +03:00
/****************************************************************************
2010-12-18 10:08:01 +03:00
A slow version of fallocate . Fallback code if SMB_VFS_FALLOCATE
fails . Needs to be outside of the default version of SMB_VFS_FALLOCATE
2010-12-03 04:26:00 +03:00
as this is also called from the default SMB_VFS_FTRUNCATE code .
2010-12-18 10:08:01 +03:00
Always extends the file size .
2010-12-03 04:26:00 +03:00
Returns 0 on success , errno on failure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SPARSE_BUF_WRITE_SIZE (32*1024)
int vfs_slow_fallocate ( files_struct * fsp , SMB_OFF_T offset , SMB_OFF_T len )
{
ssize_t pwrite_ret ;
size_t total = 0 ;
if ( ! sparse_buf ) {
sparse_buf = SMB_CALLOC_ARRAY ( char , SPARSE_BUF_WRITE_SIZE ) ;
if ( ! sparse_buf ) {
errno = ENOMEM ;
return ENOMEM ;
}
}
while ( total < len ) {
size_t curr_write_size = MIN ( SPARSE_BUF_WRITE_SIZE , ( len - total ) ) ;
pwrite_ret = SMB_VFS_PWRITE ( fsp , sparse_buf , curr_write_size , offset + total ) ;
if ( pwrite_ret = = - 1 ) {
DEBUG ( 10 , ( " vfs_slow_fallocate: SMB_VFS_PWRITE for file "
" %s failed with error %s \n " ,
fsp_str_dbg ( fsp ) , strerror ( errno ) ) ) ;
return errno ;
}
total + = pwrite_ret ;
}
return 0 ;
}
2005-05-17 05:04:51 +04:00
/****************************************************************************
A vfs fill sparse call .
Writes zeros from the end of file to len , if len is greater than EOF .
Used only by strict_sync .
Returns 0 on success , - 1 on failure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int vfs_fill_sparse ( files_struct * fsp , SMB_OFF_T len )
{
int ret ;
2010-12-14 06:17:57 +03:00
NTSTATUS status ;
2005-05-17 05:04:51 +04:00
SMB_OFF_T offset ;
size_t num_to_write ;
2010-12-14 06:17:57 +03:00
status = vfs_stat_fsp ( fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
2005-05-17 05:04:51 +04:00
}
2010-12-14 06:17:57 +03:00
if ( len < = fsp - > fsp_name - > st . st_ex_size ) {
2005-05-17 05:04:51 +04:00
return 0 ;
}
2010-12-03 02:38:36 +03:00
# ifdef S_ISFIFO
2010-12-14 06:17:57 +03:00
if ( S_ISFIFO ( fsp - > fsp_name - > st . st_ex_mode ) ) {
2010-12-03 02:38:36 +03:00
return 0 ;
}
# endif
2009-07-11 01:50:37 +04:00
DEBUG ( 10 , ( " vfs_fill_sparse: write zeros in file %s from len %.0f to "
" len %.0f (%.0f bytes) \n " , fsp_str_dbg ( fsp ) ,
2010-12-14 06:17:57 +03:00
( double ) fsp - > fsp_name - > st . st_ex_size , ( double ) len ,
( double ) ( len - fsp - > fsp_name - > st . st_ex_size ) ) ) ;
2005-05-17 05:04:51 +04:00
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_FILL_SPARSE ) ;
2005-05-17 05:04:51 +04:00
flush_write_cache ( fsp , SIZECHANGE_FLUSH ) ;
2010-12-14 06:17:57 +03:00
offset = fsp - > fsp_name - > st . st_ex_size ;
num_to_write = len - fsp - > fsp_name - > st . st_ex_size ;
2010-12-03 02:38:36 +03:00
/* Only do this on non-stream file handles. */
if ( fsp - > base_fsp = = NULL ) {
2010-12-18 10:08:01 +03:00
/* for allocation try fallocate first. This can fail on some
2010-12-03 02:38:36 +03:00
* platforms e . g . when the filesystem doesn ' t support it and no
* emulation is being done by the libc ( like on AIX with JFS1 ) . In that
2010-12-18 10:08:01 +03:00
* case we do our own emulation . fallocate implementations can
2010-12-03 02:38:36 +03:00
* return ENOTSUP or EINVAL in cases like that . */
2010-12-18 10:08:01 +03:00
ret = SMB_VFS_FALLOCATE ( fsp , VFS_FALLOCATE_EXTEND_SIZE ,
offset , num_to_write ) ;
2010-12-03 02:38:36 +03:00
if ( ret = = ENOSPC ) {
errno = ENOSPC ;
ret = - 1 ;
goto out ;
}
if ( ret = = 0 ) {
goto out ;
}
2010-12-18 10:08:01 +03:00
DEBUG ( 10 , ( " vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
2010-12-03 02:38:36 +03:00
" error %d. Falling back to slow manual allocation \n " , ret ) ) ;
}
2010-12-03 04:26:00 +03:00
ret = vfs_slow_fallocate ( fsp , offset , num_to_write ) ;
if ( ret ! = 0 ) {
errno = ret ;
ret = - 1 ;
2005-05-17 05:04:51 +04:00
}
2010-12-03 04:26:00 +03:00
out :
2005-05-17 05:04:51 +04:00
2010-12-03 04:26:00 +03:00
if ( ret = = 0 ) {
set_filelen_write_cache ( fsp , len ) ;
2005-05-17 05:04:51 +04:00
}
2009-02-03 22:56:35 +03:00
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_FILL_SPARSE ) ;
return ret ;
2005-05-17 05:04:51 +04:00
}
2000-02-03 08:10:09 +03:00
/****************************************************************************
2001-09-04 23:10:30 +04:00
Transfer some data ( n bytes ) between two file_struct ' s .
2000-02-03 08:10:09 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-09-27 23:09:59 +04:00
2008-01-10 15:30:43 +03:00
static ssize_t vfs_read_fn ( void * file , void * buf , size_t len )
2001-09-04 23:10:30 +04:00
{
2008-01-10 15:30:43 +03:00
struct files_struct * fsp = ( struct files_struct * ) file ;
2008-01-10 17:33:51 +03:00
return SMB_VFS_READ ( fsp , buf , len ) ;
2001-09-04 23:10:30 +04:00
}
2000-02-03 08:10:09 +03:00
2008-01-10 15:30:43 +03:00
static ssize_t vfs_write_fn ( void * file , const void * buf , size_t len )
2001-09-04 23:10:30 +04:00
{
2008-01-10 15:30:43 +03:00
struct files_struct * fsp = ( struct files_struct * ) file ;
2008-01-10 17:49:35 +03:00
return SMB_VFS_WRITE ( fsp , buf , len ) ;
2001-09-04 23:10:30 +04:00
}
2000-02-03 08:10:09 +03:00
2001-09-04 23:10:30 +04:00
SMB_OFF_T vfs_transfer_file ( files_struct * in , files_struct * out , SMB_OFF_T n )
{
2008-01-10 15:55:16 +03:00
return transfer_file_internal ( ( void * ) in , ( void * ) out , n ,
vfs_read_fn , vfs_write_fn ) ;
2000-02-03 08:10:09 +03:00
}
/*******************************************************************
2000-09-27 23:09:59 +04:00
A vfs_readdir wrapper which just returns the file name .
2000-02-03 08:10:09 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-09-27 23:09:59 +04:00
2009-11-16 11:49:23 +03:00
const char * vfs_readdirname ( connection_struct * conn , void * p ,
SMB_STRUCT_STAT * sbuf , char * * talloced )
2000-02-03 08:10:09 +03:00
{
2004-11-10 01:49:28 +03:00
SMB_STRUCT_DIRENT * ptr = NULL ;
2009-11-16 11:49:23 +03:00
const char * dname ;
char * translated ;
NTSTATUS status ;
2000-02-03 08:10:09 +03:00
2000-09-27 23:09:59 +04:00
if ( ! p )
return ( NULL ) ;
2000-11-15 00:56:32 +03:00
2009-01-23 07:14:38 +03:00
ptr = SMB_VFS_READDIR ( conn , ( DIR * ) p , sbuf ) ;
2000-09-27 23:09:59 +04:00
if ( ! ptr )
return ( NULL ) ;
2000-02-03 08:10:09 +03:00
2009-11-16 11:49:23 +03:00
dname = ptr - > d_name ;
2000-02-03 08:10:09 +03:00
# ifdef NEXT2
2000-09-27 23:09:59 +04:00
if ( telldir ( p ) < 0 )
return ( NULL ) ;
2000-02-03 08:10:09 +03:00
# endif
2006-03-27 23:50:45 +04:00
# ifdef HAVE_BROKEN_READDIR_NAME
2000-02-03 08:10:09 +03:00
/* using /usr/ucb/cc is BAD */
dname = dname - 2 ;
# endif
2009-11-16 11:49:23 +03:00
status = SMB_VFS_TRANSLATE_NAME ( conn , dname , vfs_translate_to_windows ,
talloc_tos ( ) , & translated ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NONE_MAPPED ) ) {
* talloced = NULL ;
return dname ;
}
* talloced = translated ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NULL ;
}
return translated ;
2000-02-03 08:10:09 +03:00
}
2000-09-27 23:09:59 +04:00
/*******************************************************************
A wrapper for vfs_chdir ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-03-03 23:12:37 +03:00
int vfs_ChDir ( connection_struct * conn , const char * path )
2000-09-27 23:09:59 +04:00
{
2010-07-13 20:30:35 +04:00
int res ;
if ( ! LastDir ) {
LastDir = SMB_STRDUP ( " " ) ;
}
if ( strcsequal ( path , " . " ) )
return ( 0 ) ;
if ( * path = = ' / ' & & strcsequal ( LastDir , path ) )
return ( 0 ) ;
DEBUG ( 4 , ( " vfs_ChDir to %s \n " , path ) ) ;
res = SMB_VFS_CHDIR ( conn , path ) ;
if ( ! res ) {
SAFE_FREE ( LastDir ) ;
LastDir = SMB_STRDUP ( path ) ;
}
return ( res ) ;
2000-09-27 23:09:59 +04:00
}
/*******************************************************************
Return the absolute current directory path - given a UNIX pathname .
Note that this path is returned in DOS format , not UNIX
format . Note this can be called with conn = = NULL .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-13 01:48:20 +04:00
char * vfs_GetWd ( TALLOC_CTX * ctx , connection_struct * conn )
2000-09-27 23:09:59 +04:00
{
2007-09-13 01:48:20 +04:00
char s [ PATH_MAX + 1 ] ;
2009-06-23 02:26:56 +04:00
char * result = NULL ;
2007-12-18 11:41:03 +03:00
DATA_BLOB cache_value ;
2009-02-17 03:06:45 +03:00
struct file_id key ;
2009-06-23 02:26:56 +04:00
struct smb_filename * smb_fname_dot = NULL ;
struct smb_filename * smb_fname_full = NULL ;
NTSTATUS status ;
2002-03-27 06:00:39 +03:00
* s = 0 ;
2007-12-18 11:41:03 +03:00
if ( ! lp_getwd_cache ( ) ) {
goto nocache ;
2002-03-27 06:00:39 +03:00
}
2009-06-23 02:26:56 +04:00
status = create_synthetic_smb_fname ( ctx , " . " , NULL , NULL ,
& smb_fname_dot ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
goto out ;
}
2000-09-27 23:09:59 +04:00
2009-06-23 02:26:56 +04:00
if ( SMB_VFS_STAT ( conn , smb_fname_dot ) = = - 1 ) {
2007-12-18 11:41:03 +03:00
/*
* Known to fail for root : the directory may be NFS - mounted
* and exported with root_squash ( so has no root access ) .
*/
2007-09-13 01:48:20 +04:00
DEBUG ( 1 , ( " vfs_GetWd: couldn't stat \" . \" error %s "
2007-12-18 11:41:03 +03:00
" (NFS problem ?) \n " , strerror ( errno ) ) ) ;
2007-09-13 01:48:20 +04:00
goto nocache ;
2002-03-27 06:00:39 +03:00
}
2000-09-27 23:09:59 +04:00
2009-06-23 02:26:56 +04:00
key = vfs_file_id_from_sbuf ( conn , & smb_fname_dot - > st ) ;
2000-09-27 23:09:59 +04:00
2007-12-18 11:41:03 +03:00
if ( ! memcache_lookup ( smbd_memcache ( ) , GETWD_CACHE ,
data_blob_const ( & key , sizeof ( key ) ) ,
& cache_value ) ) {
goto nocache ;
2002-03-27 06:00:39 +03:00
}
2000-09-27 23:09:59 +04:00
2007-12-18 11:41:03 +03:00
SMB_ASSERT ( ( cache_value . length > 0 )
& & ( cache_value . data [ cache_value . length - 1 ] = = ' \0 ' ) ) ;
2000-09-27 23:09:59 +04:00
2009-06-23 02:26:56 +04:00
status = create_synthetic_smb_fname ( ctx , ( char * ) cache_value . data ,
NULL , NULL , & smb_fname_full ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
goto out ;
}
if ( ( SMB_VFS_STAT ( conn , smb_fname_full ) = = 0 ) & &
( smb_fname_dot - > st . st_ex_dev = = smb_fname_full - > st . st_ex_dev ) & &
( smb_fname_dot - > st . st_ex_ino = = smb_fname_full - > st . st_ex_ino ) & &
( S_ISDIR ( smb_fname_dot - > st . st_ex_mode ) ) ) {
2007-12-18 11:41:03 +03:00
/*
* Ok , we ' re done
*/
2009-06-23 02:26:56 +04:00
result = talloc_strdup ( ctx , smb_fname_full - > base_name ) ;
2007-12-18 11:41:03 +03:00
if ( result = = NULL ) {
errno = ENOMEM ;
}
2009-06-23 02:26:56 +04:00
goto out ;
2002-03-27 06:00:39 +03:00
}
2000-09-27 23:09:59 +04:00
2007-12-18 11:41:03 +03:00
nocache :
/*
* We don ' t have the information to hand so rely on traditional
* methods . The very slow getcwd , which spawns a process on some
* systems , or the not quite so bad getwd .
*/
2000-09-27 23:09:59 +04:00
2007-12-18 11:41:03 +03:00
if ( ! SMB_VFS_GETWD ( conn , s ) ) {
DEBUG ( 0 , ( " vfs_GetWd: SMB_VFS_GETWD call failed: %s \n " ,
strerror ( errno ) ) ) ;
2009-06-23 02:26:56 +04:00
goto out ;
2007-12-18 11:41:03 +03:00
}
2000-09-27 23:09:59 +04:00
2009-06-23 02:26:56 +04:00
if ( lp_getwd_cache ( ) & & VALID_STAT ( smb_fname_dot - > st ) ) {
key = vfs_file_id_from_sbuf ( conn , & smb_fname_dot - > st ) ;
2002-03-27 06:00:39 +03:00
2007-12-18 11:41:03 +03:00
memcache_add ( smbd_memcache ( ) , GETWD_CACHE ,
data_blob_const ( & key , sizeof ( key ) ) ,
data_blob_const ( s , strlen ( s ) + 1 ) ) ;
}
2002-03-27 06:00:39 +03:00
2007-12-18 11:41:03 +03:00
result = talloc_strdup ( ctx , s ) ;
if ( result = = NULL ) {
2007-09-13 01:48:20 +04:00
errno = ENOMEM ;
}
2009-06-23 02:26:56 +04:00
out :
TALLOC_FREE ( smb_fname_dot ) ;
TALLOC_FREE ( smb_fname_full ) ;
2007-12-18 11:41:03 +03:00
return result ;
2000-09-27 23:09:59 +04:00
}
/*******************************************************************
2000-11-15 00:56:32 +03:00
Reduce a file name , removing . . elements and checking that
2004-05-13 04:20:50 +04:00
it is below dir in the heirachy . This uses realpath .
2000-09-27 23:09:59 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-07-09 13:43:41 +04:00
NTSTATUS check_reduced_name ( connection_struct * conn , const char * fname )
2000-09-27 23:09:59 +04:00
{
2004-05-13 04:20:50 +04:00
char * resolved_name = NULL ;
char * p = NULL ;
2002-03-27 06:00:39 +03:00
2009-11-12 13:07:15 +03:00
DEBUG ( 3 , ( " check_reduced_name [%s] [%s] \n " , fname , conn - > connectpath ) ) ;
2002-03-27 06:00:39 +03:00
2010-11-20 03:29:26 +03:00
resolved_name = SMB_VFS_REALPATH ( conn , fname ) ;
2002-03-27 06:00:39 +03:00
2004-05-13 04:20:50 +04:00
if ( ! resolved_name ) {
switch ( errno ) {
case ENOTDIR :
2009-11-12 13:07:15 +03:00
DEBUG ( 3 , ( " check_reduced_name: Component not a "
" directory in getting realpath for "
" %s \n " , fname ) ) ;
2009-11-25 01:05:56 +03:00
return NT_STATUS_OBJECT_PATH_NOT_FOUND ;
2004-05-13 04:20:50 +04:00
case ENOENT :
{
2008-01-10 04:11:04 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2007-09-13 01:48:20 +04:00
char * tmp_fname = NULL ;
char * last_component = NULL ;
2004-05-13 04:20:50 +04:00
/* Last component didn't exist. Remove it and try and canonicalise the directory. */
2008-01-10 04:11:04 +03:00
tmp_fname = talloc_strdup ( ctx , fname ) ;
2007-09-13 01:48:20 +04:00
if ( ! tmp_fname ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-13 04:20:50 +04:00
p = strrchr_m ( tmp_fname , ' / ' ) ;
if ( p ) {
* p + + = ' \0 ' ;
2007-09-13 01:48:20 +04:00
last_component = p ;
2004-05-13 04:56:00 +04:00
} else {
2007-09-13 01:48:20 +04:00
last_component = tmp_fname ;
2008-01-10 04:11:04 +03:00
tmp_fname = talloc_strdup ( ctx ,
2007-09-13 01:48:20 +04:00
" . " ) ;
if ( ! tmp_fname ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-13 04:20:50 +04:00
}
2004-05-13 04:56:00 +04:00
2010-11-20 03:29:26 +03:00
resolved_name = SMB_VFS_REALPATH ( conn , tmp_fname ) ;
2004-05-13 04:20:50 +04:00
if ( ! resolved_name ) {
2009-11-25 01:05:56 +03:00
NTSTATUS status = map_nt_error_from_unix ( errno ) ;
if ( errno = = ENOENT | | errno = = ENOTDIR ) {
status = NT_STATUS_OBJECT_PATH_NOT_FOUND ;
}
2010-12-06 16:05:49 +03:00
DEBUG ( 3 , ( " check_reduce_name: "
2009-11-12 13:07:15 +03:00
" couldn't get realpath for "
2009-11-25 01:05:56 +03:00
" %s (%s) \n " ,
fname ,
nt_errstr ( status ) ) ) ;
return status ;
2004-05-13 04:20:50 +04:00
}
2008-01-10 04:11:04 +03:00
tmp_fname = talloc_asprintf ( ctx ,
2007-09-13 01:48:20 +04:00
" %s/%s " ,
resolved_name ,
last_component ) ;
if ( ! tmp_fname ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-13 04:20:50 +04:00
SAFE_FREE ( resolved_name ) ;
2004-12-07 21:25:53 +03:00
resolved_name = SMB_STRDUP ( tmp_fname ) ;
2004-05-13 04:20:50 +04:00
if ( ! resolved_name ) {
2009-11-12 13:07:15 +03:00
DEBUG ( 0 , ( " check_reduced_name: malloc "
" fail for %s \n " , tmp_fname ) ) ;
2007-01-17 05:09:37 +03:00
return NT_STATUS_NO_MEMORY ;
2004-05-13 04:20:50 +04:00
}
break ;
}
default :
2010-09-14 03:54:21 +04:00
DEBUG ( 3 , ( " check_reduced_name: couldn't get "
2009-11-12 13:07:15 +03:00
" realpath for %s \n " , fname ) ) ;
2007-01-17 05:09:37 +03:00
return map_nt_error_from_unix ( errno ) ;
2004-05-13 04:20:50 +04:00
}
2002-03-27 06:00:39 +03:00
}
2009-11-12 13:07:15 +03:00
DEBUG ( 10 , ( " check_reduced_name realpath [%s] -> [%s] \n " , fname ,
resolved_name ) ) ;
2002-03-27 06:00:39 +03:00
2004-05-13 04:20:50 +04:00
if ( * resolved_name ! = ' / ' ) {
2009-11-12 13:07:15 +03:00
DEBUG ( 0 , ( " check_reduced_name: realpath doesn't return "
" absolute paths ! \n " ) ) ;
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2007-01-17 05:09:37 +03:00
return NT_STATUS_OBJECT_NAME_INVALID ;
2002-03-27 06:00:39 +03:00
}
2004-09-01 02:52:05 +04:00
/* Check for widelinks allowed. */
2010-02-12 02:16:23 +03:00
if ( ! lp_widelinks ( SNUM ( conn ) ) ) {
2009-05-28 21:20:14 +04:00
const char * conn_rootdir ;
conn_rootdir = SMB_VFS_CONNECTPATH ( conn , fname ) ;
if ( conn_rootdir = = NULL ) {
2009-11-12 13:07:15 +03:00
DEBUG ( 2 , ( " check_reduced_name: Could not get "
" conn_rootdir \n " ) ) ;
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2009-05-28 21:20:14 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
if ( strncmp ( conn_rootdir , resolved_name ,
strlen ( conn_rootdir ) ) ! = 0 ) {
2009-11-12 13:07:15 +03:00
DEBUG ( 2 , ( " check_reduced_name: Bad access "
" attempt: %s is a symlink outside the "
2010-02-06 02:20:18 +03:00
" share path \n " , fname ) ) ;
2010-11-30 20:21:46 +03:00
DEBUGADD ( 2 , ( " conn_rootdir =%s \n " , conn_rootdir ) ) ;
DEBUGADD ( 2 , ( " resolved_name=%s \n " , resolved_name ) ) ;
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2009-05-28 21:20:14 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2002-03-27 06:00:39 +03:00
}
2004-09-01 02:52:05 +04:00
/* Check if we are allowing users to follow symlinks */
/* Patch from David Clerc <David.Clerc@cui.unige.ch>
University of Geneva */
2007-09-13 01:48:20 +04:00
2004-09-01 02:52:05 +04:00
# ifdef S_ISLNK
if ( ! lp_symlinks ( SNUM ( conn ) ) ) {
2009-07-22 02:55:25 +04:00
struct smb_filename * smb_fname = NULL ;
NTSTATUS status ;
status = create_synthetic_smb_fname ( talloc_tos ( ) , fname , NULL ,
NULL , & smb_fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2009-07-22 02:55:25 +04:00
return status ;
}
if ( ( SMB_VFS_LSTAT ( conn , smb_fname ) ! = - 1 ) & &
( S_ISLNK ( smb_fname - > st . st_ex_mode ) ) ) {
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2009-11-12 13:07:15 +03:00
DEBUG ( 3 , ( " check_reduced_name: denied: file path name "
" %s is a symlink \n " , resolved_name ) ) ;
2009-07-22 02:55:25 +04:00
TALLOC_FREE ( smb_fname ) ;
2007-01-17 05:09:37 +03:00
return NT_STATUS_ACCESS_DENIED ;
2004-09-01 02:52:05 +04:00
}
2009-07-22 02:55:25 +04:00
TALLOC_FREE ( smb_fname ) ;
2004-09-01 02:52:05 +04:00
}
# endif
2000-09-27 23:09:59 +04:00
2009-11-12 13:07:15 +03:00
DEBUG ( 3 , ( " check_reduced_name: %s reduced to %s \n " , fname ,
resolved_name ) ) ;
2010-11-20 03:29:26 +03:00
SAFE_FREE ( resolved_name ) ;
2007-01-17 05:09:37 +03:00
return NT_STATUS_OK ;
2000-09-27 23:09:59 +04:00
}
2009-07-11 02:35:08 +04:00
/**
* XXX : This is temporary and there should be no callers of this once
* smb_filename is plumbed through all path based operations .
*/
int vfs_stat_smb_fname ( struct connection_struct * conn , const char * fname ,
SMB_STRUCT_STAT * psbuf )
{
struct smb_filename * smb_fname = NULL ;
NTSTATUS status ;
int ret ;
status = create_synthetic_smb_fname_split ( talloc_tos ( ) , fname , NULL ,
& smb_fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
2009-10-02 22:05:03 +04:00
if ( lp_posix_pathnames ( ) ) {
ret = SMB_VFS_LSTAT ( conn , smb_fname ) ;
} else {
ret = SMB_VFS_STAT ( conn , smb_fname ) ;
}
2009-07-11 02:35:08 +04:00
if ( ret ! = - 1 ) {
* psbuf = smb_fname - > st ;
}
TALLOC_FREE ( smb_fname ) ;
return ret ;
}
/**
* XXX : This is temporary and there should be no callers of this once
* smb_filename is plumbed through all path based operations .
*/
int vfs_lstat_smb_fname ( struct connection_struct * conn , const char * fname ,
SMB_STRUCT_STAT * psbuf )
{
struct smb_filename * smb_fname = NULL ;
NTSTATUS status ;
int ret ;
status = create_synthetic_smb_fname_split ( talloc_tos ( ) , fname , NULL ,
& smb_fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_LSTAT ( conn , smb_fname ) ;
if ( ret ! = - 1 ) {
* psbuf = smb_fname - > st ;
}
TALLOC_FREE ( smb_fname ) ;
return ret ;
}
2009-10-03 00:45:38 +04:00
/**
* Ensure LSTAT is called for POSIX paths .
*/
NTSTATUS vfs_stat_fsp ( files_struct * fsp )
{
int ret ;
2011-02-08 07:46:36 +03:00
if ( fsp - > fh - > fd = = - 1 ) {
2009-10-03 00:45:38 +04:00
if ( fsp - > posix_open ) {
ret = SMB_VFS_LSTAT ( fsp - > conn , fsp - > fsp_name ) ;
} else {
ret = SMB_VFS_STAT ( fsp - > conn , fsp - > fsp_name ) ;
}
if ( ret = = - 1 ) {
return map_nt_error_from_unix ( errno ) ;
}
} else {
if ( SMB_VFS_FSTAT ( fsp , & fsp - > fsp_name - > st ) ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
}
return NT_STATUS_OK ;
}
2009-07-24 04:28:58 +04:00
/*
generate a file_id from a stat structure
*/
struct file_id vfs_file_id_from_sbuf ( connection_struct * conn , const SMB_STRUCT_STAT * sbuf )
{
return SMB_VFS_FILE_ID_CREATE ( conn , sbuf ) ;
}
int smb_vfs_call_connect ( struct vfs_handle_struct * handle ,
const char * service , const char * user )
{
VFS_FIND ( connect_fn ) ;
return handle - > fns - > connect_fn ( handle , service , user ) ;
}
void smb_vfs_call_disconnect ( struct vfs_handle_struct * handle )
{
VFS_FIND ( disconnect ) ;
2009-07-25 20:33:11 +04:00
handle - > fns - > disconnect ( handle ) ;
2009-07-24 04:28:58 +04:00
}
uint64_t smb_vfs_call_disk_free ( struct vfs_handle_struct * handle ,
const char * path , bool small_query ,
uint64_t * bsize , uint64_t * dfree ,
uint64_t * dsize )
{
VFS_FIND ( disk_free ) ;
return handle - > fns - > disk_free ( handle , path , small_query , bsize , dfree ,
dsize ) ;
}
int smb_vfs_call_get_quota ( struct vfs_handle_struct * handle ,
enum SMB_QUOTA_TYPE qtype , unid_t id ,
SMB_DISK_QUOTA * qt )
{
VFS_FIND ( get_quota ) ;
return handle - > fns - > get_quota ( handle , qtype , id , qt ) ;
}
int smb_vfs_call_set_quota ( struct vfs_handle_struct * handle ,
enum SMB_QUOTA_TYPE qtype , unid_t id ,
SMB_DISK_QUOTA * qt )
{
VFS_FIND ( set_quota ) ;
return handle - > fns - > set_quota ( handle , qtype , id , qt ) ;
}
int smb_vfs_call_get_shadow_copy_data ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
SHADOW_COPY_DATA * shadow_copy_data ,
bool labels )
{
VFS_FIND ( get_shadow_copy_data ) ;
return handle - > fns - > get_shadow_copy_data ( handle , fsp , shadow_copy_data ,
labels ) ;
}
int smb_vfs_call_statvfs ( struct vfs_handle_struct * handle , const char * path ,
struct vfs_statvfs_struct * statbuf )
{
VFS_FIND ( statvfs ) ;
return handle - > fns - > statvfs ( handle , path , statbuf ) ;
}
2009-08-25 07:57:37 +04:00
uint32_t smb_vfs_call_fs_capabilities ( struct vfs_handle_struct * handle ,
enum timestamp_set_resolution * p_ts_res )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( fs_capabilities ) ;
2009-08-25 07:57:37 +04:00
return handle - > fns - > fs_capabilities ( handle , p_ts_res ) ;
2009-07-24 04:28:58 +04:00
}
SMB_STRUCT_DIR * smb_vfs_call_opendir ( struct vfs_handle_struct * handle ,
const char * fname , const char * mask ,
uint32 attributes )
{
VFS_FIND ( opendir ) ;
return handle - > fns - > opendir ( handle , fname , mask , attributes ) ;
}
SMB_STRUCT_DIRENT * smb_vfs_call_readdir ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp ,
SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( readdir ) ;
return handle - > fns - > readdir ( handle , dirp , sbuf ) ;
}
void smb_vfs_call_seekdir ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp , long offset )
{
VFS_FIND ( seekdir ) ;
2009-07-25 20:33:11 +04:00
handle - > fns - > seekdir ( handle , dirp , offset ) ;
2009-07-24 04:28:58 +04:00
}
long smb_vfs_call_telldir ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp )
{
VFS_FIND ( telldir ) ;
return handle - > fns - > telldir ( handle , dirp ) ;
}
void smb_vfs_call_rewind_dir ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp )
{
VFS_FIND ( rewind_dir ) ;
2009-07-25 20:33:11 +04:00
handle - > fns - > rewind_dir ( handle , dirp ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_mkdir ( struct vfs_handle_struct * handle , const char * path ,
mode_t mode )
{
VFS_FIND ( mkdir ) ;
return handle - > fns - > mkdir ( handle , path , mode ) ;
}
int smb_vfs_call_rmdir ( struct vfs_handle_struct * handle , const char * path )
{
VFS_FIND ( rmdir ) ;
return handle - > fns - > rmdir ( handle , path ) ;
}
int smb_vfs_call_closedir ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dir )
{
VFS_FIND ( closedir ) ;
return handle - > fns - > closedir ( handle , dir ) ;
}
void smb_vfs_call_init_search_op ( struct vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp )
{
VFS_FIND ( init_search_op ) ;
2009-07-25 20:33:11 +04:00
handle - > fns - > init_search_op ( handle , dirp ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_open ( struct vfs_handle_struct * handle ,
struct smb_filename * smb_fname , struct files_struct * fsp ,
int flags , mode_t mode )
{
VFS_FIND ( open ) ;
return handle - > fns - > open ( handle , smb_fname , fsp , flags , mode ) ;
}
NTSTATUS smb_vfs_call_create_file ( struct vfs_handle_struct * handle ,
struct smb_request * req ,
uint16_t root_dir_fid ,
struct smb_filename * smb_fname ,
uint32_t access_mask ,
uint32_t share_access ,
uint32_t create_disposition ,
uint32_t create_options ,
uint32_t file_attributes ,
uint32_t oplock_request ,
uint64_t allocation_size ,
2010-03-06 02:10:30 +03:00
uint32_t private_flags ,
2009-07-24 04:28:58 +04:00
struct security_descriptor * sd ,
struct ea_list * ea_list ,
files_struct * * result ,
int * pinfo )
{
VFS_FIND ( create_file ) ;
return handle - > fns - > create_file (
handle , req , root_dir_fid , smb_fname , access_mask ,
share_access , create_disposition , create_options ,
2010-03-06 02:10:30 +03:00
file_attributes , oplock_request , allocation_size ,
private_flags , sd , ea_list ,
2009-07-24 04:28:58 +04:00
result , pinfo ) ;
}
int smb_vfs_call_close_fn ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( close_fn ) ;
return handle - > fns - > close_fn ( handle , fsp ) ;
}
ssize_t smb_vfs_call_vfs_read ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , void * data , size_t n )
{
VFS_FIND ( vfs_read ) ;
return handle - > fns - > vfs_read ( handle , fsp , data , n ) ;
}
ssize_t smb_vfs_call_pread ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , void * data , size_t n ,
SMB_OFF_T offset )
{
VFS_FIND ( pread ) ;
return handle - > fns - > pread ( handle , fsp , data , n , offset ) ;
}
ssize_t smb_vfs_call_write ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const void * data ,
size_t n )
{
VFS_FIND ( write ) ;
return handle - > fns - > write ( handle , fsp , data , n ) ;
}
ssize_t smb_vfs_call_pwrite ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const void * data ,
size_t n , SMB_OFF_T offset )
{
VFS_FIND ( pwrite ) ;
return handle - > fns - > pwrite ( handle , fsp , data , n , offset ) ;
}
SMB_OFF_T smb_vfs_call_lseek ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_OFF_T offset ,
int whence )
{
VFS_FIND ( lseek ) ;
return handle - > fns - > lseek ( handle , fsp , offset , whence ) ;
}
ssize_t smb_vfs_call_sendfile ( struct vfs_handle_struct * handle , int tofd ,
files_struct * fromfsp , const DATA_BLOB * header ,
SMB_OFF_T offset , size_t count )
{
VFS_FIND ( sendfile ) ;
return handle - > fns - > sendfile ( handle , tofd , fromfsp , header , offset ,
count ) ;
}
ssize_t smb_vfs_call_recvfile ( struct vfs_handle_struct * handle , int fromfd ,
files_struct * tofsp , SMB_OFF_T offset ,
size_t count )
{
VFS_FIND ( recvfile ) ;
return handle - > fns - > recvfile ( handle , fromfd , tofsp , offset , count ) ;
}
int smb_vfs_call_rename ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname_src ,
const struct smb_filename * smb_fname_dst )
{
VFS_FIND ( rename ) ;
return handle - > fns - > rename ( handle , smb_fname_src , smb_fname_dst ) ;
}
int smb_vfs_call_fsync ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( fsync ) ;
return handle - > fns - > fsync ( handle , fsp ) ;
}
int smb_vfs_call_stat ( struct vfs_handle_struct * handle ,
struct smb_filename * smb_fname )
{
VFS_FIND ( stat ) ;
return handle - > fns - > stat ( handle , smb_fname ) ;
}
int smb_vfs_call_fstat ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( fstat ) ;
return handle - > fns - > fstat ( handle , fsp , sbuf ) ;
}
int smb_vfs_call_lstat ( struct vfs_handle_struct * handle ,
struct smb_filename * smb_filename )
{
VFS_FIND ( lstat ) ;
return handle - > fns - > lstat ( handle , smb_filename ) ;
}
uint64_t smb_vfs_call_get_alloc_size ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( get_alloc_size ) ;
return handle - > fns - > get_alloc_size ( handle , fsp , sbuf ) ;
}
int smb_vfs_call_unlink ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
{
VFS_FIND ( unlink ) ;
return handle - > fns - > unlink ( handle , smb_fname ) ;
}
int smb_vfs_call_chmod ( struct vfs_handle_struct * handle , const char * path ,
mode_t mode )
{
VFS_FIND ( chmod ) ;
return handle - > fns - > chmod ( handle , path , mode ) ;
}
int smb_vfs_call_fchmod ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , mode_t mode )
{
VFS_FIND ( fchmod ) ;
return handle - > fns - > fchmod ( handle , fsp , mode ) ;
}
int smb_vfs_call_chown ( struct vfs_handle_struct * handle , const char * path ,
uid_t uid , gid_t gid )
{
VFS_FIND ( chown ) ;
return handle - > fns - > chown ( handle , path , uid , gid ) ;
}
int smb_vfs_call_fchown ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , uid_t uid , gid_t gid )
{
VFS_FIND ( fchown ) ;
return handle - > fns - > fchown ( handle , fsp , uid , gid ) ;
}
int smb_vfs_call_lchown ( struct vfs_handle_struct * handle , const char * path ,
uid_t uid , gid_t gid )
{
VFS_FIND ( lchown ) ;
return handle - > fns - > lchown ( handle , path , uid , gid ) ;
}
2011-02-05 04:48:10 +03:00
NTSTATUS vfs_chown_fsp ( files_struct * fsp , uid_t uid , gid_t gid )
{
int ret ;
2011-02-08 07:46:36 +03:00
if ( fsp - > fh - > fd ! = - 1 ) {
2011-02-05 04:48:10 +03:00
/* Try fchown. */
ret = SMB_VFS_FCHOWN ( fsp , uid , gid ) ;
if ( ret = = 0 ) {
return NT_STATUS_OK ;
}
if ( ret = = - 1 & & errno ! = ENOSYS ) {
return map_nt_error_from_unix ( errno ) ;
}
}
if ( fsp - > posix_open ) {
ret = SMB_VFS_LCHOWN ( fsp - > conn ,
fsp - > fsp_name - > base_name ,
uid , gid ) ;
} else {
ret = SMB_VFS_CHOWN ( fsp - > conn ,
fsp - > fsp_name - > base_name ,
uid , gid ) ;
}
if ( ret = = 0 ) {
return NT_STATUS_OK ;
}
return map_nt_error_from_unix ( errno ) ;
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_chdir ( struct vfs_handle_struct * handle , const char * path )
{
VFS_FIND ( chdir ) ;
return handle - > fns - > chdir ( handle , path ) ;
}
char * smb_vfs_call_getwd ( struct vfs_handle_struct * handle , char * buf )
{
VFS_FIND ( getwd ) ;
return handle - > fns - > getwd ( handle , buf ) ;
}
int smb_vfs_call_ntimes ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
struct smb_file_time * ft )
{
VFS_FIND ( ntimes ) ;
return handle - > fns - > ntimes ( handle , smb_fname , ft ) ;
}
int smb_vfs_call_ftruncate ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_OFF_T offset )
{
VFS_FIND ( ftruncate ) ;
return handle - > fns - > ftruncate ( handle , fsp , offset ) ;
}
2010-12-18 10:08:01 +03:00
int smb_vfs_call_fallocate ( struct vfs_handle_struct * handle ,
2010-12-03 03:25:59 +03:00
struct files_struct * fsp ,
2010-12-18 10:08:01 +03:00
enum vfs_fallocate_mode mode ,
2010-12-03 03:25:59 +03:00
SMB_OFF_T offset ,
SMB_OFF_T len )
{
2010-12-18 10:08:01 +03:00
VFS_FIND ( fallocate ) ;
return handle - > fns - > fallocate ( handle , fsp , mode , offset , len ) ;
2010-12-03 03:25:59 +03:00
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_kernel_flock ( struct vfs_handle_struct * handle ,
2009-10-06 19:14:56 +04:00
struct files_struct * fsp , uint32 share_mode ,
uint32_t access_mask )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( kernel_flock ) ;
2009-10-06 19:14:56 +04:00
return handle - > fns - > kernel_flock ( handle , fsp , share_mode ,
access_mask ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_linux_setlease ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , int leasetype )
{
VFS_FIND ( linux_setlease ) ;
return handle - > fns - > linux_setlease ( handle , fsp , leasetype ) ;
}
int smb_vfs_call_symlink ( struct vfs_handle_struct * handle , const char * oldpath ,
const char * newpath )
{
VFS_FIND ( symlink ) ;
return handle - > fns - > symlink ( handle , oldpath , newpath ) ;
}
int smb_vfs_call_vfs_readlink ( struct vfs_handle_struct * handle ,
const char * path , char * buf , size_t bufsiz )
{
VFS_FIND ( vfs_readlink ) ;
return handle - > fns - > vfs_readlink ( handle , path , buf , bufsiz ) ;
}
int smb_vfs_call_link ( struct vfs_handle_struct * handle , const char * oldpath ,
const char * newpath )
{
VFS_FIND ( link ) ;
return handle - > fns - > link ( handle , oldpath , newpath ) ;
}
int smb_vfs_call_mknod ( struct vfs_handle_struct * handle , const char * path ,
mode_t mode , SMB_DEV_T dev )
{
VFS_FIND ( mknod ) ;
return handle - > fns - > mknod ( handle , path , mode , dev ) ;
}
2010-11-20 03:29:26 +03:00
char * smb_vfs_call_realpath ( struct vfs_handle_struct * handle , const char * path )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( realpath ) ;
2010-11-20 03:29:26 +03:00
return handle - > fns - > realpath ( handle , path ) ;
2009-07-24 04:28:58 +04:00
}
NTSTATUS smb_vfs_call_notify_watch ( struct vfs_handle_struct * handle ,
struct sys_notify_context * ctx ,
struct notify_entry * e ,
void ( * callback ) ( struct sys_notify_context * ctx ,
void * private_data ,
struct notify_event * ev ) ,
void * private_data , void * handle_p )
{
VFS_FIND ( notify_watch ) ;
return handle - > fns - > notify_watch ( handle , ctx , e , callback ,
private_data , handle_p ) ;
}
int smb_vfs_call_chflags ( struct vfs_handle_struct * handle , const char * path ,
unsigned int flags )
{
VFS_FIND ( chflags ) ;
return handle - > fns - > chflags ( handle , path , flags ) ;
}
struct file_id smb_vfs_call_file_id_create ( struct vfs_handle_struct * handle ,
const SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( file_id_create ) ;
return handle - > fns - > file_id_create ( handle , sbuf ) ;
}
NTSTATUS smb_vfs_call_streaminfo ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const char * fname ,
TALLOC_CTX * mem_ctx ,
unsigned int * num_streams ,
struct stream_struct * * streams )
{
VFS_FIND ( streaminfo ) ;
return handle - > fns - > streaminfo ( handle , fsp , fname , mem_ctx ,
num_streams , streams ) ;
}
int smb_vfs_call_get_real_filename ( struct vfs_handle_struct * handle ,
const char * path , const char * name ,
TALLOC_CTX * mem_ctx , char * * found_name )
{
VFS_FIND ( get_real_filename ) ;
return handle - > fns - > get_real_filename ( handle , path , name , mem_ctx ,
found_name ) ;
}
const char * smb_vfs_call_connectpath ( struct vfs_handle_struct * handle ,
const char * filename )
{
VFS_FIND ( connectpath ) ;
return handle - > fns - > connectpath ( handle , filename ) ;
}
bool smb_vfs_call_strict_lock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct lock_struct * plock )
{
VFS_FIND ( strict_lock ) ;
return handle - > fns - > strict_lock ( handle , fsp , plock ) ;
}
void smb_vfs_call_strict_unlock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct lock_struct * plock )
{
VFS_FIND ( strict_unlock ) ;
2009-07-25 20:33:11 +04:00
handle - > fns - > strict_unlock ( handle , fsp , plock ) ;
2009-07-24 04:28:58 +04:00
}
2009-08-27 01:56:09 +04:00
NTSTATUS smb_vfs_call_translate_name ( struct vfs_handle_struct * handle ,
2009-11-16 11:49:23 +03:00
const char * name ,
enum vfs_translate_direction direction ,
TALLOC_CTX * mem_ctx ,
char * * mapped_name )
2009-08-27 01:56:09 +04:00
{
VFS_FIND ( translate_name ) ;
2009-11-16 11:49:23 +03:00
return handle - > fns - > translate_name ( handle , name , direction , mem_ctx ,
mapped_name ) ;
2009-08-27 01:56:09 +04:00
}
2009-07-24 04:28:58 +04:00
NTSTATUS smb_vfs_call_fget_nt_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32 security_info ,
struct security_descriptor * * ppdesc )
{
VFS_FIND ( fget_nt_acl ) ;
return handle - > fns - > fget_nt_acl ( handle , fsp , security_info ,
ppdesc ) ;
}
NTSTATUS smb_vfs_call_get_nt_acl ( struct vfs_handle_struct * handle ,
const char * name ,
uint32 security_info ,
struct security_descriptor * * ppdesc )
{
VFS_FIND ( get_nt_acl ) ;
return handle - > fns - > get_nt_acl ( handle , name , security_info , ppdesc ) ;
}
NTSTATUS smb_vfs_call_fset_nt_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32 security_info_sent ,
const struct security_descriptor * psd )
{
VFS_FIND ( fset_nt_acl ) ;
return handle - > fns - > fset_nt_acl ( handle , fsp , security_info_sent , psd ) ;
}
int smb_vfs_call_chmod_acl ( struct vfs_handle_struct * handle , const char * name ,
mode_t mode )
{
VFS_FIND ( chmod_acl ) ;
return handle - > fns - > chmod_acl ( handle , name , mode ) ;
}
int smb_vfs_call_fchmod_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , mode_t mode )
{
VFS_FIND ( fchmod_acl ) ;
return handle - > fns - > fchmod_acl ( handle , fsp , mode ) ;
}
int smb_vfs_call_sys_acl_get_entry ( struct vfs_handle_struct * handle ,
SMB_ACL_T theacl , int entry_id ,
SMB_ACL_ENTRY_T * entry_p )
{
VFS_FIND ( sys_acl_get_entry ) ;
return handle - > fns - > sys_acl_get_entry ( handle , theacl , entry_id ,
entry_p ) ;
}
int smb_vfs_call_sys_acl_get_tag_type ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry_d ,
SMB_ACL_TAG_T * tag_type_p )
{
VFS_FIND ( sys_acl_get_tag_type ) ;
return handle - > fns - > sys_acl_get_tag_type ( handle , entry_d , tag_type_p ) ;
}
int smb_vfs_call_sys_acl_get_permset ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry_d ,
SMB_ACL_PERMSET_T * permset_p )
{
VFS_FIND ( sys_acl_get_permset ) ;
return handle - > fns - > sys_acl_get_permset ( handle , entry_d , permset_p ) ;
}
void * smb_vfs_call_sys_acl_get_qualifier ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry_d )
{
VFS_FIND ( sys_acl_get_qualifier ) ;
return handle - > fns - > sys_acl_get_qualifier ( handle , entry_d ) ;
}
SMB_ACL_T smb_vfs_call_sys_acl_get_file ( struct vfs_handle_struct * handle ,
const char * path_p ,
SMB_ACL_TYPE_T type )
{
VFS_FIND ( sys_acl_get_file ) ;
return handle - > fns - > sys_acl_get_file ( handle , path_p , type ) ;
}
SMB_ACL_T smb_vfs_call_sys_acl_get_fd ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( sys_acl_get_fd ) ;
return handle - > fns - > sys_acl_get_fd ( handle , fsp ) ;
}
int smb_vfs_call_sys_acl_clear_perms ( struct vfs_handle_struct * handle ,
SMB_ACL_PERMSET_T permset )
{
VFS_FIND ( sys_acl_clear_perms ) ;
return handle - > fns - > sys_acl_clear_perms ( handle , permset ) ;
}
int smb_vfs_call_sys_acl_add_perm ( struct vfs_handle_struct * handle ,
SMB_ACL_PERMSET_T permset ,
SMB_ACL_PERM_T perm )
{
VFS_FIND ( sys_acl_add_perm ) ;
return handle - > fns - > sys_acl_add_perm ( handle , permset , perm ) ;
}
char * smb_vfs_call_sys_acl_to_text ( struct vfs_handle_struct * handle ,
SMB_ACL_T theacl , ssize_t * plen )
{
VFS_FIND ( sys_acl_to_text ) ;
return handle - > fns - > sys_acl_to_text ( handle , theacl , plen ) ;
}
SMB_ACL_T smb_vfs_call_sys_acl_init ( struct vfs_handle_struct * handle ,
int count )
{
VFS_FIND ( sys_acl_init ) ;
return handle - > fns - > sys_acl_init ( handle , count ) ;
}
int smb_vfs_call_sys_acl_create_entry ( struct vfs_handle_struct * handle ,
SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
{
VFS_FIND ( sys_acl_create_entry ) ;
return handle - > fns - > sys_acl_create_entry ( handle , pacl , pentry ) ;
}
int smb_vfs_call_sys_acl_set_tag_type ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry ,
SMB_ACL_TAG_T tagtype )
{
VFS_FIND ( sys_acl_set_tag_type ) ;
return handle - > fns - > sys_acl_set_tag_type ( handle , entry , tagtype ) ;
}
int smb_vfs_call_sys_acl_set_qualifier ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry , void * qual )
{
VFS_FIND ( sys_acl_set_qualifier ) ;
return handle - > fns - > sys_acl_set_qualifier ( handle , entry , qual ) ;
}
int smb_vfs_call_sys_acl_set_permset ( struct vfs_handle_struct * handle ,
SMB_ACL_ENTRY_T entry ,
SMB_ACL_PERMSET_T permset )
{
VFS_FIND ( sys_acl_set_permset ) ;
return handle - > fns - > sys_acl_set_permset ( handle , entry , permset ) ;
}
int smb_vfs_call_sys_acl_valid ( struct vfs_handle_struct * handle ,
SMB_ACL_T theacl )
{
VFS_FIND ( sys_acl_valid ) ;
return handle - > fns - > sys_acl_valid ( handle , theacl ) ;
}
int smb_vfs_call_sys_acl_set_file ( struct vfs_handle_struct * handle ,
const char * name , SMB_ACL_TYPE_T acltype ,
SMB_ACL_T theacl )
{
VFS_FIND ( sys_acl_set_file ) ;
return handle - > fns - > sys_acl_set_file ( handle , name , acltype , theacl ) ;
}
int smb_vfs_call_sys_acl_set_fd ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_ACL_T theacl )
{
VFS_FIND ( sys_acl_set_fd ) ;
return handle - > fns - > sys_acl_set_fd ( handle , fsp , theacl ) ;
}
int smb_vfs_call_sys_acl_delete_def_file ( struct vfs_handle_struct * handle ,
const char * path )
{
VFS_FIND ( sys_acl_delete_def_file ) ;
return handle - > fns - > sys_acl_delete_def_file ( handle , path ) ;
}
int smb_vfs_call_sys_acl_get_perm ( struct vfs_handle_struct * handle ,
SMB_ACL_PERMSET_T permset ,
SMB_ACL_PERM_T perm )
{
VFS_FIND ( sys_acl_get_perm ) ;
return handle - > fns - > sys_acl_get_perm ( handle , permset , perm ) ;
}
int smb_vfs_call_sys_acl_free_text ( struct vfs_handle_struct * handle ,
char * text )
{
VFS_FIND ( sys_acl_free_text ) ;
return handle - > fns - > sys_acl_free_text ( handle , text ) ;
}
int smb_vfs_call_sys_acl_free_acl ( struct vfs_handle_struct * handle ,
SMB_ACL_T posix_acl )
{
VFS_FIND ( sys_acl_free_acl ) ;
return handle - > fns - > sys_acl_free_acl ( handle , posix_acl ) ;
}
int smb_vfs_call_sys_acl_free_qualifier ( struct vfs_handle_struct * handle ,
void * qualifier , SMB_ACL_TAG_T tagtype )
{
VFS_FIND ( sys_acl_free_qualifier ) ;
return handle - > fns - > sys_acl_free_qualifier ( handle , qualifier , tagtype ) ;
}
ssize_t smb_vfs_call_getxattr ( struct vfs_handle_struct * handle ,
const char * path , const char * name , void * value ,
size_t size )
{
VFS_FIND ( getxattr ) ;
return handle - > fns - > getxattr ( handle , path , name , value , size ) ;
}
ssize_t smb_vfs_call_lgetxattr ( struct vfs_handle_struct * handle ,
const char * path , const char * name , void * value ,
size_t size )
{
VFS_FIND ( lgetxattr ) ;
return handle - > fns - > lgetxattr ( handle , path , name , value , size ) ;
}
ssize_t smb_vfs_call_fgetxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const char * name ,
void * value , size_t size )
{
VFS_FIND ( fgetxattr ) ;
return handle - > fns - > fgetxattr ( handle , fsp , name , value , size ) ;
}
ssize_t smb_vfs_call_listxattr ( struct vfs_handle_struct * handle ,
const char * path , char * list , size_t size )
{
VFS_FIND ( listxattr ) ;
return handle - > fns - > listxattr ( handle , path , list , size ) ;
}
ssize_t smb_vfs_call_llistxattr ( struct vfs_handle_struct * handle ,
const char * path , char * list , size_t size )
{
VFS_FIND ( llistxattr ) ;
return handle - > fns - > llistxattr ( handle , path , list , size ) ;
}
ssize_t smb_vfs_call_flistxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , char * list ,
size_t size )
{
VFS_FIND ( flistxattr ) ;
return handle - > fns - > flistxattr ( handle , fsp , list , size ) ;
}
int smb_vfs_call_removexattr ( struct vfs_handle_struct * handle ,
const char * path , const char * name )
{
VFS_FIND ( removexattr ) ;
return handle - > fns - > removexattr ( handle , path , name ) ;
}
int smb_vfs_call_lremovexattr ( struct vfs_handle_struct * handle ,
const char * path , const char * name )
{
VFS_FIND ( lremovexattr ) ;
return handle - > fns - > lremovexattr ( handle , path , name ) ;
}
int smb_vfs_call_fremovexattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const char * name )
{
VFS_FIND ( fremovexattr ) ;
return handle - > fns - > fremovexattr ( handle , fsp , name ) ;
}
int smb_vfs_call_setxattr ( struct vfs_handle_struct * handle , const char * path ,
const char * name , const void * value , size_t size ,
int flags )
{
VFS_FIND ( setxattr ) ;
return handle - > fns - > setxattr ( handle , path , name , value , size , flags ) ;
}
int smb_vfs_call_lsetxattr ( struct vfs_handle_struct * handle , const char * path ,
const char * name , const void * value , size_t size ,
int flags )
{
VFS_FIND ( lsetxattr ) ;
return handle - > fns - > lsetxattr ( handle , path , name , value , size , flags ) ;
}
int smb_vfs_call_fsetxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const char * name ,
const void * value , size_t size , int flags )
{
VFS_FIND ( fsetxattr ) ;
return handle - > fns - > fsetxattr ( handle , fsp , name , value , size , flags ) ;
}
int smb_vfs_call_aio_read ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_read ) ;
return handle - > fns - > aio_read ( handle , fsp , aiocb ) ;
}
int smb_vfs_call_aio_write ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_write ) ;
return handle - > fns - > aio_write ( handle , fsp , aiocb ) ;
}
ssize_t smb_vfs_call_aio_return_fn ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_return_fn ) ;
return handle - > fns - > aio_return_fn ( handle , fsp , aiocb ) ;
}
int smb_vfs_call_aio_cancel ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_cancel ) ;
return handle - > fns - > aio_cancel ( handle , fsp , aiocb ) ;
}
int smb_vfs_call_aio_error_fn ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_error_fn ) ;
return handle - > fns - > aio_error_fn ( handle , fsp , aiocb ) ;
}
int smb_vfs_call_aio_fsync ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , int op ,
SMB_STRUCT_AIOCB * aiocb )
{
VFS_FIND ( aio_fsync ) ;
return handle - > fns - > aio_fsync ( handle , fsp , op , aiocb ) ;
}
int smb_vfs_call_aio_suspend ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const SMB_STRUCT_AIOCB * const aiocb [ ] , int n ,
const struct timespec * timeout )
{
VFS_FIND ( aio_suspend ) ;
return handle - > fns - > aio_suspend ( handle , fsp , aiocb , n , timeout ) ;
}
bool smb_vfs_call_aio_force ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( aio_force ) ;
return handle - > fns - > aio_force ( handle , fsp ) ;
}
bool smb_vfs_call_is_offline ( struct vfs_handle_struct * handle ,
const char * path , SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( is_offline ) ;
return handle - > fns - > is_offline ( handle , path , sbuf ) ;
}
int smb_vfs_call_set_offline ( struct vfs_handle_struct * handle ,
const char * path )
{
VFS_FIND ( set_offline ) ;
return handle - > fns - > set_offline ( handle , path ) ;
}