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"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2014-07-17 14:58:34 +04:00
# include "../lib/util/memcache.h"
2011-02-26 02:56:46 +03:00
# include "transfer_file.h"
2011-03-25 15:42:42 +03:00
# include "ntioctl.h"
2012-06-26 16:30:59 +04:00
# include "lib/util/tevent_unix.h"
2018-03-15 15:08:55 +03:00
# include "lib/util/tevent_ntstatus.h"
2020-05-11 23:00:37 +03:00
# include "lib/util/sys_rw.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 ;
2012-06-04 19:57:36 +04:00
struct vfs_fsp_data {
struct vfs_fsp_data * next ;
struct vfs_handle_struct * owner ;
void ( * destroy ) ( void * p_data ) ;
void * _dummy_ ;
/* NOTE: This structure contains four pointers so that we can guarantee
* that the end of the structure is always both 4 - byte and 8 - byte aligned .
*/
} ;
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 ) {
2017-04-20 22:24:43 +03:00
static_init_vfs ( NULL ) ;
2005-05-06 17:26:54 +04:00
}
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 ) ) ;
2012-04-03 07:23:43 +04:00
status = smb_load_module ( " vfs " , module_path ) ;
2009-04-29 18:33:45 +04:00
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
2011-06-07 05:44:43 +04:00
handle = talloc_zero ( 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-04-14 02:56:09 +03:00
# define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
2006-07-11 22:01:26 +04:00
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 ;
}
2021-04-13 17:57:26 +03:00
ext = talloc_zero_size (
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 ;
}
}
}
2012-06-04 19:54:41 +04:00
void vfs_remove_all_fsp_extensions ( files_struct * fsp )
{
struct vfs_fsp_data * curr ;
2012-06-11 13:33:45 +04:00
struct vfs_fsp_data * next ;
for ( curr = fsp - > vfs_extension ; curr ; curr = next ) {
next = curr - > next ;
fsp - > vfs_extension = next ;
2012-06-04 19:54:41 +04:00
if ( curr - > destroy ) {
curr - > destroy ( EXT_DATA_AREA ( curr ) ) ;
}
TALLOC_FREE ( curr ) ;
}
}
2021-01-20 16:47:19 +03:00
void * vfs_memctx_fsp_extension ( vfs_handle_struct * handle ,
const struct 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 ;
}
2021-01-20 16:47:19 +03:00
void * vfs_fetch_fsp_extension ( vfs_handle_struct * handle ,
const struct files_struct * fsp )
2007-10-16 01:01:12 +04:00
{
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
2016-04-01 19:47:31 +03:00
/*
* Ensure this module catches all VFS functions .
*/
# ifdef DEVELOPER
void smb_vfs_assert_all_fns ( const struct vfs_fn_pointers * fns ,
const char * module )
{
bool missing_fn = false ;
unsigned int idx ;
const uintptr_t * end = ( const uintptr_t * ) ( fns + 1 ) ;
for ( idx = 0 ; ( ( const uintptr_t * ) fns + idx ) < end ; idx + + ) {
if ( * ( ( const uintptr_t * ) fns + idx ) = = 0 ) {
DBG_ERR ( " VFS function at index %d not implemented "
" in module %s \n " , idx , module ) ;
missing_fn = true ;
}
}
if ( missing_fn ) {
smb_panic ( " Required VFS function not implemented in module. \n " ) ;
}
}
# else
void smb_vfs_assert_all_fns ( const struct vfs_fn_pointers * fns ,
const char * module )
{
}
# endif
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 ) ;
2012-08-12 17:51:30 +04:00
/* No need to load vfs modules for printer connections */
if ( conn - > printer ) {
return True ;
}
2020-04-07 03:24:10 +03:00
if ( lp_widelinks ( SNUM ( conn ) ) ) {
/*
* As the widelinks logic is now moving into a
* vfs_widelinks module , we need to custom load
* it after the default module is initialized .
* That way no changes to smb . conf files are
* needed .
*/
bool ok = vfs_init_custom ( conn , " widelinks " ) ;
if ( ! ok ) {
DBG_ERR ( " widelinks enabled and vfs_init_custom "
" failed for vfs_widelinks module \n " ) ;
return false ;
}
}
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
}
2020-05-11 23:00:37 +03:00
bool vfs_valid_pread_range ( off_t offset , size_t length )
{
return sys_valid_io_range ( offset , length ) ;
}
bool vfs_valid_pwrite_range ( off_t offset , size_t length )
{
/*
* See MAXFILESIZE in [ MS - FSA ] 2.1 .5 .3 Server Requests a Write
*/
static const uint64_t maxfilesize = 0xfffffff0000 ;
uint64_t last_byte_ofs ;
bool ok ;
ok = sys_valid_io_range ( offset , length ) ;
if ( ! ok ) {
return false ;
}
if ( length = = 0 ) {
return true ;
}
last_byte_ofs = offset + length ;
if ( last_byte_ofs > maxfilesize ) {
return false ;
}
return true ;
}
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 ,
2012-04-05 08:53:08 +04:00
off_t offset )
2004-01-06 04:22:14 +03:00
{
size_t total = 0 ;
ssize_t ret ;
2020-05-11 19:18:24 +03:00
bool ok ;
ok = vfs_valid_pwrite_range ( offset , N ) ;
if ( ! ok ) {
errno = EINVAL ;
return - 1 ;
}
2004-01-06 04:22:14 +03:00
2007-10-31 02:22:24 +03:00
if ( req & & req - > unread_bytes ) {
2014-06-11 15:54:43 +04:00
int sockfd = req - > xconn - > transport . sock ;
2007-10-31 02:22:24 +03:00
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 ;
2014-04-09 20:50:46 +04:00
/*
* Leave the socket non - blocking and
* use SMB_VFS_RECVFILE . If it returns
* EAGAIN | | EWOULDBLOCK temporarily set
* the socket blocking and retry
* the RECVFILE .
*/
while ( total < N ) {
ret = SMB_VFS_RECVFILE ( sockfd ,
fsp ,
offset + total ,
N - total ) ;
if ( ret = = 0 | | ( ret = = - 1 & &
2014-09-17 02:25:38 +04:00
( errno = = EAGAIN | |
errno = = EWOULDBLOCK ) ) ) {
2014-04-09 20:50:46 +04:00
int old_flags ;
/* Ensure the socket is blocking. */
old_flags = fcntl ( sockfd , F_GETFL , 0 ) ;
if ( set_blocking ( sockfd , true ) = = - 1 ) {
return ( ssize_t ) - 1 ;
}
ret = SMB_VFS_RECVFILE ( sockfd ,
fsp ,
offset + total ,
N - total ) ;
if ( fcntl ( sockfd , F_SETFL , old_flags ) = = - 1 ) {
return ( ssize_t ) - 1 ;
}
if ( ret = = - 1 ) {
return ( ssize_t ) - 1 ;
}
total + = ret ;
return ( ssize_t ) total ;
}
/* Any other error case. */
if ( ret = = - 1 ) {
return ret ;
}
total + = ret ;
2013-04-08 21:49:03 +04:00
}
2014-04-09 20:50:46 +04:00
return ( ssize_t ) total ;
2007-10-31 02:22:24 +03:00
}
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 ;
2020-05-11 19:18:24 +03:00
bool ok ;
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
2020-05-11 19:18:24 +03:00
ok = vfs_valid_pwrite_range ( ( off_t ) len , 0 ) ;
if ( ! ok ) {
DEBUG ( 0 , ( " vfs_allocate_file_space: %s negative/invalid len "
2009-07-11 01:50:37 +04:00
" 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 ) ;
2019-05-27 12:24:14 +03:00
ret = SMB_VFS_FTRUNCATE ( fsp , ( off_t ) 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 ;
}
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
2013-09-05 14:33:21 +04:00
if ( lp_strict_allocate ( SNUM ( fsp - > conn ) ) ) {
/* See if we have a syscall that will allocate beyond
end - of - file without changing EOF . */
2015-02-09 20:21:59 +03:00
ret = SMB_VFS_FALLOCATE ( fsp , VFS_FALLOCATE_FL_KEEP_SIZE ,
0 , len ) ;
2013-09-05 14:33:21 +04:00
} else {
ret = 0 ;
}
2010-12-21 03:53:16 +03:00
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
2014-12-06 02:34:12 +03:00
if ( ret = = - 1 & & errno = = ENOSPC ) {
return - 1 ;
}
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. */
2016-01-14 01:09:36 +03:00
space_avail =
get_dfree_info ( conn , fsp - > fsp_name , & 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-04-05 08:53:08 +04:00
int vfs_set_filelen ( files_struct * fsp , off_t len )
2000-11-16 03:59:18 +03:00
{
int ret ;
2020-05-11 19:18:24 +03:00
bool ok ;
ok = vfs_valid_pwrite_range ( len , 0 ) ;
if ( ! ok ) {
errno = EINVAL ;
return - 1 ;
}
2000-11-16 03:59:18 +03:00
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 ) ) ;
2008-01-07 17:55:09 +03:00
if ( ( ret = SMB_VFS_FTRUNCATE ( fsp , len ) ) ! = - 1 ) {
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 .
2014-12-06 02:34:12 +03:00
Returns 0 on success , - 1 on failure .
2010-12-03 04:26:00 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SPARSE_BUF_WRITE_SIZE (32*1024)
2012-04-05 08:53:08 +04:00
int vfs_slow_fallocate ( files_struct * fsp , off_t offset , off_t len )
2010-12-03 04:26:00 +03:00
{
ssize_t pwrite_ret ;
size_t total = 0 ;
2020-05-11 19:18:24 +03:00
bool ok ;
ok = vfs_valid_pwrite_range ( offset , len ) ;
if ( ! ok ) {
errno = EINVAL ;
return - 1 ;
}
2010-12-03 04:26:00 +03:00
if ( ! sparse_buf ) {
sparse_buf = SMB_CALLOC_ARRAY ( char , SPARSE_BUF_WRITE_SIZE ) ;
if ( ! sparse_buf ) {
errno = ENOMEM ;
2014-12-06 02:34:12 +03:00
return - 1 ;
2010-12-03 04:26:00 +03:00
}
}
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 ) {
2014-12-06 02:34:12 +03:00
int saved_errno = errno ;
2010-12-03 04:26:00 +03:00
DEBUG ( 10 , ( " vfs_slow_fallocate: SMB_VFS_PWRITE for file "
" %s failed with error %s \n " ,
2014-12-06 02:34:12 +03:00
fsp_str_dbg ( fsp ) , strerror ( saved_errno ) ) ) ;
errno = saved_errno ;
return - 1 ;
2010-12-03 04:26:00 +03:00
}
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-04-05 08:53:08 +04:00
int vfs_fill_sparse ( files_struct * fsp , off_t len )
2005-05-17 05:04:51 +04:00
{
int ret ;
2010-12-14 06:17:57 +03:00
NTSTATUS status ;
2012-04-05 08:53:08 +04:00
off_t offset ;
2005-05-17 05:04:51 +04:00
size_t num_to_write ;
2020-05-11 19:18:24 +03:00
bool ok ;
ok = vfs_valid_pwrite_range ( len , 0 ) ;
if ( ! ok ) {
errno = EINVAL ;
return - 1 ;
}
2005-05-17 05:04:51 +04:00
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 ) ;
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. */
2022-02-11 11:37:35 +03:00
if ( ! fsp_is_alternate_stream ( fsp ) ) {
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 . */
2015-02-09 20:21:59 +03:00
ret = SMB_VFS_FALLOCATE ( fsp , 0 , offset , num_to_write ) ;
2014-12-06 02:34:12 +03:00
if ( ret = = - 1 & & errno = = ENOSPC ) {
2010-12-03 02:38:36 +03:00
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 ) ;
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
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
}
2019-09-27 09:37:40 +03:00
/*******************************************************************************
Set a fd into blocking / nonblocking mode through VFS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int vfs_set_blocking ( files_struct * fsp , bool set )
{
int val ;
# ifdef O_NONBLOCK
# define FLAG_TO_SET O_NONBLOCK
# else
# ifdef SYSV
# define FLAG_TO_SET O_NDELAY
# else /* BSD */
# define FLAG_TO_SET FNDELAY
# endif
# endif
2020-10-26 16:39:02 +03:00
if ( fsp - > fsp_flags . is_pathref ) {
return 0 ;
}
2019-09-27 09:37:40 +03:00
val = SMB_VFS_FCNTL ( fsp , F_GETFL , 0 ) ;
if ( val = = - 1 ) {
return - 1 ;
}
if ( set ) {
val & = ~ FLAG_TO_SET ;
} else {
val | = FLAG_TO_SET ;
}
return SMB_VFS_FCNTL ( fsp , F_SETFL , val ) ;
# undef FLAG_TO_SET
}
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
2015-04-27 13:16:16 +03:00
static ssize_t vfs_pread_fn ( void * file , void * buf , size_t len , off_t offset )
2001-09-04 23:10:30 +04:00
{
2008-01-10 15:30:43 +03:00
struct files_struct * fsp = ( struct files_struct * ) file ;
2015-04-27 13:16:16 +03:00
return SMB_VFS_PREAD ( fsp , buf , len , offset ) ;
2001-09-04 23:10:30 +04:00
}
2000-02-03 08:10:09 +03:00
2015-04-27 13:16:16 +03:00
static ssize_t vfs_pwrite_fn ( void * file , const void * buf , size_t len , off_t offset )
2001-09-04 23:10:30 +04:00
{
2008-01-10 15:30:43 +03:00
struct files_struct * fsp = ( struct files_struct * ) file ;
2015-04-27 13:16:16 +03:00
return SMB_VFS_PWRITE ( fsp , buf , len , offset ) ;
2001-09-04 23:10:30 +04:00
}
2000-02-03 08:10:09 +03:00
2012-04-05 08:53:08 +04:00
off_t vfs_transfer_file ( files_struct * in , files_struct * out , off_t n )
2001-09-04 23:10:30 +04:00
{
2008-01-10 15:55:16 +03:00
return transfer_file_internal ( ( void * ) in , ( void * ) out , n ,
2015-04-27 13:16:16 +03:00
vfs_pread_fn , vfs_pwrite_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
2020-11-22 15:57:27 +03:00
const char * vfs_readdirname ( connection_struct * conn ,
struct files_struct * dirfsp ,
2023-11-16 22:39:50 +03:00
DIR * d ,
2020-11-22 15:57:27 +03:00
char * * talloced )
2000-02-03 08:10:09 +03:00
{
2012-03-28 06:18:14 +04:00
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
2023-11-16 22:39:50 +03:00
if ( d = = NULL ) {
2000-09-27 23:09:59 +04:00
return ( NULL ) ;
2023-11-16 22:39:50 +03:00
}
2000-11-15 00:56:32 +03:00
2023-11-16 22:39:50 +03:00
ptr = SMB_VFS_READDIR ( conn , dirfsp , d ) ;
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 ;
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 ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-06-29 21:29:33 +03:00
int vfs_ChDir ( connection_struct * conn , const struct smb_filename * smb_fname )
2000-09-27 23:09:59 +04:00
{
2012-09-12 22:39:37 +04:00
int ret ;
2019-08-15 16:53:32 +03:00
struct smb_filename * cwd = NULL ;
2012-09-12 22:39:37 +04:00
2012-09-13 21:13:21 +04:00
if ( ! LastDir ) {
LastDir = SMB_STRDUP ( " " ) ;
}
2017-06-29 21:29:33 +03:00
if ( ISDOT ( smb_fname - > base_name ) ) {
2020-07-01 10:38:58 +03:00
/*
* passing a ' . ' is a noop ,
* and we only expect this after
* everything is initialized .
*
* So the first vfs_ChDir ( ) on a given
* connection_struct must not be ' . ' .
*
* Note : conn_new ( ) sets
* conn - > cwd_fsp - > fh - > fd = - 1
* and vfs_ChDir ( ) leaves with
* conn - > cwd_fsp - > fh - > fd = AT_FDCWD
* on success !
*/
2020-10-17 18:01:47 +03:00
if ( fsp_get_pathref_fd ( conn - > cwd_fsp ) ! = AT_FDCWD ) {
2020-07-01 10:38:58 +03:00
/*
* This should never happen and
* we might change this to
* SMB_ASSERT ( ) in future .
*/
DBG_ERR ( " Called with '.' as first operation! \n " ) ;
log_stack_trace ( ) ;
errno = EINVAL ;
return - 1 ;
}
2012-09-12 22:21:01 +04:00
return 0 ;
2010-07-13 20:30:35 +04:00
}
2020-07-02 13:06:28 +03:00
if ( smb_fname - > base_name [ 0 ] = = ' / ' & &
strcsequal ( LastDir , smb_fname - > base_name ) )
{
2020-07-01 10:38:58 +03:00
/*
* conn - > cwd_fsp - > fsp_name and the kernel
* are already correct , but conn - > cwd_fsp - > fh - > fd
* might still be - 1 as initialized in conn_new ( ) .
*
* This can happen when a client made a 2 nd
* tree connect to a share with the same underlying
* path ( may or may not the same share ) .
*/
2020-09-26 22:46:51 +03:00
fsp_set_fd ( conn - > cwd_fsp , AT_FDCWD ) ;
2012-09-13 21:13:21 +04:00
return 0 ;
}
2017-06-29 21:29:33 +03:00
DEBUG ( 4 , ( " vfs_ChDir to %s \n " , smb_fname - > base_name ) ) ;
2010-07-13 20:30:35 +04:00
2017-06-29 21:29:33 +03:00
ret = SMB_VFS_CHDIR ( conn , smb_fname ) ;
2017-10-04 22:43:22 +03:00
if ( ret ! = 0 ) {
return - 1 ;
}
/*
2019-08-15 16:53:32 +03:00
* Always replace conn - > cwd_fsp . We
2017-10-04 22:43:22 +03:00
* don ' t know if it ' s been modified by
* VFS modules in the stack .
*/
2021-06-23 09:38:44 +03:00
fsp_set_fd ( conn - > cwd_fsp , AT_FDCWD ) ;
2017-10-04 22:43:22 +03:00
/* conn cache. */
2019-08-15 16:53:32 +03:00
cwd = vfs_GetWd ( conn , conn ) ;
if ( cwd = = NULL ) {
2017-10-04 22:43:22 +03:00
/*
* vfs_GetWd ( ) failed .
* We must be able to read cwd .
* Return to original directory
* and return - 1.
*/
2018-11-09 22:23:21 +03:00
int saved_errno = errno ;
2017-10-04 22:43:22 +03:00
2019-08-15 16:53:32 +03:00
if ( conn - > cwd_fsp - > fsp_name = = NULL ) {
2017-10-04 22:43:22 +03:00
/*
* Failed on the very first chdir ( ) + getwd ( )
* for this connection . We can ' t
* continue .
*/
smb_panic ( " conn->cwd getwd failed \n " ) ;
/* NOTREACHED */
return - 1 ;
}
/* Return to the previous $cwd. */
2019-08-15 16:53:32 +03:00
ret = SMB_VFS_CHDIR ( conn , conn - > cwd_fsp - > fsp_name ) ;
2017-10-04 22:43:22 +03:00
if ( ret ! = 0 ) {
smb_panic ( " conn->cwd getwd failed \n " ) ;
2017-06-30 00:32:47 +03:00
/* NOTREACHED */
return - 1 ;
}
2017-10-04 22:43:22 +03:00
errno = saved_errno ;
/* And fail the chdir(). */
return - 1 ;
}
/* vfs_GetWd() succeeded. */
/* Replace global cache. */
SAFE_FREE ( LastDir ) ;
LastDir = SMB_STRDUP ( smb_fname - > base_name ) ;
2019-08-15 16:53:32 +03:00
/*
* ( Indirect ) Callers of vfs_ChDir ( ) may still hold references to the
* old conn - > cwd_fsp - > fsp_name . Move it to talloc_tos ( ) , that way
* callers can use it for the lifetime of the SMB request .
*/
talloc_move ( talloc_tos ( ) , & conn - > cwd_fsp - > fsp_name ) ;
conn - > cwd_fsp - > fsp_name = talloc_move ( conn - > cwd_fsp , & cwd ) ;
DBG_INFO ( " vfs_ChDir got %s \n " , fsp_str_dbg ( conn - > cwd_fsp ) ) ;
2017-10-04 22:43:22 +03:00
2012-09-12 22:39:37 +04:00
return ret ;
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-06-30 00:32:47 +03:00
struct smb_filename * vfs_GetWd ( TALLOC_CTX * ctx , connection_struct * conn )
2000-09-27 23:09:59 +04:00
{
2017-06-30 00:32:47 +03:00
struct smb_filename * current_dir_fname = NULL ;
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 ;
2017-06-30 00:32:47 +03:00
struct smb_filename * result = NULL ;
2002-03-27 06:00:39 +03:00
2007-12-18 11:41:03 +03:00
if ( ! lp_getwd_cache ( ) ) {
goto nocache ;
2002-03-27 06:00:39 +03:00
}
2020-05-03 16:08:59 +03:00
smb_fname_dot = synthetic_smb_fname ( ctx ,
" . " ,
NULL ,
NULL ,
2020-04-30 12:48:32 +03:00
0 ,
2020-05-03 16:08:59 +03:00
0 ) ;
2013-04-12 13:43:24 +04:00
if ( smb_fname_dot = = NULL ) {
errno = ENOMEM ;
2009-06-23 02:26:56 +04:00
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
2017-06-30 00:32:47 +03:00
smb_fname_full = ( struct smb_filename * ) memcache_lookup_talloc (
smbd_memcache ( ) ,
GETWD_CACHE ,
data_blob_const ( & key , sizeof ( key ) ) ) ;
2000-09-27 23:09:59 +04:00
2013-04-12 13:43:24 +04:00
if ( smb_fname_full = = NULL ) {
2017-06-30 00:32:47 +03:00
goto nocache ;
2009-06-23 02:26:56 +04:00
}
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
2017-06-30 00:32:47 +03:00
* Note : smb_fname_full is owned by smbd_memcache ( )
* so we must make a copy to return .
2007-12-18 11:41:03 +03:00
*/
2017-06-30 00:32:47 +03:00
result = cp_smb_filename ( ctx , smb_fname_full ) ;
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
2017-06-30 00:32:47 +03:00
current_dir_fname = SMB_VFS_GETWD ( conn , ctx ) ;
if ( current_dir_fname = = NULL ) {
2007-12-18 11:41:03 +03:00
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
2017-06-30 00:32:47 +03:00
/*
* smbd_memcache ( ) will own current_dir_fname after the
* memcache_add_talloc call , so we must make
* a copy on ctx to return .
*/
result = cp_smb_filename ( ctx , current_dir_fname ) ;
if ( result = = NULL ) {
errno = ENOMEM ;
}
2002-03-27 06:00:39 +03:00
2017-06-30 00:32:47 +03:00
/*
* Ensure the memory going into the cache
* doesn ' t have a destructor so it can be
* cleanly freed .
*/
talloc_set_destructor ( current_dir_fname , NULL ) ;
memcache_add_talloc ( smbd_memcache ( ) ,
GETWD_CACHE ,
data_blob_const ( & key , sizeof ( key ) ) ,
& current_dir_fname ) ;
/* current_dir_fname is now == NULL here. */
} else {
/* current_dir_fname is already allocated on ctx. */
result = current_dir_fname ;
2007-09-13 01:48:20 +04:00
}
2009-06-23 02:26:56 +04:00
out :
TALLOC_FREE ( smb_fname_dot ) ;
2017-06-30 00:32:47 +03:00
/*
* Don ' t free current_dir_fname here . It ' s either been moved
* to the memcache or is being returned in result .
*/
2007-12-18 11:41:03 +03:00
return result ;
2000-09-27 23:09:59 +04:00
}
2020-10-16 15:35:10 +03:00
/*
* Ensure LSTAT is called for POSIX paths .
*/
int vfs_stat ( struct connection_struct * conn ,
struct smb_filename * smb_fname )
{
if ( smb_fname - > flags & SMB_FILENAME_POSIX_PATH ) {
return SMB_VFS_LSTAT ( conn , smb_fname ) ;
}
return SMB_VFS_STAT ( conn , smb_fname ) ;
}
2015-05-01 22:50:51 +03:00
/**
* XXX : This is temporary and there should be no callers of this once
* smb_filename is plumbed through all path based operations .
*
* Called when we know stream name parsing has already been done .
*/
2016-03-19 08:17:30 +03:00
int vfs_stat_smb_basename ( struct connection_struct * conn ,
const struct smb_filename * smb_fname_in ,
SMB_STRUCT_STAT * psbuf )
2015-05-01 22:50:51 +03:00
{
struct smb_filename smb_fname = {
2016-03-19 08:17:30 +03:00
. base_name = discard_const_p ( char , smb_fname_in - > base_name ) ,
2020-05-02 09:10:36 +03:00
. flags = smb_fname_in - > flags ,
. twrp = smb_fname_in - > twrp ,
2015-05-01 22:50:51 +03:00
} ;
int ret ;
2021-12-14 01:02:51 +03:00
ret = vfs_stat ( conn , & smb_fname ) ;
2015-05-01 22:50:51 +03:00
if ( ret ! = - 1 ) {
* psbuf = smb_fname . st ;
}
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 ;
2019-09-09 09:08:06 +03:00
struct stat_ex saved_stat = fsp - > fsp_name - > st ;
2009-10-03 00:45:38 +04:00
2023-08-04 18:19:00 +03:00
if ( fsp - > fake_file_handle ! = NULL ) {
return NT_STATUS_OK ;
}
2020-10-05 08:50:16 +03:00
if ( fsp_get_pathref_fd ( fsp ) = = - 1 ) {
2024-10-04 20:22:39 +03:00
if ( fsp - > fsp_flags . posix_open ) {
2009-10-03 00:45:38 +04:00
ret = SMB_VFS_LSTAT ( fsp - > conn , fsp - > fsp_name ) ;
} else {
ret = SMB_VFS_STAT ( fsp - > conn , fsp - > fsp_name ) ;
}
} else {
2019-09-09 09:03:53 +03:00
ret = SMB_VFS_FSTAT ( fsp , & fsp - > fsp_name - > st ) ;
}
if ( ret = = - 1 ) {
return map_nt_error_from_unix ( errno ) ;
2009-10-03 00:45:38 +04:00
}
2019-09-09 09:08:06 +03:00
update_stat_ex_from_saved_stat ( & fsp - > fsp_name - > st , & saved_stat ) ;
2022-06-30 11:45:54 +03:00
fsp - > fsp_flags . is_directory = S_ISDIR ( fsp - > fsp_name - > st . st_ex_mode ) ;
2009-10-03 00:45:38 +04:00
return NT_STATUS_OK ;
}
2019-12-02 18:21:42 +03:00
void init_smb_file_time ( struct smb_file_time * ft )
{
2024-06-25 14:06:35 +03:00
struct timespec omit = make_omit_timespec ( ) ;
2019-12-02 18:21:42 +03:00
* ft = ( struct smb_file_time ) {
2024-06-25 14:06:35 +03:00
. atime = omit ,
. ctime = omit ,
. mtime = omit ,
. create_time = omit ,
2019-12-02 18:21:42 +03:00
} ;
}
2011-10-17 22:10:29 +04:00
/**
* Initialize num_streams and streams , then call VFS op streaminfo
*/
2021-04-28 11:51:05 +03:00
NTSTATUS vfs_fstreaminfo ( struct files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
unsigned int * num_streams ,
struct stream_struct * * streams )
{
* num_streams = 0 ;
* streams = NULL ;
if ( fsp = = NULL ) {
/*
* Callers may pass fsp = = NULL when passing smb_fname - > fsp of a
* symlink . This is ok , handle it here , by just return no
* streams on a symlink .
*/
return NT_STATUS_OK ;
}
if ( fsp_get_pathref_fd ( fsp ) = = - 1 ) {
/*
* No streams on non - real files / directories .
*/
return NT_STATUS_OK ;
}
return SMB_VFS_FSTREAMINFO ( fsp ,
mem_ctx ,
num_streams ,
streams ) ;
}
2020-07-23 08:32:11 +03:00
int vfs_fake_fd ( void )
{
int pipe_fds [ 2 ] ;
int ret ;
/*
* Return a valid fd , but ensure any attempt to use
* it returns an error ( EPIPE ) .
*/
ret = pipe ( pipe_fds ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
close ( pipe_fds [ 1 ] ) ;
return pipe_fds [ 0 ] ;
}
2020-12-18 16:03:09 +03:00
/*
* This is just a helper to make
2021-10-12 13:36:16 +03:00
* users of vfs_fake_fd ( ) more symmetric
2020-12-18 16:03:09 +03:00
*/
int vfs_fake_fd_close ( int fd )
{
return close ( fd ) ;
}
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 ) ;
}
2020-05-20 18:01:48 +03:00
NTSTATUS vfs_at_fspcwd ( TALLOC_CTX * mem_ctx ,
struct connection_struct * conn ,
struct files_struct * * _fsp )
{
struct files_struct * fsp = NULL ;
fsp = talloc_zero ( mem_ctx , struct files_struct ) ;
if ( fsp = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
fsp - > fsp_name = synthetic_smb_fname ( fsp , " . " , NULL , NULL , 0 , 0 ) ;
if ( fsp - > fsp_name = = NULL ) {
TALLOC_FREE ( fsp ) ;
return NT_STATUS_NO_MEMORY ;
}
2020-09-27 22:16:03 +03:00
fsp - > fh = fd_handle_create ( fsp ) ;
2020-05-20 18:01:48 +03:00
if ( fsp - > fh = = NULL ) {
TALLOC_FREE ( fsp ) ;
return NT_STATUS_NO_MEMORY ;
}
2020-09-26 22:46:51 +03:00
fsp_set_fd ( fsp , AT_FDCWD ) ;
2020-05-20 18:01:48 +03:00
fsp - > fnum = FNUM_FIELD_INVALID ;
fsp - > conn = conn ;
* _fsp = fsp ;
return NT_STATUS_OK ;
}
2024-09-24 08:36:58 +03:00
uint32_t vfs_get_fs_capabilities ( struct connection_struct * conn ,
enum timestamp_set_resolution * ts_res )
{
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES ;
struct smb_filename * smb_fname_cpath = NULL ;
struct vfs_statvfs_struct statbuf ;
int ret ;
smb_fname_cpath = synthetic_smb_fname ( talloc_tos ( ) ,
conn - > connectpath ,
NULL ,
NULL ,
0 ,
0 ) ;
if ( smb_fname_cpath = = NULL ) {
return caps ;
}
ZERO_STRUCT ( statbuf ) ;
ret = SMB_VFS_STATVFS ( conn , smb_fname_cpath , & statbuf ) ;
if ( ret = = 0 ) {
caps = statbuf . FsCapabilities ;
}
if ( lp_nt_acl_support ( SNUM ( conn ) ) ) {
caps | = FILE_PERSISTENT_ACLS ;
}
caps | = lp_parm_int ( SNUM ( conn ) , " share " , " fake_fscaps " , 0 ) ;
* ts_res = TIMESTAMP_SET_SECONDS ;
/* Work out what timestamp resolution we can
* use when setting a timestamp . */
ret = SMB_VFS_STAT ( conn , smb_fname_cpath ) ;
if ( ret = = - 1 ) {
TALLOC_FREE ( smb_fname_cpath ) ;
return caps ;
}
if ( smb_fname_cpath - > st . st_ex_mtime . tv_nsec | |
smb_fname_cpath - > st . st_ex_atime . tv_nsec | |
smb_fname_cpath - > st . st_ex_ctime . tv_nsec ) {
/* If any of the normal UNIX directory timestamps
* have a non - zero tv_nsec component assume
* we might be able to set sub - second timestamps .
* See what filetime set primitives we have .
*/
# if defined(HAVE_UTIMENSAT)
* ts_res = TIMESTAMP_SET_NT_OR_BETTER ;
# elif defined(HAVE_UTIMES)
/* utimes allows msec timestamps to be set. */
* ts_res = TIMESTAMP_SET_MSEC ;
# elif defined(HAVE_UTIME)
/* utime only allows sec timestamps to be set. */
* ts_res = TIMESTAMP_SET_SECONDS ;
# endif
DBG_DEBUG ( " vfs_get_fs_capabilities: timestamp "
" resolution of %s "
" available on share %s, directory %s \n " ,
* ts_res = = TIMESTAMP_SET_MSEC ? " msec " : " sec " ,
lp_servicename ( talloc_tos ( ) , lp_sub , conn - > params - > service ) ,
conn - > connectpath ) ;
}
TALLOC_FREE ( smb_fname_cpath ) ;
return caps ;
}
2022-08-21 16:37:18 +03:00
static struct smb_vfs_deny_state * smb_vfs_deny_global ;
void smb_vfs_assert_allowed ( void )
{
if ( unlikely ( smb_vfs_deny_global ! = NULL ) ) {
DBG_ERR ( " Called with VFS denied by %s \n " ,
smb_vfs_deny_global - > location ) ;
smb_panic ( " Called with VFS denied! " ) ;
}
}
void _smb_vfs_deny_push ( struct smb_vfs_deny_state * state , const char * location )
{
SMB_ASSERT ( smb_vfs_deny_global ! = state ) ;
* state = ( struct smb_vfs_deny_state ) {
. parent = smb_vfs_deny_global ,
. location = location ,
} ;
smb_vfs_deny_global = state ;
}
void _smb_vfs_deny_pop ( struct smb_vfs_deny_state * state , const char * location )
{
SMB_ASSERT ( smb_vfs_deny_global = = state ) ;
smb_vfs_deny_global = state - > parent ;
* state = ( struct smb_vfs_deny_state ) { . parent = NULL , } ;
}
2022-08-21 16:19:59 +03:00
# define VFS_FIND(__fn__) do { \
2022-08-21 16:37:18 +03:00
if ( unlikely ( smb_vfs_deny_global ! = NULL ) ) { \
DBG_ERR ( " Called with VFS denied by %s \n " , \
smb_vfs_deny_global - > location ) ; \
smb_panic ( " Called with VFS denied! " ) ; \
} \
2022-08-21 16:19:59 +03:00
while ( handle - > fns - > __fn__ # # _fn = = NULL ) { \
handle = handle - > next ; \
} \
} while ( 0 )
2009-07-24 04:28:58 +04:00
int smb_vfs_call_connect ( struct vfs_handle_struct * handle ,
const char * service , const char * user )
{
2011-12-04 08:45:04 +04:00
VFS_FIND ( connect ) ;
2009-07-24 04:28:58 +04:00
return handle - > fns - > connect_fn ( handle , service , user ) ;
}
void smb_vfs_call_disconnect ( struct vfs_handle_struct * handle )
{
VFS_FIND ( disconnect ) ;
2011-12-04 08:45:04 +04:00
handle - > fns - > disconnect_fn ( handle ) ;
2009-07-24 04:28:58 +04:00
}
uint64_t smb_vfs_call_disk_free ( struct vfs_handle_struct * handle ,
2017-05-23 20:40:47 +03:00
const struct smb_filename * smb_fname ,
uint64_t * bsize ,
uint64_t * dfree ,
uint64_t * dsize )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( disk_free ) ;
2017-05-23 20:40:47 +03:00
return handle - > fns - > disk_free_fn ( handle , smb_fname ,
bsize , dfree , dsize ) ;
2009-07-24 04:28:58 +04:00
}
2017-06-01 21:45:25 +03:00
int smb_vfs_call_get_quota ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
enum SMB_QUOTA_TYPE qtype ,
unid_t id ,
SMB_DISK_QUOTA * qt )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( get_quota ) ;
2017-06-01 21:45:25 +03:00
return handle - > fns - > get_quota_fn ( handle , smb_fname , qtype , id , qt ) ;
2009-07-24 04:28:58 +04:00
}
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > set_quota_fn ( handle , qtype , id , qt ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_get_shadow_copy_data ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
2011-05-30 14:06:31 +04:00
struct shadow_copy_data * shadow_copy_data ,
2009-07-24 04:28:58 +04:00
bool labels )
{
VFS_FIND ( get_shadow_copy_data ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > get_shadow_copy_data_fn ( handle , fsp ,
shadow_copy_data ,
labels ) ;
2009-07-24 04:28:58 +04:00
}
2017-06-03 01:26:06 +03:00
int smb_vfs_call_statvfs ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
struct vfs_statvfs_struct * statbuf )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( statvfs ) ;
2017-06-03 01:26:06 +03:00
return handle - > fns - > statvfs_fn ( handle , smb_fname , statbuf ) ;
2009-07-24 04:28:58 +04:00
}
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fs_capabilities_fn ( handle , p_ts_res ) ;
2009-07-24 04:28:58 +04:00
}
2011-10-01 08:57:18 +04:00
NTSTATUS smb_vfs_call_get_dfs_referrals ( struct vfs_handle_struct * handle ,
struct dfs_GetDFSReferral * r )
{
VFS_FIND ( get_dfs_referrals ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > get_dfs_referrals_fn ( handle , r ) ;
2011-10-01 08:57:18 +04:00
}
2020-01-09 21:13:14 +03:00
NTSTATUS smb_vfs_call_create_dfs_pathat ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
const struct referral * reflist ,
size_t referral_count )
{
VFS_FIND ( create_dfs_pathat ) ;
return handle - > fns - > create_dfs_pathat_fn ( handle ,
dirfsp ,
smb_fname ,
reflist ,
referral_count ) ;
}
2020-01-28 20:51:17 +03:00
NTSTATUS smb_vfs_call_read_dfs_pathat ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct files_struct * dirfsp ,
2020-05-30 02:32:12 +03:00
struct smb_filename * smb_fname ,
2020-01-28 20:51:17 +03:00
struct referral * * ppreflist ,
size_t * preferral_count )
{
VFS_FIND ( read_dfs_pathat ) ;
return handle - > fns - > read_dfs_pathat_fn ( handle ,
mem_ctx ,
dirfsp ,
smb_fname ,
ppreflist ,
preferral_count ) ;
}
2012-03-28 06:22:03 +04:00
DIR * smb_vfs_call_fdopendir ( struct vfs_handle_struct * handle ,
2011-02-09 02:07:48 +03:00
struct files_struct * fsp ,
const char * mask ,
2015-04-14 02:56:09 +03:00
uint32_t attributes )
2011-02-09 02:07:48 +03:00
{
VFS_FIND ( fdopendir ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fdopendir_fn ( handle , fsp , mask , attributes ) ;
2011-02-09 02:07:48 +03:00
}
2012-03-28 06:18:14 +04:00
struct dirent * smb_vfs_call_readdir ( struct vfs_handle_struct * handle ,
2020-11-22 15:57:27 +03:00
struct files_struct * dirfsp ,
2023-06-20 13:42:52 +03:00
DIR * dirp )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( readdir ) ;
2023-06-20 13:42:52 +03:00
return handle - > fns - > readdir_fn ( handle , dirfsp , dirp ) ;
2009-07-24 04:28:58 +04:00
}
void smb_vfs_call_rewind_dir ( struct vfs_handle_struct * handle ,
2012-03-28 06:22:03 +04:00
DIR * dirp )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( rewind_dir ) ;
2011-12-04 08:45:04 +04:00
handle - > fns - > rewind_dir_fn ( handle , dirp ) ;
2009-07-24 04:28:58 +04:00
}
2019-09-04 22:20:46 +03:00
int smb_vfs_call_mkdirat ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
mode_t mode )
{
VFS_FIND ( mkdirat ) ;
return handle - > fns - > mkdirat_fn ( handle ,
dirfsp ,
smb_fname ,
mode ) ;
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_closedir ( struct vfs_handle_struct * handle ,
2012-03-28 06:22:03 +04:00
DIR * dir )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( closedir ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > closedir_fn ( handle , dir ) ;
2009-07-24 04:28:58 +04:00
}
2020-05-15 17:29:44 +03:00
int smb_vfs_call_openat ( struct vfs_handle_struct * handle ,
const struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
struct files_struct * fsp ,
2022-06-03 16:53:29 +03:00
const struct vfs_open_how * how )
2020-05-15 17:29:44 +03:00
{
VFS_FIND ( openat ) ;
return handle - > fns - > openat_fn ( handle ,
dirfsp ,
smb_fname ,
fsp ,
2022-06-03 16:53:29 +03:00
how ) ;
2020-05-15 17:29:44 +03:00
}
2009-07-24 04:28:58 +04:00
NTSTATUS smb_vfs_call_create_file ( struct vfs_handle_struct * handle ,
struct smb_request * req ,
2021-11-23 14:29:17 +03:00
struct files_struct * dirfsp ,
2009-07-24 04:28:58 +04:00
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 ,
2019-08-07 23:00:11 +03:00
const struct smb2_lease * lease ,
2009-07-24 04:28:58 +04:00
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 ,
2014-11-26 16:12:51 +03:00
int * pinfo ,
const struct smb2_create_blobs * in_context_blobs ,
struct smb2_create_blobs * out_context_blobs )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( create_file ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > create_file_fn (
2021-11-23 14:29:17 +03:00
handle , req , dirfsp , smb_fname ,
2020-05-14 15:00:22 +03:00
access_mask , share_access , create_disposition , create_options ,
2013-08-21 17:56:14 +04:00
file_attributes , oplock_request , lease , allocation_size ,
2010-03-06 02:10:30 +03:00
private_flags , sd , ea_list ,
2014-11-26 16:12:51 +03:00
result , pinfo , in_context_blobs , out_context_blobs ) ;
2009-07-24 04:28:58 +04:00
}
2011-12-04 08:45:04 +04:00
int smb_vfs_call_close ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
2009-07-24 04:28:58 +04:00
{
2011-12-04 08:45:04 +04:00
VFS_FIND ( close ) ;
2009-07-24 04:28:58 +04:00
return handle - > fns - > close_fn ( handle , fsp ) ;
}
ssize_t smb_vfs_call_pread ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , void * data , size_t n ,
2012-04-05 08:53:08 +04:00
off_t offset )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( pread ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > pread_fn ( handle , fsp , data , n , offset ) ;
2009-07-24 04:28:58 +04:00
}
2012-06-26 16:30:59 +04:00
struct smb_vfs_call_pread_state {
2016-02-26 12:54:01 +03:00
ssize_t ( * recv_fn ) ( struct tevent_req * req , struct vfs_aio_state * vfs_aio_state ) ;
2012-06-26 16:30:59 +04:00
ssize_t retval ;
2016-02-26 12:54:01 +03:00
struct vfs_aio_state vfs_aio_state ;
2012-06-26 16:30:59 +04:00
} ;
static void smb_vfs_call_pread_done ( struct tevent_req * subreq ) ;
struct tevent_req * smb_vfs_call_pread_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp ,
void * data ,
size_t n , off_t offset )
{
struct tevent_req * req , * subreq ;
struct smb_vfs_call_pread_state * state ;
req = tevent_req_create ( mem_ctx , & state ,
struct smb_vfs_call_pread_state ) ;
if ( req = = NULL ) {
return NULL ;
}
VFS_FIND ( pread_send ) ;
state - > recv_fn = handle - > fns - > pread_recv_fn ;
subreq = handle - > fns - > pread_send_fn ( handle , state , ev , fsp , data , n ,
offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , smb_vfs_call_pread_done , req ) ;
return req ;
}
static void smb_vfs_call_pread_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct smb_vfs_call_pread_state * state = tevent_req_data (
req , struct smb_vfs_call_pread_state ) ;
2016-02-26 12:54:01 +03:00
state - > retval = state - > recv_fn ( subreq , & state - > vfs_aio_state ) ;
2012-06-26 16:30:59 +04:00
TALLOC_FREE ( subreq ) ;
if ( state - > retval = = - 1 ) {
2016-02-26 12:54:01 +03:00
tevent_req_error ( req , state - > vfs_aio_state . error ) ;
2012-06-26 16:30:59 +04:00
return ;
}
tevent_req_done ( req ) ;
}
2016-02-26 12:54:01 +03:00
ssize_t SMB_VFS_PREAD_RECV ( struct tevent_req * req ,
struct vfs_aio_state * vfs_aio_state )
2012-06-26 16:30:59 +04:00
{
struct smb_vfs_call_pread_state * state = tevent_req_data (
req , struct smb_vfs_call_pread_state ) ;
2018-08-29 05:24:46 +03:00
ssize_t retval ;
2012-06-26 16:30:59 +04:00
2016-02-26 12:54:01 +03:00
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
2018-07-12 15:43:55 +03:00
tevent_req_received ( req ) ;
2012-06-26 16:30:59 +04:00
return - 1 ;
}
2016-02-26 12:54:01 +03:00
* vfs_aio_state = state - > vfs_aio_state ;
2018-08-29 05:24:46 +03:00
retval = state - > retval ;
2018-07-12 15:43:55 +03:00
tevent_req_received ( req ) ;
2018-08-29 05:24:46 +03:00
return retval ;
2012-06-26 16:30:59 +04:00
}
2009-07-24 04:28:58 +04:00
ssize_t smb_vfs_call_pwrite ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const void * data ,
2012-04-05 08:53:08 +04:00
size_t n , off_t offset )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( pwrite ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > pwrite_fn ( handle , fsp , data , n , offset ) ;
2009-07-24 04:28:58 +04:00
}
2012-06-26 16:30:59 +04:00
struct smb_vfs_call_pwrite_state {
2016-02-26 12:54:01 +03:00
ssize_t ( * recv_fn ) ( struct tevent_req * req , struct vfs_aio_state * vfs_aio_state ) ;
2012-06-26 16:30:59 +04:00
ssize_t retval ;
2016-02-26 12:54:01 +03:00
struct vfs_aio_state vfs_aio_state ;
2012-06-26 16:30:59 +04:00
} ;
static void smb_vfs_call_pwrite_done ( struct tevent_req * subreq ) ;
struct tevent_req * smb_vfs_call_pwrite_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp ,
const void * data ,
size_t n , off_t offset )
{
struct tevent_req * req , * subreq ;
struct smb_vfs_call_pwrite_state * state ;
req = tevent_req_create ( mem_ctx , & state ,
struct smb_vfs_call_pwrite_state ) ;
if ( req = = NULL ) {
return NULL ;
}
VFS_FIND ( pwrite_send ) ;
state - > recv_fn = handle - > fns - > pwrite_recv_fn ;
subreq = handle - > fns - > pwrite_send_fn ( handle , state , ev , fsp , data , n ,
offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , smb_vfs_call_pwrite_done , req ) ;
return req ;
}
static void smb_vfs_call_pwrite_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct smb_vfs_call_pwrite_state * state = tevent_req_data (
req , struct smb_vfs_call_pwrite_state ) ;
2016-02-26 12:54:01 +03:00
state - > retval = state - > recv_fn ( subreq , & state - > vfs_aio_state ) ;
2012-06-26 16:30:59 +04:00
TALLOC_FREE ( subreq ) ;
if ( state - > retval = = - 1 ) {
2016-02-26 12:54:01 +03:00
tevent_req_error ( req , state - > vfs_aio_state . error ) ;
2012-06-26 16:30:59 +04:00
return ;
}
tevent_req_done ( req ) ;
}
2016-02-26 12:54:01 +03:00
ssize_t SMB_VFS_PWRITE_RECV ( struct tevent_req * req ,
struct vfs_aio_state * vfs_aio_state )
2012-06-26 16:30:59 +04:00
{
struct smb_vfs_call_pwrite_state * state = tevent_req_data (
req , struct smb_vfs_call_pwrite_state ) ;
2018-08-29 05:24:46 +03:00
ssize_t retval ;
2012-06-26 16:30:59 +04:00
2016-02-26 12:54:01 +03:00
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
2018-07-12 15:44:27 +03:00
tevent_req_received ( req ) ;
2012-06-26 16:30:59 +04:00
return - 1 ;
}
2016-02-26 12:54:01 +03:00
* vfs_aio_state = state - > vfs_aio_state ;
2018-08-29 05:24:46 +03:00
retval = state - > retval ;
2018-07-12 15:44:27 +03:00
tevent_req_received ( req ) ;
2018-08-29 05:24:46 +03:00
return retval ;
2012-06-26 16:30:59 +04:00
}
2012-04-05 08:53:08 +04:00
off_t smb_vfs_call_lseek ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , off_t offset ,
2009-07-24 04:28:58 +04:00
int whence )
{
VFS_FIND ( lseek ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > lseek_fn ( handle , fsp , offset , whence ) ;
2009-07-24 04:28:58 +04:00
}
ssize_t smb_vfs_call_sendfile ( struct vfs_handle_struct * handle , int tofd ,
files_struct * fromfsp , const DATA_BLOB * header ,
2012-04-05 08:53:08 +04:00
off_t offset , size_t count )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( sendfile ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > sendfile_fn ( handle , tofd , fromfsp , header , offset ,
count ) ;
2009-07-24 04:28:58 +04:00
}
ssize_t smb_vfs_call_recvfile ( struct vfs_handle_struct * handle , int fromfd ,
2012-04-05 08:53:08 +04:00
files_struct * tofsp , off_t offset ,
2009-07-24 04:28:58 +04:00
size_t count )
{
VFS_FIND ( recvfile ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > recvfile_fn ( handle , fromfd , tofsp , offset , count ) ;
2009-07-24 04:28:58 +04:00
}
2019-08-09 01:22:31 +03:00
int smb_vfs_call_renameat ( struct vfs_handle_struct * handle ,
files_struct * srcfsp ,
const struct smb_filename * smb_fname_src ,
files_struct * dstfsp ,
2024-08-06 14:21:34 +03:00
const struct smb_filename * smb_fname_dst ,
const struct vfs_rename_how * how )
2019-08-09 01:22:31 +03:00
{
VFS_FIND ( renameat ) ;
return handle - > fns - > renameat_fn ( handle ,
srcfsp ,
smb_fname_src ,
dstfsp ,
2024-08-06 14:21:34 +03:00
smb_fname_dst ,
how ) ;
2009-07-24 04:28:58 +04:00
}
2012-07-13 12:22:25 +04:00
struct smb_vfs_call_fsync_state {
2016-02-26 12:54:01 +03:00
int ( * recv_fn ) ( struct tevent_req * req , struct vfs_aio_state * vfs_aio_state ) ;
2012-07-13 12:22:25 +04:00
int retval ;
2016-02-26 12:54:01 +03:00
struct vfs_aio_state vfs_aio_state ;
2012-07-13 12:22:25 +04:00
} ;
static void smb_vfs_call_fsync_done ( struct tevent_req * subreq ) ;
struct tevent_req * smb_vfs_call_fsync_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp )
{
struct tevent_req * req , * subreq ;
struct smb_vfs_call_fsync_state * state ;
req = tevent_req_create ( mem_ctx , & state ,
struct smb_vfs_call_fsync_state ) ;
if ( req = = NULL ) {
return NULL ;
}
VFS_FIND ( fsync_send ) ;
state - > recv_fn = handle - > fns - > fsync_recv_fn ;
subreq = handle - > fns - > fsync_send_fn ( handle , state , ev , fsp ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , smb_vfs_call_fsync_done , req ) ;
return req ;
}
static void smb_vfs_call_fsync_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct smb_vfs_call_fsync_state * state = tevent_req_data (
req , struct smb_vfs_call_fsync_state ) ;
2016-02-26 12:54:01 +03:00
state - > retval = state - > recv_fn ( subreq , & state - > vfs_aio_state ) ;
2012-07-13 12:22:25 +04:00
TALLOC_FREE ( subreq ) ;
if ( state - > retval = = - 1 ) {
2016-02-26 12:54:01 +03:00
tevent_req_error ( req , state - > vfs_aio_state . error ) ;
2012-07-13 12:22:25 +04:00
return ;
}
tevent_req_done ( req ) ;
}
2016-02-26 12:54:01 +03:00
int SMB_VFS_FSYNC_RECV ( struct tevent_req * req , struct vfs_aio_state * vfs_aio_state )
2012-07-13 12:22:25 +04:00
{
struct smb_vfs_call_fsync_state * state = tevent_req_data (
req , struct smb_vfs_call_fsync_state ) ;
2018-08-29 05:24:46 +03:00
ssize_t retval ;
2012-07-13 12:22:25 +04:00
2016-02-26 12:54:01 +03:00
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
2018-07-12 15:44:40 +03:00
tevent_req_received ( req ) ;
2012-07-13 12:22:25 +04:00
return - 1 ;
}
2016-02-26 12:54:01 +03:00
* vfs_aio_state = state - > vfs_aio_state ;
2018-08-29 05:24:46 +03:00
retval = state - > retval ;
2018-07-12 15:44:40 +03:00
tevent_req_received ( req ) ;
2018-08-29 05:24:46 +03:00
return retval ;
2012-07-13 12:22:25 +04:00
}
2018-04-28 02:59:02 +03:00
/*
* Synchronous version of fsync , built from backend
* async VFS primitives . Uses a temporary sub - event
* context ( NOT NESTED ) .
*/
int smb_vfs_fsync_sync ( files_struct * fsp )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct tevent_req * req = NULL ;
struct vfs_aio_state aio_state = { 0 } ;
int ret = - 1 ;
bool ok ;
struct tevent_context * ev = samba_tevent_context_init ( frame ) ;
if ( ev = = NULL ) {
goto out ;
}
req = SMB_VFS_FSYNC_SEND ( talloc_tos ( ) , ev , fsp ) ;
if ( req = = NULL ) {
goto out ;
}
ok = tevent_req_poll ( req , ev ) ;
if ( ! ok ) {
goto out ;
}
ret = SMB_VFS_FSYNC_RECV ( req , & aio_state ) ;
out :
TALLOC_FREE ( frame ) ;
if ( aio_state . error ! = 0 ) {
errno = aio_state . error ;
}
return ret ;
}
2012-07-13 12:22:25 +04:00
2009-07-24 04:28:58 +04:00
int smb_vfs_call_stat ( struct vfs_handle_struct * handle ,
struct smb_filename * smb_fname )
{
VFS_FIND ( stat ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > stat_fn ( handle , smb_fname ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_fstat ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( fstat ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fstat_fn ( handle , fsp , sbuf ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_lstat ( struct vfs_handle_struct * handle ,
struct smb_filename * smb_filename )
{
VFS_FIND ( lstat ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > lstat_fn ( handle , smb_filename ) ;
2009-07-24 04:28:58 +04:00
}
2022-01-06 17:59:05 +03:00
int smb_vfs_call_fstatat (
struct vfs_handle_struct * handle ,
const struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
SMB_STRUCT_STAT * sbuf ,
int flags )
{
VFS_FIND ( fstatat ) ;
return handle - > fns - > fstatat_fn ( handle , dirfsp , smb_fname , sbuf , flags ) ;
}
2009-07-24 04:28:58 +04:00
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > get_alloc_size_fn ( handle , fsp , sbuf ) ;
2009-07-24 04:28:58 +04:00
}
2019-09-12 00:37:31 +03:00
int smb_vfs_call_unlinkat ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
int flags )
{
VFS_FIND ( unlinkat ) ;
return handle - > fns - > unlinkat_fn ( handle ,
dirfsp ,
smb_fname ,
flags ) ;
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_fchmod ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , mode_t mode )
{
VFS_FIND ( fchmod ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fchmod_fn ( handle , fsp , mode ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_fchown ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , uid_t uid , gid_t gid )
{
VFS_FIND ( fchown ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fchown_fn ( handle , fsp , uid , gid ) ;
2009-07-24 04:28:58 +04:00
}
2016-03-04 01:34:57 +03:00
int smb_vfs_call_lchown ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
uid_t uid ,
gid_t gid )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( lchown ) ;
2016-03-04 01:34:57 +03:00
return handle - > fns - > lchown_fn ( handle , smb_fname , uid , gid ) ;
2009-07-24 04:28:58 +04:00
}
2017-06-29 21:29:33 +03:00
int smb_vfs_call_chdir ( struct vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( chdir ) ;
2017-06-29 21:29:33 +03:00
return handle - > fns - > chdir_fn ( handle , smb_fname ) ;
2009-07-24 04:28:58 +04:00
}
2017-06-30 00:32:47 +03:00
struct smb_filename * smb_vfs_call_getwd ( struct vfs_handle_struct * handle ,
TALLOC_CTX * ctx )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( getwd ) ;
2017-06-30 00:32:47 +03:00
return handle - > fns - > getwd_fn ( handle , ctx ) ;
2009-07-24 04:28:58 +04:00
}
2021-04-13 13:07:52 +03:00
int smb_vfs_call_fntimes ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct smb_file_time * ft )
{
VFS_FIND ( fntimes ) ;
return handle - > fns - > fntimes_fn ( handle , fsp , ft ) ;
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_ftruncate ( struct vfs_handle_struct * handle ,
2012-04-05 08:53:08 +04:00
struct files_struct * fsp , off_t offset )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( ftruncate ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > ftruncate_fn ( handle , fsp , offset ) ;
2009-07-24 04:28:58 +04:00
}
2010-12-18 10:08:01 +03:00
int smb_vfs_call_fallocate ( struct vfs_handle_struct * handle ,
2015-02-09 20:21:59 +03:00
struct files_struct * fsp ,
uint32_t mode ,
off_t offset ,
off_t len )
2010-12-03 03:25:59 +03:00
{
2010-12-18 10:08:01 +03:00
VFS_FIND ( fallocate ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fallocate_fn ( handle , fsp , mode , offset , len ) ;
2010-12-03 03:25:59 +03:00
}
2021-09-21 00:51:02 +03:00
int smb_vfs_call_filesystem_sharemode ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t share_mode ,
uint32_t access_mask )
{
VFS_FIND ( filesystem_sharemode ) ;
return handle - > fns - > filesystem_sharemode_fn ( handle ,
fsp ,
share_mode ,
access_mask ) ;
2009-07-24 04:28:58 +04:00
}
2019-09-27 08:49:37 +03:00
int smb_vfs_call_fcntl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , int cmd , . . . )
{
int result ;
va_list cmd_arg ;
VFS_FIND ( fcntl ) ;
va_start ( cmd_arg , cmd ) ;
result = handle - > fns - > fcntl_fn ( handle , fsp , cmd , cmd_arg ) ;
va_end ( cmd_arg ) ;
return result ;
}
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > linux_setlease_fn ( handle , fsp , leasetype ) ;
2009-07-24 04:28:58 +04:00
}
2019-08-30 22:01:13 +03:00
int smb_vfs_call_symlinkat ( struct vfs_handle_struct * handle ,
2020-04-30 20:30:50 +03:00
const struct smb_filename * link_target ,
2019-08-22 23:42:26 +03:00
struct files_struct * dirfsp ,
2019-08-30 22:01:13 +03:00
const struct smb_filename * new_smb_fname )
{
VFS_FIND ( symlinkat ) ;
return handle - > fns - > symlinkat_fn ( handle ,
link_target ,
dirfsp ,
new_smb_fname ) ;
}
int smb_vfs_call_readlinkat ( struct vfs_handle_struct * handle ,
2020-10-13 16:19:30 +03:00
const struct files_struct * dirfsp ,
2019-08-22 23:42:26 +03:00
const struct smb_filename * smb_fname ,
char * buf ,
size_t bufsiz )
{
VFS_FIND ( readlinkat ) ;
return handle - > fns - > readlinkat_fn ( handle ,
dirfsp ,
smb_fname ,
buf ,
bufsiz ) ;
}
2019-08-13 02:49:26 +03:00
int smb_vfs_call_linkat ( struct vfs_handle_struct * handle ,
struct files_struct * srcfsp ,
const struct smb_filename * old_smb_fname ,
struct files_struct * dstfsp ,
const struct smb_filename * new_smb_fname ,
int flags )
{
VFS_FIND ( linkat ) ;
return handle - > fns - > linkat_fn ( handle ,
srcfsp ,
old_smb_fname ,
dstfsp ,
new_smb_fname ,
flags ) ;
}
2019-08-21 02:31:00 +03:00
int smb_vfs_call_mknodat ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
mode_t mode ,
SMB_DEV_T dev )
{
VFS_FIND ( mknodat ) ;
return handle - > fns - > mknodat_fn ( handle ,
dirfsp ,
smb_fname ,
mode ,
dev ) ;
}
2017-06-30 21:32:59 +03:00
struct smb_filename * smb_vfs_call_realpath ( struct vfs_handle_struct * handle ,
TALLOC_CTX * ctx ,
const struct smb_filename * smb_fname )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( realpath ) ;
2017-06-30 21:32:59 +03:00
return handle - > fns - > realpath_fn ( handle , ctx , smb_fname ) ;
2009-07-24 04:28:58 +04:00
}
2021-06-10 18:31:40 +03:00
int smb_vfs_call_fchflags ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
unsigned int flags )
{
VFS_FIND ( fchflags ) ;
return handle - > fns - > fchflags_fn ( handle , fsp , flags ) ;
}
2009-07-24 04:28:58 +04:00
struct file_id smb_vfs_call_file_id_create ( struct vfs_handle_struct * handle ,
const SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( file_id_create ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > file_id_create_fn ( handle , sbuf ) ;
2009-07-24 04:28:58 +04:00
}
2019-06-29 15:08:04 +03:00
uint64_t smb_vfs_call_fs_file_id ( struct vfs_handle_struct * handle ,
const SMB_STRUCT_STAT * sbuf )
{
VFS_FIND ( fs_file_id ) ;
return handle - > fns - > fs_file_id_fn ( handle , sbuf ) ;
}
2021-05-08 02:11:46 +03:00
NTSTATUS smb_vfs_call_fstreaminfo ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
unsigned int * num_streams ,
struct stream_struct * * streams )
{
VFS_FIND ( fstreaminfo ) ;
return handle - > fns - > fstreaminfo_fn ( handle , fsp , mem_ctx ,
num_streams , streams ) ;
}
2022-03-13 14:15:59 +03:00
NTSTATUS smb_vfs_call_get_real_filename_at ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const char * name ,
TALLOC_CTX * mem_ctx ,
char * * found_name )
{
VFS_FIND ( get_real_filename_at ) ;
return handle - > fns - > get_real_filename_at_fn (
handle , dirfsp , name , mem_ctx , found_name ) ;
}
2009-07-24 04:28:58 +04:00
const char * smb_vfs_call_connectpath ( struct vfs_handle_struct * handle ,
2022-09-15 06:18:33 +03:00
const struct files_struct * dirfsp ,
2017-06-30 23:37:03 +03:00
const struct smb_filename * smb_fname )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( connectpath ) ;
2022-09-15 06:18:33 +03:00
return handle - > fns - > connectpath_fn ( handle , dirfsp , smb_fname ) ;
2009-07-24 04:28:58 +04:00
}
2017-07-09 15:34:10 +03:00
bool smb_vfs_call_strict_lock_check ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct lock_struct * plock )
2009-07-24 04:28:58 +04:00
{
2017-07-09 15:34:10 +03:00
VFS_FIND ( strict_lock_check ) ;
return handle - > fns - > strict_lock_check_fn ( 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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > translate_name_fn ( handle , name , direction , mem_ctx ,
mapped_name ) ;
2009-08-27 01:56:09 +04:00
}
2021-05-26 20:39:43 +03:00
NTSTATUS smb_vfs_call_parent_pathname ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
const struct smb_filename * smb_fname_in ,
struct smb_filename * * parent_dir_out ,
struct smb_filename * * atname_out )
{
VFS_FIND ( parent_pathname ) ;
return handle - > fns - > parent_pathname_fn ( handle ,
mem_ctx ,
smb_fname_in ,
parent_dir_out ,
atname_out ) ;
}
2011-09-16 22:52:22 +04:00
NTSTATUS smb_vfs_call_fsctl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
TALLOC_CTX * ctx ,
uint32_t function ,
uint16_t req_flags ,
const uint8_t * in_data ,
uint32_t in_len ,
uint8_t * * out_data ,
uint32_t max_out_len ,
uint32_t * out_len )
{
VFS_FIND ( fsctl ) ;
2013-01-15 20:22:59 +04:00
return handle - > fns - > fsctl_fn ( handle , fsp , ctx , function , req_flags ,
in_data , in_len , out_data , max_out_len ,
2011-12-04 08:45:04 +04:00
out_len ) ;
2016-03-20 22:51:32 +03:00
}
NTSTATUS smb_vfs_call_fget_dos_attributes ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t * dosmode )
{
VFS_FIND ( fget_dos_attributes ) ;
return handle - > fns - > fget_dos_attributes_fn ( handle , fsp , dosmode ) ;
}
NTSTATUS smb_vfs_call_fset_dos_attributes ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t dosmode )
{
2021-03-03 14:29:43 +03:00
VFS_FIND ( fset_dos_attributes ) ;
2016-03-20 22:51:32 +03:00
return handle - > fns - > fset_dos_attributes_fn ( handle , fsp , dosmode ) ;
}
2017-06-03 13:57:59 +03:00
struct tevent_req * smb_vfs_call_offload_read_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t fsctl ,
uint32_t ttl ,
off_t offset ,
size_t to_copy )
{
VFS_FIND ( offload_read_send ) ;
return handle - > fns - > offload_read_send_fn ( mem_ctx , ev , handle ,
fsp , fsctl ,
ttl , offset , to_copy ) ;
}
NTSTATUS smb_vfs_call_offload_read_recv ( struct tevent_req * req ,
struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
2021-06-22 21:13:02 +03:00
uint32_t * flags ,
uint64_t * xferlen ,
2017-06-03 13:57:59 +03:00
DATA_BLOB * token_blob )
{
VFS_FIND ( offload_read_recv ) ;
2021-06-22 21:13:02 +03:00
return handle - > fns - > offload_read_recv_fn ( req , handle , mem_ctx , flags , xferlen , token_blob ) ;
2017-06-03 13:57:59 +03:00
}
2017-06-04 14:50:33 +03:00
struct tevent_req * smb_vfs_call_offload_write_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
2017-06-09 14:02:49 +03:00
uint32_t fsctl ,
DATA_BLOB * token ,
off_t transfer_offset ,
2017-06-04 14:50:33 +03:00
struct files_struct * dest_fsp ,
off_t dest_off ,
2017-06-10 10:05:55 +03:00
off_t num )
2017-06-04 14:50:33 +03:00
{
VFS_FIND ( offload_write_send ) ;
2017-06-09 14:02:49 +03:00
return handle - > fns - > offload_write_send_fn ( handle , mem_ctx , ev , fsctl ,
token , transfer_offset ,
2017-06-10 10:05:55 +03:00
dest_fsp , dest_off , num ) ;
2013-01-15 20:22:59 +04:00
}
2017-06-04 14:50:33 +03:00
NTSTATUS smb_vfs_call_offload_write_recv ( struct vfs_handle_struct * handle ,
struct tevent_req * req ,
off_t * copied )
2013-01-15 20:22:59 +04:00
{
2017-06-04 14:50:33 +03:00
VFS_FIND ( offload_write_recv ) ;
return handle - > fns - > offload_write_recv_fn ( handle , req , copied ) ;
2013-01-15 20:22:59 +04:00
}
2018-03-15 15:08:55 +03:00
struct smb_vfs_call_get_dos_attributes_state {
2019-01-14 15:51:23 +03:00
files_struct * dir_fsp ;
2018-03-15 15:08:55 +03:00
NTSTATUS ( * recv_fn ) ( struct tevent_req * req ,
struct vfs_aio_state * aio_state ,
uint32_t * dosmode ) ;
struct vfs_aio_state aio_state ;
uint32_t dos_attributes ;
} ;
static void smb_vfs_call_get_dos_attributes_done ( struct tevent_req * subreq ) ;
struct tevent_req * smb_vfs_call_get_dos_attributes_send (
TALLOC_CTX * mem_ctx ,
2018-12-28 14:12:20 +03:00
struct tevent_context * ev ,
2018-03-15 15:08:55 +03:00
struct vfs_handle_struct * handle ,
files_struct * dir_fsp ,
struct smb_filename * smb_fname )
{
struct tevent_req * req = NULL ;
struct smb_vfs_call_get_dos_attributes_state * state = NULL ;
struct tevent_req * subreq = NULL ;
req = tevent_req_create ( mem_ctx , & state ,
struct smb_vfs_call_get_dos_attributes_state ) ;
if ( req = = NULL ) {
return NULL ;
}
VFS_FIND ( get_dos_attributes_send ) ;
2019-01-14 15:50:31 +03:00
* state = ( struct smb_vfs_call_get_dos_attributes_state ) {
2019-01-14 15:51:23 +03:00
. dir_fsp = dir_fsp ,
2019-01-14 15:50:31 +03:00
. recv_fn = handle - > fns - > get_dos_attributes_recv_fn ,
} ;
2018-03-15 15:08:55 +03:00
subreq = handle - > fns - > get_dos_attributes_send_fn ( mem_ctx ,
2018-12-28 14:12:20 +03:00
ev ,
2018-03-15 15:08:55 +03:00
handle ,
dir_fsp ,
smb_fname ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
2018-12-28 14:12:20 +03:00
return tevent_req_post ( req , ev ) ;
2018-03-15 15:08:55 +03:00
}
2018-12-28 14:12:20 +03:00
tevent_req_defer_callback ( req , ev ) ;
2018-03-15 15:08:55 +03:00
tevent_req_set_callback ( subreq ,
smb_vfs_call_get_dos_attributes_done ,
req ) ;
return req ;
}
static void smb_vfs_call_get_dos_attributes_done ( struct tevent_req * subreq )
{
struct tevent_req * req =
tevent_req_callback_data ( subreq ,
struct tevent_req ) ;
struct smb_vfs_call_get_dos_attributes_state * state =
tevent_req_data ( req ,
struct smb_vfs_call_get_dos_attributes_state ) ;
NTSTATUS status ;
2019-01-14 15:51:23 +03:00
bool ok ;
/*
* Make sure we run as the user again
*/
2019-07-13 17:20:11 +03:00
ok = change_to_user_and_service_by_fsp ( state - > dir_fsp ) ;
2019-01-14 15:51:23 +03:00
SMB_ASSERT ( ok ) ;
2018-03-15 15:08:55 +03:00
status = state - > recv_fn ( subreq ,
& state - > aio_state ,
& state - > dos_attributes ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
return ;
}
tevent_req_done ( req ) ;
}
NTSTATUS smb_vfs_call_get_dos_attributes_recv (
struct tevent_req * req ,
struct vfs_aio_state * aio_state ,
uint32_t * dos_attributes )
{
struct smb_vfs_call_get_dos_attributes_state * state =
tevent_req_data ( req ,
struct smb_vfs_call_get_dos_attributes_state ) ;
NTSTATUS status ;
if ( tevent_req_is_nterror ( req , & status ) ) {
tevent_req_received ( req ) ;
return status ;
}
* aio_state = state - > aio_state ;
* dos_attributes = state - > dos_attributes ;
tevent_req_received ( req ) ;
return NT_STATUS_OK ;
}
2020-10-13 13:02:34 +03:00
NTSTATUS smb_vfs_call_fget_compression ( vfs_handle_struct * handle ,
2013-11-18 17:54:30 +04:00
TALLOC_CTX * mem_ctx ,
struct files_struct * fsp ,
uint16_t * _compression_fmt )
{
2020-10-13 13:02:34 +03:00
VFS_FIND ( fget_compression ) ;
return handle - > fns - > fget_compression_fn ( handle , mem_ctx , fsp ,
2013-11-18 17:54:30 +04:00
_compression_fmt ) ;
}
NTSTATUS smb_vfs_call_set_compression ( vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct files_struct * fsp ,
uint16_t compression_fmt )
{
VFS_FIND ( set_compression ) ;
return handle - > fns - > set_compression_fn ( handle , mem_ctx , fsp ,
compression_fmt ) ;
}
2012-04-10 05:16:57 +04:00
NTSTATUS smb_vfs_call_snap_check_path ( vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
const char * service_path ,
char * * base_volume )
{
VFS_FIND ( snap_check_path ) ;
return handle - > fns - > snap_check_path_fn ( handle , mem_ctx , service_path ,
base_volume ) ;
}
NTSTATUS smb_vfs_call_snap_create ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
const char * base_volume ,
time_t * tstamp ,
bool rw ,
char * * base_path ,
char * * snap_path )
{
VFS_FIND ( snap_create ) ;
return handle - > fns - > snap_create_fn ( handle , mem_ctx , base_volume , tstamp ,
rw , base_path , snap_path ) ;
}
NTSTATUS smb_vfs_call_snap_delete ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
char * base_path ,
char * snap_path )
{
VFS_FIND ( snap_delete ) ;
return handle - > fns - > snap_delete_fn ( handle , mem_ctx , base_path ,
snap_path ) ;
}
2009-07-24 04:28:58 +04:00
NTSTATUS smb_vfs_call_fget_nt_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
2015-04-14 02:56:09 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2009-07-24 04:28:58 +04:00
struct security_descriptor * * ppdesc )
{
VFS_FIND ( fget_nt_acl ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fget_nt_acl_fn ( handle , fsp , security_info ,
2012-10-10 04:50:27 +04:00
mem_ctx , ppdesc ) ;
2009-07-24 04:28:58 +04:00
}
NTSTATUS smb_vfs_call_fset_nt_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
2015-04-14 02:56:09 +03:00
uint32_t security_info_sent ,
2009-07-24 04:28:58 +04:00
const struct security_descriptor * psd )
{
VFS_FIND ( fset_nt_acl ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fset_nt_acl_fn ( handle , fsp , security_info_sent ,
psd ) ;
2009-07-24 04:28:58 +04:00
}
2012-04-28 08:31:34 +04:00
NTSTATUS smb_vfs_call_audit_file ( struct vfs_handle_struct * handle ,
struct smb_filename * file ,
struct security_acl * sacl ,
uint32_t access_requested ,
uint32_t access_denied )
{
VFS_FIND ( audit_file ) ;
return handle - > fns - > audit_file_fn ( handle ,
file ,
sacl ,
access_requested ,
access_denied ) ;
}
2009-07-24 04:28:58 +04:00
SMB_ACL_T smb_vfs_call_sys_acl_get_fd ( struct vfs_handle_struct * handle ,
2012-10-10 03:18:32 +04:00
struct files_struct * fsp ,
2021-05-14 17:26:46 +03:00
SMB_ACL_TYPE_T type ,
2012-10-10 03:18:32 +04:00
TALLOC_CTX * mem_ctx )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( sys_acl_get_fd ) ;
2021-05-14 17:26:46 +03:00
return handle - > fns - > sys_acl_get_fd_fn ( handle , fsp , type , mem_ctx ) ;
2009-07-24 04:28:58 +04:00
}
2012-09-10 06:44:01 +04:00
int smb_vfs_call_sys_acl_blob_get_fd ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
char * * blob_description ,
DATA_BLOB * blob )
{
VFS_FIND ( sys_acl_blob_get_fd ) ;
return handle - > fns - > sys_acl_blob_get_fd_fn ( handle , fsp , mem_ctx , blob_description , blob ) ;
}
2009-07-24 04:28:58 +04:00
int smb_vfs_call_sys_acl_set_fd ( struct vfs_handle_struct * handle ,
2020-12-14 18:28:26 +03:00
struct files_struct * fsp ,
SMB_ACL_TYPE_T type ,
SMB_ACL_T theacl )
2009-07-24 04:28:58 +04:00
{
VFS_FIND ( sys_acl_set_fd ) ;
2020-12-14 18:28:26 +03:00
return handle - > fns - > sys_acl_set_fd_fn ( handle , fsp , type , theacl ) ;
2009-07-24 04:28:58 +04:00
}
2021-05-15 00:20:50 +03:00
int smb_vfs_call_sys_acl_delete_def_fd ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( sys_acl_delete_def_fd ) ;
return handle - > fns - > sys_acl_delete_def_fd_fn ( handle , fsp ) ;
}
2018-03-13 10:14:53 +03:00
struct smb_vfs_call_getxattrat_state {
2019-01-14 15:51:23 +03:00
files_struct * dir_fsp ;
2018-03-13 10:14:53 +03:00
ssize_t ( * recv_fn ) ( struct tevent_req * req ,
struct vfs_aio_state * aio_state ,
TALLOC_CTX * mem_ctx ,
uint8_t * * xattr_value ) ;
ssize_t retval ;
uint8_t * xattr_value ;
struct vfs_aio_state aio_state ;
} ;
static void smb_vfs_call_getxattrat_done ( struct tevent_req * subreq ) ;
struct tevent_req * smb_vfs_call_getxattrat_send (
TALLOC_CTX * mem_ctx ,
2018-12-27 18:32:46 +03:00
struct tevent_context * ev ,
2018-03-13 10:14:53 +03:00
struct vfs_handle_struct * handle ,
files_struct * dir_fsp ,
const struct smb_filename * smb_fname ,
const char * xattr_name ,
size_t alloc_hint )
{
struct tevent_req * req = NULL ;
struct smb_vfs_call_getxattrat_state * state = NULL ;
struct tevent_req * subreq = NULL ;
req = tevent_req_create ( mem_ctx , & state ,
struct smb_vfs_call_getxattrat_state ) ;
if ( req = = NULL ) {
return NULL ;
}
VFS_FIND ( getxattrat_send ) ;
2019-01-14 15:52:51 +03:00
* state = ( struct smb_vfs_call_getxattrat_state ) {
2019-01-14 15:51:23 +03:00
. dir_fsp = dir_fsp ,
2019-01-14 15:52:51 +03:00
. recv_fn = handle - > fns - > getxattrat_recv_fn ,
} ;
2018-03-13 10:14:53 +03:00
subreq = handle - > fns - > getxattrat_send_fn ( mem_ctx ,
2018-12-27 18:32:46 +03:00
ev ,
2018-03-13 10:14:53 +03:00
handle ,
dir_fsp ,
smb_fname ,
xattr_name ,
alloc_hint ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
2018-12-27 18:32:46 +03:00
return tevent_req_post ( req , ev ) ;
2018-03-13 10:14:53 +03:00
}
2018-12-27 18:32:46 +03:00
tevent_req_defer_callback ( req , ev ) ;
2018-03-13 10:14:53 +03:00
tevent_req_set_callback ( subreq , smb_vfs_call_getxattrat_done , req ) ;
return req ;
}
static void smb_vfs_call_getxattrat_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct smb_vfs_call_getxattrat_state * state = tevent_req_data (
req , struct smb_vfs_call_getxattrat_state ) ;
2019-01-14 15:51:23 +03:00
bool ok ;
/*
* Make sure we run as the user again
*/
2019-07-13 17:20:11 +03:00
ok = change_to_user_and_service_by_fsp ( state - > dir_fsp ) ;
2019-01-14 15:51:23 +03:00
SMB_ASSERT ( ok ) ;
2018-03-13 10:14:53 +03:00
state - > retval = state - > recv_fn ( subreq ,
& state - > aio_state ,
state ,
& state - > xattr_value ) ;
TALLOC_FREE ( subreq ) ;
if ( state - > retval = = - 1 ) {
tevent_req_error ( req , state - > aio_state . error ) ;
return ;
}
tevent_req_done ( req ) ;
}
ssize_t smb_vfs_call_getxattrat_recv ( struct tevent_req * req ,
struct vfs_aio_state * aio_state ,
TALLOC_CTX * mem_ctx ,
uint8_t * * xattr_value )
{
struct smb_vfs_call_getxattrat_state * state = tevent_req_data (
req , struct smb_vfs_call_getxattrat_state ) ;
size_t xattr_size ;
if ( tevent_req_is_unix_error ( req , & aio_state - > error ) ) {
tevent_req_received ( req ) ;
return - 1 ;
}
* aio_state = state - > aio_state ;
xattr_size = state - > retval ;
if ( xattr_value ! = NULL ) {
* xattr_value = talloc_move ( mem_ctx , & state - > xattr_value ) ;
}
tevent_req_received ( req ) ;
return xattr_size ;
}
2009-07-24 04:28:58 +04:00
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fgetxattr_fn ( handle , fsp , name , value , size ) ;
2009-07-24 04:28:58 +04:00
}
ssize_t smb_vfs_call_flistxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , char * list ,
size_t size )
{
VFS_FIND ( flistxattr ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > flistxattr_fn ( handle , fsp , list , size ) ;
2009-07-24 04:28:58 +04:00
}
int smb_vfs_call_fremovexattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , const char * name )
{
VFS_FIND ( fremovexattr ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fremovexattr_fn ( handle , fsp , name ) ;
2009-07-24 04:28:58 +04:00
}
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 ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > fsetxattr_fn ( handle , fsp , name , value , size , flags ) ;
2009-07-24 04:28:58 +04:00
}
bool smb_vfs_call_aio_force ( struct vfs_handle_struct * handle ,
struct files_struct * fsp )
{
VFS_FIND ( aio_force ) ;
2011-12-04 08:45:04 +04:00
return handle - > fns - > aio_force_fn ( handle , fsp ) ;
2009-07-24 04:28:58 +04:00
}
2012-09-04 20:04:11 +04:00
NTSTATUS smb_vfs_call_durable_cookie ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
DATA_BLOB * cookie )
{
VFS_FIND ( durable_cookie ) ;
return handle - > fns - > durable_cookie_fn ( handle , fsp , mem_ctx , cookie ) ;
}
NTSTATUS smb_vfs_call_durable_disconnect ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const DATA_BLOB old_cookie ,
TALLOC_CTX * mem_ctx ,
DATA_BLOB * new_cookie )
{
VFS_FIND ( durable_disconnect ) ;
return handle - > fns - > durable_disconnect_fn ( handle , fsp , old_cookie ,
mem_ctx , new_cookie ) ;
}
NTSTATUS smb_vfs_call_durable_reconnect ( struct vfs_handle_struct * handle ,
struct smb_request * smb1req ,
struct smbXsrv_open * op ,
const DATA_BLOB old_cookie ,
TALLOC_CTX * mem_ctx ,
struct files_struct * * fsp ,
DATA_BLOB * new_cookie )
{
VFS_FIND ( durable_reconnect ) ;
return handle - > fns - > durable_reconnect_fn ( handle , smb1req , op ,
old_cookie , mem_ctx , fsp ,
new_cookie ) ;
}
2014-11-26 16:30:37 +03:00
2021-05-10 13:38:58 +03:00
NTSTATUS smb_vfs_call_freaddir_attr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
struct readdir_attr_data * * attr_data )
{
VFS_FIND ( freaddir_attr ) ;
return handle - > fns - > freaddir_attr_fn ( handle ,
fsp ,
mem_ctx ,
attr_data ) ;
}
2022-08-21 16:15:09 +03:00
bool smb_vfs_call_lock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , int op , off_t offset ,
off_t count , int type )
{
VFS_FIND ( lock ) ;
return handle - > fns - > lock_fn ( handle , fsp , op , offset , count , type ) ;
}
bool smb_vfs_call_getlock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp , off_t * poffset ,
off_t * pcount , int * ptype , pid_t * ppid )
{
VFS_FIND ( getlock ) ;
return handle - > fns - > getlock_fn ( handle , fsp , poffset , pcount , ptype ,
ppid ) ;
}
NTSTATUS smb_vfs_call_brl_lock_windows ( struct vfs_handle_struct * handle ,
struct byte_range_lock * br_lck ,
struct lock_struct * plock )
{
VFS_FIND ( brl_lock_windows ) ;
return handle - > fns - > brl_lock_windows_fn ( handle , br_lck , plock ) ;
}
bool smb_vfs_call_brl_unlock_windows ( struct vfs_handle_struct * handle ,
struct byte_range_lock * br_lck ,
const struct lock_struct * plock )
{
VFS_FIND ( brl_unlock_windows ) ;
return handle - > fns - > brl_unlock_windows_fn ( handle , br_lck , plock ) ;
}