2007-11-17 04:07:11 +03:00
/*
2005-03-18 16:13:38 +03:00
* Catia VFS module
*
* Implement a fixed mapping of forbidden NT characters in filenames that are
* used a lot by the CAD package Catia .
*
2016-12-06 17:00:58 +03:00
* Catia V4 on AIX uses characters like " <*$ a *lot*, all forbidden under
* Windows . . .
2005-03-18 16:13:38 +03:00
*
* Copyright ( C ) Volker Lendecke , 2005
2009-08-27 01:55:38 +04:00
* Copyright ( C ) Aravind Srinivasan , 2009
2013-03-01 03:58:05 +04:00
* Copyright ( C ) Guenter Kukkukk , 2013
2016-12-06 17:00:58 +03:00
* Copyright ( C ) Ralph Boehme , 2017
2005-03-18 16:13:38 +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
2005-03-18 16:13:38 +03:00
* ( at your option ) any later version .
2007-11-17 04:07:11 +03:00
*
2005-03-18 16:13:38 +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 .
2007-11-17 04:07:11 +03:00
*
2005-03-18 16:13:38 +03:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2005-03-18 16:13:38 +03:00
*/
# include "includes.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2016-12-06 17:00:58 +03:00
# include "lib/util/tevent_unix.h"
# include "lib/util/tevent_ntstatus.h"
2005-03-18 16:13:38 +03:00
2013-02-27 08:34:05 +04:00
static int vfs_catia_debug_level = DBGC_VFS ;
# undef DBGC_CLASS
# define DBGC_CLASS vfs_catia_debug_level
2009-08-27 01:55:38 +04:00
# define GLOBAL_SNUM 0xFFFFFFF
# define MAP_SIZE 0xFF
# define MAP_NUM 0x101 /* max unicode charval / MAP_SIZE */
# define T_OFFSET(_v_) ((_v_ % MAP_SIZE))
# define T_START(_v_) (((_v_ / MAP_SIZE) * MAP_SIZE))
# define T_PICK(_v_) ((_v_ / MAP_SIZE))
struct char_mappings {
smb_ucs2_t entry [ MAP_SIZE ] [ 2 ] ;
} ;
struct share_mapping_entry {
int snum ;
struct share_mapping_entry * next ;
struct char_mappings * * mappings ;
} ;
2016-12-06 17:00:58 +03:00
struct catia_cache {
bool is_fsp_ext ;
const struct catia_cache * const * busy ;
char * orig_fname ;
char * fname ;
char * orig_base_fname ;
char * base_fname ;
} ;
2009-08-27 01:55:38 +04:00
struct share_mapping_entry * srt_head = NULL ;
static bool build_table ( struct char_mappings * * cmaps , int value )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
int i ;
int start = T_START ( value ) ;
2007-11-17 04:07:11 +03:00
2009-09-15 00:28:11 +04:00
( * cmaps ) = talloc_zero ( NULL , struct char_mappings ) ;
2009-08-27 01:55:38 +04:00
if ( ! * cmaps )
return False ;
2009-09-15 00:22:26 +04:00
for ( i = 0 ; i < MAP_SIZE ; i + + ) {
2009-09-04 00:46:10 +04:00
( * cmaps ) - > entry [ i ] [ vfs_translate_to_unix ] = start + i ;
( * cmaps ) - > entry [ i ] [ vfs_translate_to_windows ] = start + i ;
2007-11-17 04:07:11 +03:00
}
2009-08-27 01:55:38 +04:00
return True ;
}
static void set_tables ( struct char_mappings * * cmaps ,
long unix_map ,
long windows_map )
{
int i ;
/* set unix -> windows */
i = T_OFFSET ( unix_map ) ;
2009-09-04 00:46:10 +04:00
cmaps [ T_PICK ( unix_map ) ] - > entry [ i ] [ vfs_translate_to_windows ] = windows_map ;
2009-08-27 01:55:38 +04:00
/* set windows -> unix */
i = T_OFFSET ( windows_map ) ;
2009-09-04 00:46:10 +04:00
cmaps [ T_PICK ( windows_map ) ] - > entry [ i ] [ vfs_translate_to_unix ] = unix_map ;
2009-08-27 01:55:38 +04:00
}
static bool build_ranges ( struct char_mappings * * cmaps ,
long unix_map ,
long windows_map )
{
if ( ! cmaps [ T_PICK ( unix_map ) ] ) {
if ( ! build_table ( & cmaps [ T_PICK ( unix_map ) ] , unix_map ) )
return False ;
2007-11-17 04:07:11 +03:00
}
2009-08-27 01:55:38 +04:00
if ( ! cmaps [ T_PICK ( windows_map ) ] ) {
if ( ! build_table ( & cmaps [ T_PICK ( windows_map ) ] , windows_map ) )
return False ;
}
2007-11-17 04:07:11 +03:00
2009-08-27 01:55:38 +04:00
set_tables ( cmaps , unix_map , windows_map ) ;
return True ;
}
2009-09-15 00:47:31 +04:00
static struct share_mapping_entry * get_srt ( connection_struct * conn ,
struct share_mapping_entry * * global )
2009-08-27 01:55:38 +04:00
{
struct share_mapping_entry * share ;
for ( share = srt_head ; share ! = NULL ; share = share - > next ) {
if ( share - > snum = = GLOBAL_SNUM )
( * global ) = share ;
if ( share - > snum = = SNUM ( conn ) )
return share ;
2007-11-17 04:07:11 +03:00
}
2009-08-27 01:55:38 +04:00
return share ;
}
2009-09-15 00:47:31 +04:00
static struct share_mapping_entry * add_srt ( int snum , const char * * mappings )
2009-08-27 01:55:38 +04:00
{
char * tmp ;
fstring mapping ;
int i ;
long unix_map , windows_map ;
struct share_mapping_entry * ret = NULL ;
ret = ( struct share_mapping_entry * )
TALLOC_ZERO ( NULL , sizeof ( struct share_mapping_entry ) +
( mappings ? ( MAP_NUM * sizeof ( struct char_mappings * ) ) : 0 ) ) ;
if ( ! ret )
return ret ;
ret - > snum = snum ;
2016-04-10 13:51:15 +03:00
ret - > next = srt_head ;
srt_head = ret ;
2009-08-27 01:55:38 +04:00
if ( mappings ) {
ret - > mappings = ( struct char_mappings * * ) ( ( unsigned char * ) ret +
sizeof ( struct share_mapping_entry ) ) ;
memset ( ret - > mappings , 0 ,
MAP_NUM * sizeof ( struct char_mappings * ) ) ;
} else {
ret - > mappings = NULL ;
return ret ;
2007-11-17 04:07:11 +03:00
}
2009-08-27 01:55:38 +04:00
/*
* catia mappings are of the form :
* UNIX char ( in 0 xnn hex ) : WINDOWS char ( in 0 xnn hex )
*
2013-05-15 20:18:07 +04:00
* multiple mappings are comma separated in smb . conf
2009-08-27 01:55:38 +04:00
*/
for ( i = 0 ; mappings [ i ] ; i + + ) {
fstrcpy ( mapping , mappings [ i ] ) ;
unix_map = strtol ( mapping , & tmp , 16 ) ;
if ( unix_map = = 0 & & errno = = EINVAL ) {
DEBUG ( 0 , ( " INVALID CATIA MAPPINGS - %s \n " , mapping ) ) ;
continue ;
}
windows_map = strtol ( + + tmp , NULL , 16 ) ;
if ( windows_map = = 0 & & errno = = EINVAL ) {
DEBUG ( 0 , ( " INVALID CATIA MAPPINGS - %s \n " , mapping ) ) ;
continue ;
}
if ( ! build_ranges ( ret - > mappings , unix_map , windows_map ) ) {
DEBUG ( 0 , ( " TABLE ERROR - CATIA MAPPINGS - %s \n " , mapping ) ) ;
continue ;
}
}
2007-11-17 04:07:11 +03:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
static bool init_mappings ( connection_struct * conn ,
struct share_mapping_entry * * selected_out )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
const char * * mappings = NULL ;
struct share_mapping_entry * share_level = NULL ;
struct share_mapping_entry * global = NULL ;
/* check srt cache */
share_level = get_srt ( conn , & global ) ;
if ( share_level ) {
* selected_out = share_level ;
return ( share_level - > mappings ! = NULL ) ;
}
/* see if we have a global setting */
if ( ! global ) {
/* global setting */
mappings = lp_parm_string_list ( - 1 , " catia " , " mappings " , NULL ) ;
global = add_srt ( GLOBAL_SNUM , mappings ) ;
}
/* no global setting - what about share level ? */
mappings = lp_parm_string_list ( SNUM ( conn ) , " catia " , " mappings " , NULL ) ;
share_level = add_srt ( SNUM ( conn ) , mappings ) ;
if ( share_level - > mappings ) {
( * selected_out ) = share_level ;
return True ;
2015-02-24 17:03:11 +03:00
}
if ( global - > mappings ) {
2009-08-27 01:55:38 +04:00
share_level - > mappings = global - > mappings ;
( * selected_out ) = share_level ;
return True ;
}
return False ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
static NTSTATUS catia_string_replace_allocate ( connection_struct * conn ,
const char * name_in ,
char * * mapped_name ,
2013-06-17 21:43:32 +04:00
enum vfs_translate_direction direction )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
static smb_ucs2_t * tmpbuf = NULL ;
smb_ucs2_t * ptr ;
struct share_mapping_entry * selected ;
struct char_mappings * map = NULL ;
size_t converted_size ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-09-24 00:37:04 +04:00
if ( ! init_mappings ( conn , & selected ) ) {
/* No mappings found. Just use the old name */
* mapped_name = talloc_strdup ( NULL , name_in ) ;
if ( ! * mapped_name ) {
errno = ENOMEM ;
return NT_STATUS_NO_MEMORY ;
}
2009-08-27 01:55:38 +04:00
return NT_STATUS_OK ;
2009-09-24 00:37:04 +04:00
}
2009-08-27 01:55:38 +04:00
if ( ( push_ucs2_talloc ( ctx , & tmpbuf , name_in ,
2010-02-09 11:09:57 +03:00
& converted_size ) ) = = false ) {
2009-08-27 01:55:38 +04:00
return map_nt_error_from_unix ( errno ) ;
}
ptr = tmpbuf ;
for ( ; * ptr ; ptr + + ) {
if ( * ptr = = 0 )
break ;
map = selected - > mappings [ T_PICK ( ( * ptr ) ) ] ;
/* nothing to do */
if ( ! map )
continue ;
* ptr = map - > entry [ T_OFFSET ( ( * ptr ) ) ] [ direction ] ;
}
if ( ( pull_ucs2_talloc ( ctx , mapped_name , tmpbuf ,
2010-02-09 11:09:57 +03:00
& converted_size ) ) = = false ) {
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( tmpbuf ) ;
return map_nt_error_from_unix ( errno ) ;
}
TALLOC_FREE ( tmpbuf ) ;
return NT_STATUS_OK ;
2005-03-18 16:13:38 +03:00
}
2012-03-28 06:22:03 +04:00
static DIR * catia_opendir ( vfs_handle_struct * handle ,
2016-02-27 01:53:12 +03:00
const struct smb_filename * smb_fname ,
const char * mask ,
uint32_t attr )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name_mapped = NULL ;
NTSTATUS status ;
2012-03-28 06:22:03 +04:00
DIR * ret ;
2016-02-27 01:53:12 +03:00
struct smb_filename * mapped_smb_fname = NULL ;
2005-03-18 16:13:38 +03:00
2016-02-27 01:53:12 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name_mapped ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return NULL ;
}
2009-08-27 01:55:38 +04:00
2016-02-27 01:53:12 +03:00
mapped_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name_mapped ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-27 01:53:12 +03:00
if ( mapped_smb_fname = = NULL ) {
TALLOC_FREE ( mapped_smb_fname ) ;
errno = ENOMEM ;
return NULL ;
}
ret = SMB_VFS_NEXT_OPENDIR ( handle , mapped_smb_fname , mask , attr ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name_mapped ) ;
2016-02-27 01:53:12 +03:00
TALLOC_FREE ( mapped_smb_fname ) ;
2009-08-27 01:55:38 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
/*
* TRANSLATE_NAME call which converts the given name to
* " WINDOWS displayable " name
*/
2009-11-16 11:49:23 +03:00
static NTSTATUS catia_translate_name ( struct vfs_handle_struct * handle ,
const char * orig_name ,
enum vfs_translate_direction direction ,
TALLOC_CTX * mem_ctx ,
char * * pmapped_name )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
2009-11-16 11:49:23 +03:00
char * mapped_name ;
2013-02-27 08:50:52 +04:00
NTSTATUS status , ret ;
2007-11-17 04:07:11 +03:00
2009-08-27 01:55:38 +04:00
/*
* Copy the supplied name and free the memory for mapped_name ,
* already allocated by the caller .
* We will be allocating new memory for mapped_name in
* catia_string_replace_allocate
*/
2009-11-16 11:49:23 +03:00
name = talloc_strdup ( talloc_tos ( ) , orig_name ) ;
2009-08-27 01:55:38 +04:00
if ( ! name ) {
errno = ENOMEM ;
return NT_STATUS_NO_MEMORY ;
2007-11-17 04:07:11 +03:00
}
2013-02-27 08:50:52 +04:00
status = catia_string_replace_allocate ( handle - > conn , name ,
2009-11-16 11:49:23 +03:00
& mapped_name , direction ) ;
2007-11-17 04:07:11 +03:00
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2013-02-27 08:50:52 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2007-11-17 04:07:11 +03:00
}
2009-08-27 01:55:38 +04:00
2009-11-16 11:49:23 +03:00
ret = SMB_VFS_NEXT_TRANSLATE_NAME ( handle , mapped_name , direction ,
mem_ctx , pmapped_name ) ;
if ( NT_STATUS_EQUAL ( ret , NT_STATUS_NONE_MAPPED ) ) {
* pmapped_name = talloc_move ( mem_ctx , & mapped_name ) ;
2013-02-27 08:50:52 +04:00
/* we need to return the former translation result here */
ret = status ;
2009-11-16 11:49:23 +03:00
} else {
TALLOC_FREE ( mapped_name ) ;
}
2009-08-27 01:55:38 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2016-12-06 17:00:58 +03:00
# define CATIA_DEBUG_CC(lvl, cc, fsp) \
catia_debug_cc ( ( lvl ) , ( cc ) , ( fsp ) , __location__ ) ;
static void catia_debug_cc ( int lvl ,
struct catia_cache * cc ,
files_struct * fsp ,
const char * location )
{
DEBUG ( lvl , ( " %s: cc [0x%p] cc->busy [0x%p] "
" is_fsp_ext [%s] "
" fsp [0x%p] fsp name [%s] "
" orig_fname [%s] "
" fname [%s] "
" orig_base_fname [%s] "
" base_fname [%s] \n " ,
location ,
cc , cc - > busy ,
cc - > is_fsp_ext ? " yes " : " no " ,
fsp , fsp_str_dbg ( fsp ) ,
cc - > orig_fname , cc - > fname ,
cc - > orig_base_fname , cc - > base_fname ) ) ;
}
static void catia_free_cc ( struct catia_cache * * _cc ,
vfs_handle_struct * handle ,
files_struct * fsp )
{
struct catia_cache * cc = * _cc ;
if ( cc - > is_fsp_ext ) {
VFS_REMOVE_FSP_EXTENSION ( handle , fsp ) ;
cc = NULL ;
} else {
TALLOC_FREE ( cc ) ;
}
* _cc = NULL ;
}
static struct catia_cache * catia_validate_and_apply_cc (
vfs_handle_struct * handle ,
files_struct * fsp ,
const struct catia_cache * const * busy ,
bool * make_tmp_cache )
{
struct catia_cache * cc = NULL ;
* make_tmp_cache = false ;
cc = ( struct catia_cache * ) VFS_FETCH_FSP_EXTENSION ( handle , fsp ) ;
if ( cc = = NULL ) {
return NULL ;
}
if ( cc - > busy ! = NULL ) {
if ( cc - > busy = = busy ) {
/* This should never happen */
CATIA_DEBUG_CC ( 0 , cc , fsp ) ;
smb_panic ( __location__ ) ;
}
/*
* Recursion . Validate names , the names in the fsp ' s should be
* the translated names we had set .
*/
if ( ( cc - > fname ! = fsp - > fsp_name - > base_name )
| |
( ( fsp - > base_fsp ! = NULL ) & &
( cc - > base_fname ! = fsp - > base_fsp - > fsp_name - > base_name ) ) )
{
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
/*
* Names changed . Setting don ' t expose the cache on the
* fsp and ask the caller to create a temporary cache .
*/
* make_tmp_cache = true ;
return NULL ;
}
/*
* Ok , a validated cache while in a recursion , just let the
* caller detect that cc - > busy is ! = busy and there ' s
* nothing else to do .
*/
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
return cc ;
}
/* Not in a recursion */
if ( ( cc - > orig_fname ! = fsp - > fsp_name - > base_name )
| |
( ( fsp - > base_fsp ! = NULL ) & &
( cc - > orig_base_fname ! = fsp - > base_fsp - > fsp_name - > base_name ) ) )
{
/*
* fsp names changed , this can happen in an rename op .
* Trigger recreation as a full fledged fsp extension .
*/
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
catia_free_cc ( & cc , handle , fsp ) ;
return NULL ;
}
/*
* Ok , we found a valid cache entry , no recursion . Just set translated
* names from the cache and mark the cc as busy .
*/
fsp - > fsp_name - > base_name = cc - > fname ;
if ( fsp - > base_fsp ! = NULL ) {
fsp - > base_fsp - > fsp_name - > base_name = cc - > base_fname ;
}
cc - > busy = busy ;
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
return cc ;
}
# define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
catia_fetch_fsp_pre_next ( ( mem_ctx ) , ( handle ) , ( fsp ) , ( _cc ) , __func__ ) ;
static int catia_fetch_fsp_pre_next ( TALLOC_CTX * mem_ctx ,
vfs_handle_struct * handle ,
files_struct * fsp ,
struct catia_cache * * _cc ,
const char * function )
{
const struct catia_cache * const * busy =
( const struct catia_cache * const * ) _cc ;
struct catia_cache * cc = NULL ;
NTSTATUS status ;
bool make_tmp_cache = false ;
* _cc = NULL ;
DBG_DEBUG ( " Called from [%s] \n " , function ) ;
cc = catia_validate_and_apply_cc ( handle ,
fsp ,
busy ,
& make_tmp_cache ) ;
if ( cc ! = NULL ) {
if ( cc - > busy ! = busy ) {
return 0 ;
}
* _cc = cc ;
return 0 ;
}
if ( ! make_tmp_cache ) {
cc = ( struct catia_cache * ) VFS_ADD_FSP_EXTENSION (
handle , fsp , struct catia_cache , NULL ) ;
if ( cc = = NULL ) {
return - 1 ;
}
* cc = ( struct catia_cache ) {
. is_fsp_ext = true ,
} ;
mem_ctx = VFS_MEMCTX_FSP_EXTENSION ( handle , fsp ) ;
if ( mem_ctx = = NULL ) {
DBG_ERR ( " VFS_MEMCTX_FSP_EXTENSION failed \n " ) ;
catia_free_cc ( & cc , handle , fsp ) ;
return - 1 ;
}
} else {
cc = talloc_zero ( mem_ctx , struct catia_cache ) ;
if ( cc = = NULL ) {
return - 1 ;
}
mem_ctx = cc ;
}
status = catia_string_replace_allocate ( handle - > conn ,
fsp - > fsp_name - > base_name ,
& cc - > fname ,
vfs_translate_to_unix ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
catia_free_cc ( & cc , handle , fsp ) ;
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
talloc_steal ( mem_ctx , cc - > fname ) ;
if ( fsp - > base_fsp ! = NULL ) {
status = catia_string_replace_allocate (
handle - > conn ,
fsp - > base_fsp - > fsp_name - > base_name ,
& cc - > base_fname ,
vfs_translate_to_unix ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
catia_free_cc ( & cc , handle , fsp ) ;
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
talloc_steal ( mem_ctx , cc - > base_fname ) ;
}
cc - > orig_fname = fsp - > fsp_name - > base_name ;
fsp - > fsp_name - > base_name = cc - > fname ;
if ( fsp - > base_fsp ! = NULL ) {
cc - > orig_base_fname = fsp - > base_fsp - > fsp_name - > base_name ;
fsp - > base_fsp - > fsp_name - > base_name = cc - > base_fname ;
}
cc - > busy = busy ;
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
* _cc = cc ;
return 0 ;
}
# define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
int saved_errno = errno ; \
catia_fetch_fsp_post_next ( ( _cc ) , ( fsp ) , __func__ ) ; \
errno = saved_errno ; \
} while ( 0 )
static void catia_fetch_fsp_post_next ( struct catia_cache * * _cc ,
files_struct * fsp ,
const char * function )
{
const struct catia_cache * const * busy =
( const struct catia_cache * const * ) _cc ;
struct catia_cache * cc = * _cc ;
DBG_DEBUG ( " Called from [%s] \n " , function ) ;
if ( cc = = NULL ) {
/*
* This can happen when recursing in the VFS on the fsp when the
* pre_next func noticed the recursion and set out cc pointer to
* NULL .
*/
return ;
}
if ( cc - > busy ! = busy ) {
CATIA_DEBUG_CC ( 0 , cc , fsp ) ;
smb_panic ( __location__ ) ;
return ;
}
cc - > busy = NULL ;
* _cc = NULL ;
fsp - > fsp_name - > base_name = cc - > orig_fname ;
if ( fsp - > base_fsp ! = NULL ) {
fsp - > base_fsp - > fsp_name - > base_name = cc - > orig_base_fname ;
}
CATIA_DEBUG_CC ( 10 , cc , fsp ) ;
if ( ! cc - > is_fsp_ext ) {
TALLOC_FREE ( cc ) ;
}
return ;
}
2006-07-11 22:01:26 +04:00
static int catia_open ( vfs_handle_struct * handle ,
2009-06-16 23:01:13 +04:00
struct smb_filename * smb_fname ,
2007-11-17 04:07:11 +03:00
files_struct * fsp ,
int flags ,
mode_t mode )
2005-03-18 16:13:38 +03:00
{
2016-12-06 17:00:58 +03:00
struct catia_cache * cc = NULL ;
char * orig_smb_fname = smb_fname - > base_name ;
char * mapped_smb_fname = NULL ;
2009-08-27 01:55:38 +04:00
NTSTATUS status ;
2016-12-06 17:00:58 +03:00
int ret ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
2016-12-06 17:00:58 +03:00
smb_fname - > base_name ,
& mapped_smb_fname ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-06-16 23:01:13 +04:00
2016-12-06 17:00:58 +03:00
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
TALLOC_FREE ( mapped_smb_fname ) ;
return ret ;
}
smb_fname - > base_name = mapped_smb_fname ;
2009-07-07 22:40:39 +04:00
ret = SMB_VFS_NEXT_OPEN ( handle , smb_fname , fsp , flags , mode ) ;
2016-12-06 17:00:58 +03:00
smb_fname - > base_name = orig_smb_fname ;
TALLOC_FREE ( mapped_smb_fname ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
2009-08-27 01:55:38 +04:00
return ret ;
}
2006-07-11 22:01:26 +04:00
static int catia_rename ( vfs_handle_struct * handle ,
2009-07-01 04:04:38 +04:00
const struct smb_filename * smb_fname_src ,
const struct smb_filename * smb_fname_dst )
2005-03-18 16:13:38 +03:00
{
2007-11-17 04:07:11 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-07-01 04:04:38 +04:00
struct smb_filename * smb_fname_src_tmp = NULL ;
struct smb_filename * smb_fname_dst_tmp = NULL ;
2009-09-02 21:20:21 +04:00
char * src_name_mapped = NULL ;
char * dst_name_mapped = NULL ;
2009-07-01 04:04:38 +04:00
NTSTATUS status ;
int ret = - 1 ;
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname_src - > base_name ,
2009-09-04 00:46:10 +04:00
& src_name_mapped , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname_dst - > base_name ,
2009-09-04 00:46:10 +04:00
& dst_name_mapped , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
2009-07-01 04:04:38 +04:00
}
/* Setup temporary smb_filename structs. */
2013-04-11 18:10:22 +04:00
smb_fname_src_tmp = cp_smb_filename ( ctx , smb_fname_src ) ;
if ( smb_fname_src_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-01 04:04:38 +04:00
goto out ;
}
2009-08-27 01:55:38 +04:00
2013-04-11 18:10:22 +04:00
smb_fname_dst_tmp = cp_smb_filename ( ctx , smb_fname_dst ) ;
if ( smb_fname_dst_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-01 04:04:38 +04:00
goto out ;
2007-11-17 04:07:11 +03:00
}
2005-03-18 16:13:38 +03:00
2009-09-02 21:20:21 +04:00
smb_fname_src_tmp - > base_name = src_name_mapped ;
smb_fname_dst_tmp - > base_name = dst_name_mapped ;
2009-07-01 04:04:38 +04:00
DEBUG ( 10 , ( " converted old name: %s \n " ,
2009-08-27 01:55:38 +04:00
smb_fname_str_dbg ( smb_fname_src_tmp ) ) ) ;
2009-07-01 04:04:38 +04:00
DEBUG ( 10 , ( " converted new name: %s \n " ,
2009-08-27 01:55:38 +04:00
smb_fname_str_dbg ( smb_fname_dst_tmp ) ) ) ;
2009-07-01 04:04:38 +04:00
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_RENAME ( handle , smb_fname_src_tmp ,
smb_fname_dst_tmp ) ;
out :
2009-09-02 21:20:21 +04:00
TALLOC_FREE ( src_name_mapped ) ;
TALLOC_FREE ( dst_name_mapped ) ;
2009-07-01 04:04:38 +04:00
TALLOC_FREE ( smb_fname_src_tmp ) ;
TALLOC_FREE ( smb_fname_dst_tmp ) ;
return ret ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_stat ( vfs_handle_struct * handle ,
2009-06-23 02:26:56 +04:00
struct smb_filename * smb_fname )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
2009-06-23 02:26:56 +04:00
char * tmp_base_name ;
int ret ;
2009-08-27 01:55:38 +04:00
NTSTATUS status ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
2009-09-04 00:46:10 +04:00
& name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-06-23 02:26:56 +04:00
tmp_base_name = smb_fname - > base_name ;
smb_fname - > base_name = name ;
ret = SMB_VFS_NEXT_STAT ( handle , smb_fname ) ;
smb_fname - > base_name = tmp_base_name ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2009-06-23 02:26:56 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_lstat ( vfs_handle_struct * handle ,
2009-06-23 02:26:56 +04:00
struct smb_filename * smb_fname )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
2009-06-23 02:26:56 +04:00
char * tmp_base_name ;
int ret ;
2009-08-27 01:55:38 +04:00
NTSTATUS status ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
2009-09-04 00:46:10 +04:00
& name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-06-23 02:26:56 +04:00
tmp_base_name = smb_fname - > base_name ;
smb_fname - > base_name = name ;
ret = SMB_VFS_NEXT_LSTAT ( handle , smb_fname ) ;
smb_fname - > base_name = tmp_base_name ;
TALLOC_FREE ( name ) ;
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-07-02 20:27:44 +04:00
static int catia_unlink ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2005-03-18 16:13:38 +03:00
{
2009-07-02 20:27:44 +04:00
struct smb_filename * smb_fname_tmp = NULL ;
char * name = NULL ;
NTSTATUS status ;
int ret ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
2009-09-04 00:46:10 +04:00
& name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-07-02 20:27:44 +04:00
/* Setup temporary smb_filename structs. */
2013-04-11 18:11:26 +04:00
smb_fname_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname ) ;
if ( smb_fname_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-02 20:27:44 +04:00
return - 1 ;
}
smb_fname_tmp - > base_name = name ;
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_UNLINK ( handle , smb_fname_tmp ) ;
TALLOC_FREE ( smb_fname_tmp ) ;
TALLOC_FREE ( name ) ;
2009-07-02 20:27:44 +04:00
2009-08-27 01:55:38 +04:00
return ret ;
}
static int catia_chown ( vfs_handle_struct * handle ,
2016-03-03 22:54:23 +03:00
const struct smb_filename * smb_fname ,
2009-08-27 01:55:38 +04:00
uid_t uid ,
gid_t gid )
{
char * name = NULL ;
NTSTATUS status ;
int ret ;
2016-03-03 22:54:23 +03:00
int saved_errno ;
struct smb_filename * catia_smb_fname = NULL ;
2009-08-27 01:55:38 +04:00
2016-03-03 22:54:23 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
2016-03-03 22:54:23 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-03 22:54:23 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( name ) ;
errno = ENOMEM ;
return - 1 ;
}
2009-08-27 01:55:38 +04:00
2016-03-03 22:54:23 +03:00
ret = SMB_VFS_NEXT_CHOWN ( handle , catia_smb_fname , uid , gid ) ;
saved_errno = errno ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2016-03-03 22:54:23 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
errno = saved_errno ;
2009-07-02 20:27:44 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
static int catia_lchown ( vfs_handle_struct * handle ,
2016-03-04 01:34:57 +03:00
const struct smb_filename * smb_fname ,
2009-08-27 01:55:38 +04:00
uid_t uid ,
gid_t gid )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
NTSTATUS status ;
int ret ;
2016-03-04 01:34:57 +03:00
int saved_errno ;
struct smb_filename * catia_smb_fname = NULL ;
2005-03-18 16:13:38 +03:00
2016-03-04 01:34:57 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2016-03-04 01:34:57 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-04 01:34:57 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( name ) ;
errno = ENOMEM ;
return - 1 ;
}
2009-08-27 01:55:38 +04:00
2016-03-04 01:34:57 +03:00
ret = SMB_VFS_NEXT_LCHOWN ( handle , catia_smb_fname , uid , gid ) ;
saved_errno = errno ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2016-03-04 01:34:57 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
errno = saved_errno ;
2009-08-27 01:55:38 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2016-03-02 03:20:25 +03:00
static int catia_chmod ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
mode_t mode )
2014-03-10 20:14:38 +04:00
{
char * name = NULL ;
NTSTATUS status ;
int ret ;
2016-03-02 03:20:25 +03:00
int saved_errno ;
struct smb_filename * catia_smb_fname = NULL ;
2014-03-10 20:14:38 +04:00
2016-03-02 03:20:25 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name ,
vfs_translate_to_unix ) ;
2014-03-10 20:14:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
2016-03-02 03:20:25 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-02 03:20:25 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( name ) ;
errno = ENOMEM ;
return - 1 ;
}
2014-03-10 20:14:38 +04:00
2016-03-02 03:20:25 +03:00
ret = SMB_VFS_NEXT_CHMOD ( handle , catia_smb_fname , mode ) ;
saved_errno = errno ;
2014-03-10 20:14:38 +04:00
TALLOC_FREE ( name ) ;
2016-03-02 03:20:25 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
errno = saved_errno ;
2014-03-10 20:14:38 +04:00
return ret ;
}
2009-08-27 01:55:38 +04:00
static int catia_rmdir ( vfs_handle_struct * handle ,
2016-02-25 01:02:45 +03:00
const struct smb_filename * smb_fname )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
NTSTATUS status ;
int ret ;
2016-02-25 01:02:45 +03:00
struct smb_filename * catia_smb_fname = NULL ;
2005-03-18 16:13:38 +03:00
2016-02-25 01:02:45 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2016-02-25 01:02:45 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-25 01:02:45 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( name ) ;
errno = ENOMEM ;
return - 1 ;
}
2009-08-27 01:55:38 +04:00
2016-02-25 01:02:45 +03:00
ret = SMB_VFS_NEXT_RMDIR ( handle , catia_smb_fname ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2016-02-25 01:02:45 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
2009-08-27 01:55:38 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
static int catia_mkdir ( vfs_handle_struct * handle ,
2016-02-24 00:14:03 +03:00
const struct smb_filename * smb_fname ,
2009-08-27 01:55:38 +04:00
mode_t mode )
2007-05-24 03:55:12 +04:00
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
NTSTATUS status ;
int ret ;
2016-02-24 00:14:03 +03:00
struct smb_filename * catia_smb_fname = NULL ;
2007-05-24 03:55:12 +04:00
2016-02-24 00:14:03 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2016-02-24 00:14:03 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-24 00:14:03 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( name ) ;
errno = ENOMEM ;
return - 1 ;
}
2009-08-27 01:55:38 +04:00
2016-02-24 00:14:03 +03:00
ret = SMB_VFS_NEXT_MKDIR ( handle , catia_smb_fname , mode ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( name ) ;
2016-02-24 00:14:03 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
2009-08-27 01:55:38 +04:00
return ret ;
2007-05-24 03:55:12 +04:00
}
2006-07-11 22:01:26 +04:00
static int catia_chdir ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path )
{
2009-08-27 01:55:38 +04:00
char * name = NULL ;
NTSTATUS status ;
int ret ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn , path ,
2009-09-04 00:46:10 +04:00
& name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHDIR ( handle , name ) ;
TALLOC_FREE ( name ) ;
return ret ;
}
static int catia_ntimes ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
struct smb_file_time * ft )
{
struct smb_filename * smb_fname_tmp = NULL ;
char * name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
2009-09-04 00:46:10 +04:00
& name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
2013-04-11 18:12:13 +04:00
smb_fname_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname ) ;
if ( smb_fname_tmp = = NULL ) {
errno = ENOMEM ;
2009-08-27 01:55:38 +04:00
return - 1 ;
}
smb_fname_tmp - > base_name = name ;
ret = SMB_VFS_NEXT_NTIMES ( handle , smb_fname_tmp , ft ) ;
2009-09-02 21:20:21 +04:00
TALLOC_FREE ( name ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( smb_fname_tmp ) ;
return ret ;
}
static char *
2010-11-20 03:29:26 +03:00
catia_realpath ( vfs_handle_struct * handle , const char * path )
2009-08-27 01:55:38 +04:00
{
char * mapped_name = NULL ;
NTSTATUS status ;
char * ret = NULL ;
status = catia_string_replace_allocate ( handle - > conn , path ,
2009-09-04 00:46:10 +04:00
& mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return NULL ;
}
2010-11-20 03:29:26 +03:00
ret = SMB_VFS_NEXT_REALPATH ( handle , mapped_name ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int catia_chflags ( struct vfs_handle_struct * handle ,
const char * path , unsigned int flags )
{
char * mapped_name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate ( handle - > conn , path ,
2009-09-04 00:46:10 +04:00
& mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHFLAGS ( handle , mapped_name , flags ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static NTSTATUS
catia_streaminfo ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
2016-03-05 01:16:13 +03:00
const struct smb_filename * smb_fname ,
2009-08-27 01:55:38 +04:00
TALLOC_CTX * mem_ctx ,
2015-05-09 16:12:41 +03:00
unsigned int * _num_streams ,
struct stream_struct * * _streams )
2009-08-27 01:55:38 +04:00
{
char * mapped_name = NULL ;
NTSTATUS status ;
2016-04-10 14:09:29 +03:00
unsigned int i ;
2016-03-05 01:16:13 +03:00
struct smb_filename * catia_smb_fname = NULL ;
2015-05-09 16:12:41 +03:00
unsigned int num_streams = 0 ;
struct stream_struct * streams = NULL ;
* _num_streams = 0 ;
* _streams = NULL ;
2009-08-27 01:55:38 +04:00
2016-03-05 01:16:13 +03:00
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
& mapped_name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return status ;
}
2016-03-05 01:16:13 +03:00
catia_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
mapped_name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-05 01:16:13 +03:00
if ( catia_smb_fname = = NULL ) {
TALLOC_FREE ( mapped_name ) ;
return NT_STATUS_NO_MEMORY ;
}
status = SMB_VFS_NEXT_STREAMINFO ( handle , fsp , catia_smb_fname ,
2015-05-09 16:12:41 +03:00
mem_ctx , & num_streams , & streams ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( mapped_name ) ;
2016-03-05 01:16:13 +03:00
TALLOC_FREE ( catia_smb_fname ) ;
2015-05-09 16:12:41 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-08-27 01:55:38 +04:00
2015-05-09 16:12:41 +03:00
/*
* Translate stream names just like the base names
*/
for ( i = 0 ; i < num_streams ; i + + ) {
/*
* Strip " : " prefix and " :$DATA " suffix to get a
* " pure " stream name and only translate that .
*/
void * old_ptr = streams [ i ] . name ;
char * stream_name = streams [ i ] . name + 1 ;
char * stream_type = strrchr_m ( stream_name , ' : ' ) ;
if ( stream_type ! = NULL ) {
* stream_type = ' \0 ' ;
stream_type + = 1 ;
}
status = catia_string_replace_allocate ( handle - > conn , stream_name ,
& mapped_name , vfs_translate_to_windows ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( streams ) ;
return status ;
}
if ( stream_type ! = NULL ) {
streams [ i ] . name = talloc_asprintf ( streams , " :%s:%s " ,
mapped_name , stream_type ) ;
} else {
streams [ i ] . name = talloc_asprintf ( streams , " :%s " ,
mapped_name ) ;
}
TALLOC_FREE ( mapped_name ) ;
TALLOC_FREE ( old_ptr ) ;
if ( streams [ i ] . name = = NULL ) {
TALLOC_FREE ( streams ) ;
return NT_STATUS_NO_MEMORY ;
}
}
* _num_streams = num_streams ;
* _streams = streams ;
return NT_STATUS_OK ;
2009-08-27 01:55:38 +04:00
}
static NTSTATUS
catia_get_nt_acl ( struct vfs_handle_struct * handle ,
2016-02-12 21:30:10 +03:00
const struct smb_filename * smb_fname ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2009-08-27 01:55:38 +04:00
struct security_descriptor * * ppdesc )
{
char * mapped_name = NULL ;
2016-02-12 21:30:10 +03:00
const char * path = smb_fname - > base_name ;
struct smb_filename * mapped_smb_fname = NULL ;
2009-08-27 01:55:38 +04:00
NTSTATUS status ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
path , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return status ;
}
2016-02-12 21:30:10 +03:00
mapped_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
mapped_name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-12 21:30:10 +03:00
if ( mapped_smb_fname = = NULL ) {
TALLOC_FREE ( mapped_name ) ;
return NT_STATUS_NO_MEMORY ;
}
status = SMB_VFS_NEXT_GET_NT_ACL ( handle , mapped_smb_fname ,
2012-10-10 04:50:27 +04:00
security_info , mem_ctx , ppdesc ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( mapped_name ) ;
2016-02-12 21:30:10 +03:00
TALLOC_FREE ( mapped_smb_fname ) ;
2009-08-27 01:55:38 +04:00
return status ;
}
static int
catia_chmod_acl ( vfs_handle_struct * handle ,
2016-03-02 04:25:25 +03:00
const struct smb_filename * smb_fname ,
2009-08-27 01:55:38 +04:00
mode_t mode )
{
char * mapped_name = NULL ;
2016-03-02 04:25:25 +03:00
struct smb_filename * mapped_smb_fname = NULL ;
2009-08-27 01:55:38 +04:00
NTSTATUS status ;
int ret ;
2016-03-02 04:25:25 +03:00
int saved_errno ;
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn ,
2016-03-02 04:25:25 +03:00
smb_fname - > base_name ,
& mapped_name ,
vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
2016-03-02 04:25:25 +03:00
mapped_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
mapped_name ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-02 04:25:25 +03:00
if ( mapped_smb_fname = = NULL ) {
TALLOC_FREE ( mapped_name ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHMOD_ACL ( handle , mapped_smb_fname , mode ) ;
saved_errno = errno ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( mapped_name ) ;
2016-03-02 04:25:25 +03:00
TALLOC_FREE ( mapped_smb_fname ) ;
errno = saved_errno ;
2009-08-27 01:55:38 +04:00
return ret ;
}
static SMB_ACL_T
catia_sys_acl_get_file ( vfs_handle_struct * handle ,
const char * path ,
2012-10-10 03:18:32 +04:00
SMB_ACL_TYPE_T type ,
TALLOC_CTX * mem_ctx )
2009-08-27 01:55:38 +04:00
{
char * mapped_name = NULL ;
NTSTATUS status ;
SMB_ACL_T ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
path , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return NULL ;
}
2012-10-10 03:18:32 +04:00
ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE ( handle , mapped_name , type , mem_ctx ) ;
2009-08-27 01:55:38 +04:00
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int
catia_sys_acl_set_file ( vfs_handle_struct * handle ,
const char * path ,
SMB_ACL_TYPE_T type ,
SMB_ACL_T theacl )
{
char * mapped_name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
path , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE ( handle , mapped_name , type , theacl ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int
catia_sys_acl_delete_def_file ( vfs_handle_struct * handle ,
const char * path )
{
char * mapped_name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
path , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE ( handle , mapped_name ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static ssize_t
catia_getxattr ( vfs_handle_struct * handle , const char * path ,
const char * name , void * value , size_t size )
{
char * mapped_name = NULL ;
NTSTATUS status ;
ssize_t ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
name , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_GETXATTR ( handle , path , mapped_name , value , size ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static ssize_t
catia_listxattr ( vfs_handle_struct * handle , const char * path ,
char * list , size_t size )
{
char * mapped_name = NULL ;
NTSTATUS status ;
ssize_t ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
path , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_LISTXATTR ( handle , mapped_name , list , size ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int
catia_removexattr ( vfs_handle_struct * handle , const char * path ,
const char * name )
{
char * mapped_name = NULL ;
NTSTATUS status ;
ssize_t ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
name , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_REMOVEXATTR ( handle , path , mapped_name ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int
catia_setxattr ( vfs_handle_struct * handle , const char * path ,
const char * name , const void * value , size_t size ,
int flags )
{
char * mapped_name = NULL ;
NTSTATUS status ;
ssize_t ret ;
status = catia_string_replace_allocate ( handle - > conn ,
2009-09-04 00:46:10 +04:00
name , & mapped_name , vfs_translate_to_unix ) ;
2009-08-27 01:55:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_SETXATTR ( handle , path , mapped_name , value , size , flags ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
2016-12-06 17:00:58 +03:00
static int catia_fstat ( vfs_handle_struct * handle ,
files_struct * fsp ,
SMB_STRUCT_STAT * sbuf )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FSTAT ( handle , fsp , sbuf ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static ssize_t catia_pread ( vfs_handle_struct * handle ,
files_struct * fsp , void * data ,
size_t n , off_t offset )
{
struct catia_cache * cc = NULL ;
ssize_t result ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
result = SMB_VFS_NEXT_PREAD ( handle , fsp , data , n , offset ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static ssize_t catia_pwrite ( vfs_handle_struct * handle ,
files_struct * fsp , const void * data ,
size_t n , off_t offset )
{
struct catia_cache * cc = NULL ;
ssize_t result ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
result = SMB_VFS_NEXT_PWRITE ( handle , fsp , data , n , offset ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static int catia_ftruncate ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
off_t offset )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FTRUNCATE ( handle , fsp , offset ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static int catia_fallocate ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t mode ,
off_t offset ,
off_t len )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FALLOCATE ( handle , fsp , mode , offset , len ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static ssize_t catia_fgetxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const char * name ,
void * value ,
size_t size )
{
char * mapped_xattr_name = NULL ;
NTSTATUS status ;
ssize_t result ;
status = catia_string_replace_allocate ( handle - > conn ,
name , & mapped_xattr_name ,
vfs_translate_to_unix ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
result = SMB_VFS_NEXT_FGETXATTR ( handle , fsp , mapped_xattr_name ,
value , size ) ;
TALLOC_FREE ( mapped_xattr_name ) ;
return result ;
}
static ssize_t catia_flistxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
char * list ,
size_t size )
{
struct catia_cache * cc = NULL ;
ssize_t result ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
result = SMB_VFS_NEXT_FLISTXATTR ( handle , fsp , list , size ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static int catia_fremovexattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const char * name )
{
char * mapped_name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate ( handle - > conn ,
name , & mapped_name , vfs_translate_to_unix ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_FREMOVEXATTR ( handle , fsp , mapped_name ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static int catia_fsetxattr ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
const char * name ,
const void * value ,
size_t size ,
int flags )
{
char * mapped_xattr_name = NULL ;
NTSTATUS status ;
int ret ;
status = catia_string_replace_allocate (
handle - > conn , name , & mapped_xattr_name , vfs_translate_to_unix ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_FSETXATTR ( handle , fsp , mapped_xattr_name ,
value , size , flags ) ;
TALLOC_FREE ( mapped_xattr_name ) ;
return ret ;
}
static SMB_ACL_T catia_sys_acl_get_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
TALLOC_CTX * mem_ctx )
{
struct catia_cache * cc = NULL ;
struct smb_acl_t * result = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return NULL ;
}
result = SMB_VFS_NEXT_SYS_ACL_GET_FD ( handle , fsp , mem_ctx ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static int catia_sys_acl_blob_get_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
TALLOC_CTX * mem_ctx ,
char * * blob_description ,
DATA_BLOB * blob )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD ( handle , fsp , mem_ctx ,
blob_description , blob ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static int catia_sys_acl_set_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
SMB_ACL_T theacl )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_SYS_ACL_SET_FD ( handle , fsp , theacl ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static int catia_fchmod_acl ( vfs_handle_struct * handle ,
files_struct * fsp ,
mode_t mode )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FCHMOD_ACL ( handle , fsp , mode ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static NTSTATUS catia_fget_nt_acl ( vfs_handle_struct * handle ,
files_struct * fsp ,
uint32_t security_info ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * ppdesc )
{
struct catia_cache * cc = NULL ;
NTSTATUS status ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
status = SMB_VFS_NEXT_FGET_NT_ACL ( handle , fsp , security_info ,
mem_ctx , ppdesc ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return status ;
}
static NTSTATUS catia_fset_nt_acl ( vfs_handle_struct * handle ,
files_struct * fsp ,
uint32_t security_info_sent ,
const struct security_descriptor * psd )
{
struct catia_cache * cc = NULL ;
NTSTATUS status ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
status = SMB_VFS_NEXT_FSET_NT_ACL ( handle , fsp , security_info_sent , psd ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return status ;
}
static NTSTATUS catia_fset_dos_attributes ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t dosmode )
{
struct catia_cache * cc = NULL ;
NTSTATUS status ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES ( handle , fsp , dosmode ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return status ;
}
static NTSTATUS catia_fget_dos_attributes ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t * dosmode )
{
struct catia_cache * cc = NULL ;
NTSTATUS status ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES ( handle , fsp , dosmode ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return status ;
}
static int catia_fchown ( vfs_handle_struct * handle ,
files_struct * fsp ,
uid_t uid ,
gid_t gid )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FCHOWN ( handle , fsp , uid , gid ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static int catia_fchmod ( vfs_handle_struct * handle ,
files_struct * fsp ,
mode_t mode )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return ret ;
}
ret = SMB_VFS_NEXT_FCHMOD ( handle , fsp , mode ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
struct catia_pread_state {
ssize_t ret ;
struct vfs_aio_state vfs_aio_state ;
struct files_struct * fsp ;
struct catia_cache * cc ;
} ;
static void catia_pread_done ( struct tevent_req * subreq ) ;
static struct tevent_req * catia_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 = NULL , * subreq = NULL ;
struct catia_pread_state * state = NULL ;
int ret ;
req = tevent_req_create ( mem_ctx , & state ,
struct catia_pread_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > fsp = fsp ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( state , handle , fsp , & state - > cc ) ;
if ( ret ! = 0 ) {
tevent_req_error ( req , errno ) ;
return tevent_req_post ( req , ev ) ;
}
subreq = SMB_VFS_NEXT_PREAD_SEND ( state , ev , handle , fsp , data ,
n , offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , catia_pread_done , req ) ;
return req ;
}
static void catia_pread_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct catia_pread_state * state = tevent_req_data (
req , struct catia_pread_state ) ;
state - > ret = SMB_VFS_PREAD_RECV ( subreq , & state - > vfs_aio_state ) ;
TALLOC_FREE ( subreq ) ;
CATIA_FETCH_FSP_POST_NEXT ( & state - > cc , state - > fsp ) ;
tevent_req_done ( req ) ;
}
static ssize_t catia_pread_recv ( struct tevent_req * req ,
struct vfs_aio_state * vfs_aio_state )
{
struct catia_pread_state * state = tevent_req_data (
req , struct catia_pread_state ) ;
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
return - 1 ;
}
* vfs_aio_state = state - > vfs_aio_state ;
return state - > ret ;
}
struct catia_pwrite_state {
ssize_t ret ;
struct vfs_aio_state vfs_aio_state ;
struct files_struct * fsp ;
struct catia_cache * cc ;
} ;
static void catia_pwrite_done ( struct tevent_req * subreq ) ;
static struct tevent_req * catia_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 = NULL , * subreq = NULL ;
struct catia_pwrite_state * state = NULL ;
int ret ;
req = tevent_req_create ( mem_ctx , & state ,
struct catia_pwrite_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > fsp = fsp ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( state , handle , fsp , & state - > cc ) ;
if ( ret ! = 0 ) {
tevent_req_error ( req , errno ) ;
return tevent_req_post ( req , ev ) ;
}
subreq = SMB_VFS_NEXT_PWRITE_SEND ( state , ev , handle , fsp , data ,
n , offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , catia_pwrite_done , req ) ;
return req ;
}
static void catia_pwrite_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct catia_pwrite_state * state = tevent_req_data (
req , struct catia_pwrite_state ) ;
state - > ret = SMB_VFS_PWRITE_RECV ( subreq , & state - > vfs_aio_state ) ;
TALLOC_FREE ( subreq ) ;
CATIA_FETCH_FSP_POST_NEXT ( & state - > cc , state - > fsp ) ;
tevent_req_done ( req ) ;
}
static ssize_t catia_pwrite_recv ( struct tevent_req * req ,
struct vfs_aio_state * vfs_aio_state )
{
struct catia_pwrite_state * state = tevent_req_data (
req , struct catia_pwrite_state ) ;
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
return - 1 ;
}
* vfs_aio_state = state - > vfs_aio_state ;
return state - > ret ;
}
static off_t catia_lseek ( vfs_handle_struct * handle ,
files_struct * fsp ,
off_t offset ,
int whence )
{
struct catia_cache * cc = NULL ;
ssize_t result ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
result = SMB_VFS_NEXT_LSEEK ( handle , fsp , offset , whence ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static int catia_fsync ( vfs_handle_struct * handle , files_struct * fsp )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ret = SMB_VFS_NEXT_FSYNC ( handle , fsp ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
struct catia_fsync_state {
int ret ;
struct vfs_aio_state vfs_aio_state ;
struct files_struct * fsp ;
struct catia_cache * cc ;
} ;
static void catia_fsync_done ( struct tevent_req * subreq ) ;
static struct tevent_req * catia_fsync_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp )
{
struct tevent_req * req = NULL , * subreq = NULL ;
struct catia_fsync_state * state = NULL ;
int ret ;
req = tevent_req_create ( mem_ctx , & state ,
struct catia_fsync_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > fsp = fsp ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( state , handle , fsp , & state - > cc ) ;
if ( ret ! = 0 ) {
tevent_req_error ( req , errno ) ;
return tevent_req_post ( req , ev ) ;
}
subreq = SMB_VFS_NEXT_FSYNC_SEND ( state , ev , handle , fsp ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , catia_fsync_done , req ) ;
return req ;
}
static void catia_fsync_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct catia_fsync_state * state = tevent_req_data (
req , struct catia_fsync_state ) ;
state - > ret = SMB_VFS_FSYNC_RECV ( subreq , & state - > vfs_aio_state ) ;
TALLOC_FREE ( subreq ) ;
CATIA_FETCH_FSP_POST_NEXT ( & state - > cc , state - > fsp ) ;
tevent_req_done ( req ) ;
}
static int catia_fsync_recv ( struct tevent_req * req ,
struct vfs_aio_state * vfs_aio_state )
{
struct catia_fsync_state * state = tevent_req_data (
req , struct catia_fsync_state ) ;
if ( tevent_req_is_unix_error ( req , & vfs_aio_state - > error ) ) {
return - 1 ;
}
* vfs_aio_state = state - > vfs_aio_state ;
return state - > ret ;
}
static bool catia_lock ( vfs_handle_struct * handle ,
files_struct * fsp ,
int op ,
off_t offset ,
off_t count ,
int type )
{
struct catia_cache * cc = NULL ;
bool ok ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ok = SMB_VFS_NEXT_LOCK ( handle , fsp , op , offset , count , type ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ok ;
}
static int catia_kernel_flock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
uint32_t share_mode ,
uint32_t access_mask )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ret = SMB_VFS_NEXT_KERNEL_FLOCK ( handle , fsp , share_mode , access_mask ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static int catia_linux_setlease ( vfs_handle_struct * handle ,
files_struct * fsp ,
int leasetype )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ret = SMB_VFS_NEXT_LINUX_SETLEASE ( handle , fsp , leasetype ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ret ;
}
static bool catia_getlock ( vfs_handle_struct * handle ,
files_struct * fsp ,
off_t * poffset ,
off_t * pcount ,
int * ptype ,
pid_t * ppid )
{
struct catia_cache * cc = NULL ;
int ret ;
bool ok ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ok = SMB_VFS_NEXT_GETLOCK ( handle , fsp , poffset , pcount , ptype , ppid ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ok ;
}
static bool catia_strict_lock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct lock_struct * plock )
{
struct catia_cache * cc = NULL ;
int ret ;
bool ok ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
ok = SMB_VFS_NEXT_STRICT_LOCK ( handle , fsp , plock ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return ok ;
}
static void catia_strict_unlock ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
struct lock_struct * plock )
{
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
smb_panic ( " CATIA_FETCH_FSP_PRE_NEXT failed \n " ) ;
}
SMB_VFS_NEXT_STRICT_UNLOCK ( handle , fsp , plock ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
}
static NTSTATUS catia_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 )
{
NTSTATUS result ;
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
result = SMB_VFS_NEXT_FSCTL ( handle ,
fsp ,
ctx ,
function ,
req_flags ,
_in_data ,
in_len ,
_out_data ,
max_out_len ,
out_len ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static NTSTATUS catia_get_compression ( vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct files_struct * fsp ,
struct smb_filename * smb_fname ,
uint16_t * _compression_fmt )
{
NTSTATUS result ;
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
result = SMB_VFS_NEXT_GET_COMPRESSION ( handle , mem_ctx , fsp , smb_fname ,
_compression_fmt ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static NTSTATUS catia_set_compression ( vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct files_struct * fsp ,
uint16_t compression_fmt )
{
NTSTATUS result ;
struct catia_cache * cc = NULL ;
int ret ;
ret = CATIA_FETCH_FSP_PRE_NEXT ( talloc_tos ( ) , handle , fsp , & cc ) ;
if ( ret ! = 0 ) {
return map_nt_error_from_unix ( errno ) ;
}
result = SMB_VFS_NEXT_SET_COMPRESSION ( handle , mem_ctx , fsp ,
compression_fmt ) ;
CATIA_FETCH_FSP_POST_NEXT ( & cc , fsp ) ;
return result ;
}
static struct vfs_fn_pointers vfs_catia_fns = {
/* Directory operations */
. mkdir_fn = catia_mkdir ,
. rmdir_fn = catia_rmdir ,
. opendir_fn = catia_opendir ,
/* File operations */
. open_fn = catia_open ,
. pread_fn = catia_pread ,
. pread_send_fn = catia_pread_send ,
. pread_recv_fn = catia_pread_recv ,
. pwrite_fn = catia_pwrite ,
. pwrite_send_fn = catia_pwrite_send ,
. pwrite_recv_fn = catia_pwrite_recv ,
. lseek_fn = catia_lseek ,
. rename_fn = catia_rename ,
. fsync_fn = catia_fsync ,
. fsync_send_fn = catia_fsync_send ,
. fsync_recv_fn = catia_fsync_recv ,
. stat_fn = catia_stat ,
. fstat_fn = catia_fstat ,
. lstat_fn = catia_lstat ,
. unlink_fn = catia_unlink ,
. chmod_fn = catia_chmod ,
. fchmod_fn = catia_fchmod ,
. chown_fn = catia_chown ,
. fchown_fn = catia_fchown ,
. lchown_fn = catia_lchown ,
. chdir_fn = catia_chdir ,
. ntimes_fn = catia_ntimes ,
. ftruncate_fn = catia_ftruncate ,
. fallocate_fn = catia_fallocate ,
. lock_fn = catia_lock ,
. kernel_flock_fn = catia_kernel_flock ,
. linux_setlease_fn = catia_linux_setlease ,
. getlock_fn = catia_getlock ,
. realpath_fn = catia_realpath ,
. chflags_fn = catia_chflags ,
. streaminfo_fn = catia_streaminfo ,
. strict_lock_fn = catia_strict_lock ,
. strict_unlock_fn = catia_strict_unlock ,
. translate_name_fn = catia_translate_name ,
. fsctl_fn = catia_fsctl ,
. fset_dos_attributes_fn = catia_fset_dos_attributes ,
. fget_dos_attributes_fn = catia_fget_dos_attributes ,
. get_compression_fn = catia_get_compression ,
. set_compression_fn = catia_set_compression ,
/* NT ACL operations. */
. get_nt_acl_fn = catia_get_nt_acl ,
. fget_nt_acl_fn = catia_fget_nt_acl ,
. fset_nt_acl_fn = catia_fset_nt_acl ,
/* POSIX ACL operations. */
. chmod_acl_fn = catia_chmod_acl ,
. fchmod_acl_fn = catia_fchmod_acl ,
. sys_acl_get_file_fn = catia_sys_acl_get_file ,
. sys_acl_get_fd_fn = catia_sys_acl_get_fd ,
. sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd ,
. sys_acl_set_file_fn = catia_sys_acl_set_file ,
. sys_acl_set_fd_fn = catia_sys_acl_set_fd ,
. sys_acl_delete_def_file_fn = catia_sys_acl_delete_def_file ,
/* EA operations. */
2011-12-04 08:45:04 +04:00
. getxattr_fn = catia_getxattr ,
. listxattr_fn = catia_listxattr ,
. removexattr_fn = catia_removexattr ,
. setxattr_fn = catia_setxattr ,
2016-12-06 17:00:58 +03:00
. fgetxattr_fn = catia_fgetxattr ,
. flistxattr_fn = catia_flistxattr ,
. fremovexattr_fn = catia_fremovexattr ,
. fsetxattr_fn = catia_fsetxattr ,
2005-03-18 16:13:38 +03:00
} ;
2015-08-13 19:16:20 +03:00
static_decl_vfs ;
2006-07-11 22:01:26 +04:00
NTSTATUS vfs_catia_init ( void )
2005-03-18 16:13:38 +03:00
{
2013-02-27 08:34:05 +04:00
NTSTATUS ret ;
ret = smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " catia " ,
2009-07-24 04:28:58 +04:00
& vfs_catia_fns ) ;
2013-02-27 08:34:05 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) )
return ret ;
vfs_catia_debug_level = debug_add_class ( " catia " ) ;
if ( vfs_catia_debug_level = = - 1 ) {
vfs_catia_debug_level = DBGC_VFS ;
DEBUG ( 0 , ( " vfs_catia: Couldn't register custom debugging "
" class! \n " ) ) ;
} else {
DEBUG ( 10 , ( " vfs_catia: Debug class number of "
" 'catia': %d \n " , vfs_catia_debug_level ) ) ;
}
return ret ;
2005-03-18 16:13:38 +03:00
}