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 .
*
* Yes , this a BAD BAD UGLY INCOMPLETE hack , but it helps quite some people
* out there . Catia V4 on AIX uses characters like " <*$ a *lot*, all forbidden
* under Windows . . .
*
* Copyright ( C ) Volker Lendecke , 2005
2009-08-27 01:55:38 +04:00
* Copyright ( C ) Aravind Srinivasan , 2009
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"
2005-03-18 16:13:38 +03:00
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 ;
} ;
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 ;
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 )
*
* multiple mappings are comma seperated in smb . conf
*/
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 ;
}
}
ret - > next = srt_head ;
srt_head = ret ;
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 ;
} else if ( global - > mappings ) {
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 ,
int 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
}
2006-07-11 22:01:26 +04:00
static SMB_STRUCT_DIR * catia_opendir ( vfs_handle_struct * handle ,
2009-08-27 01:55:38 +04:00
const char * fname ,
const char * mask ,
uint32 attr )
2005-03-18 16:13:38 +03:00
{
2009-08-27 01:55:38 +04:00
char * name_mapped = NULL ;
NTSTATUS status ;
SMB_STRUCT_DIR * ret ;
2005-03-18 16:13:38 +03:00
2009-08-27 01:55:38 +04:00
status = catia_string_replace_allocate ( handle - > conn , fname ,
2009-09-04 00:46:10 +04:00
& 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
ret = SMB_VFS_NEXT_OPENDIR ( handle , name_mapped , mask , attr ) ;
TALLOC_FREE ( name_mapped ) ;
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 ;
2009-08-27 01:55:38 +04:00
NTSTATUS 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
}
2009-08-27 01:55:38 +04:00
ret = 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 ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
return ret ;
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 ) ;
} else {
TALLOC_FREE ( mapped_name ) ;
}
2009-08-27 01:55:38 +04:00
return ret ;
2005-03-18 16:13:38 +03:00
}
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
{
2009-08-27 01:55:38 +04:00
char * name_mapped = NULL ;
2009-06-16 23:01:13 +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
tmp_base_name = smb_fname - > base_name ;
status = catia_string_replace_allocate ( handle - > conn ,
smb_fname - > base_name ,
2009-09-04 00:46:10 +04:00
& 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 - 1 ;
}
2009-06-16 23:01:13 +04:00
2009-08-27 01:55:38 +04:00
smb_fname - > base_name = name_mapped ;
2009-07-07 22:40:39 +04:00
ret = SMB_VFS_NEXT_OPEN ( handle , smb_fname , fsp , flags , mode ) ;
2009-08-27 01:55:38 +04:00
smb_fname - > base_name = tmp_base_name ;
TALLOC_FREE ( name_mapped ) ;
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. */
2009-08-27 01:55:38 +04:00
status = copy_smb_filename ( ctx , smb_fname_src , & smb_fname_src_tmp ) ;
2009-07-01 04:04:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
goto out ;
}
2009-08-27 01:55:38 +04:00
status = copy_smb_filename ( ctx , smb_fname_dst , & smb_fname_dst_tmp ) ;
2009-07-01 04:04:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
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. */
2009-08-27 01:55:38 +04:00
status = copy_smb_filename ( talloc_tos ( ) , smb_fname , & smb_fname_tmp ) ;
2009-07-02 20:27:44 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
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 ,
const char * path ,
uid_t uid ,
gid_t gid )
{
char * name = NULL ;
NTSTATUS status ;
int ret ;
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_CHOWN ( handle , name , uid , gid ) ;
TALLOC_FREE ( name ) ;
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 ,
const char * path ,
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 ;
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 ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_LCHOWN ( handle , name , uid , gid ) ;
TALLOC_FREE ( name ) ;
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-08-27 01:55:38 +04:00
static int catia_rmdir ( vfs_handle_struct * handle ,
const char * path )
2005-03-18 16:13:38 +03:00
{
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 ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_RMDIR ( handle , name ) ;
TALLOC_FREE ( name ) ;
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 ,
const char * path ,
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 ;
2007-05-24 03:55:12 +04: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 ) ;
2007-11-17 04:07:11 +03:00
return - 1 ;
}
2009-08-27 01:55:38 +04:00
ret = SMB_VFS_NEXT_MKDIR ( handle , name , mode ) ;
TALLOC_FREE ( name ) ;
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 ;
}
status = copy_smb_filename ( talloc_tos ( ) , smb_fname , & smb_fname_tmp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
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 ,
const char * path ,
TALLOC_CTX * mem_ctx ,
unsigned int * num_streams ,
struct stream_struct * * streams )
{
char * mapped_name = NULL ;
NTSTATUS status ;
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 status ;
}
status = SMB_VFS_NEXT_STREAMINFO ( handle , fsp , mapped_name ,
mem_ctx , num_streams , streams ) ;
TALLOC_FREE ( mapped_name ) ;
return status ;
}
static NTSTATUS
catia_get_nt_acl ( struct vfs_handle_struct * handle ,
const char * path ,
uint32 security_info ,
struct security_descriptor * * ppdesc )
{
char * mapped_name = NULL ;
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 ;
}
status = SMB_VFS_NEXT_GET_NT_ACL ( handle , mapped_name ,
security_info , ppdesc ) ;
TALLOC_FREE ( mapped_name ) ;
return status ;
}
static int
catia_chmod_acl ( vfs_handle_struct * handle ,
const char * path ,
mode_t mode )
{
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_CHMOD_ACL ( handle , mapped_name , mode ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
}
static SMB_ACL_T
catia_sys_acl_get_file ( vfs_handle_struct * handle ,
const char * path ,
SMB_ACL_TYPE_T type )
{
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 ;
}
ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE ( handle , mapped_name , type ) ;
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_lgetxattr ( 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_LGETXATTR ( 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 ssize_t
catia_llistxattr ( 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_LLISTXATTR ( 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_lremovexattr ( 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_LREMOVEXATTR ( 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 ;
}
static int
catia_lsetxattr ( 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 ) ;
return - 1 ;
}
ret = SMB_VFS_NEXT_LSETXATTR ( handle , path , mapped_name , value , size , flags ) ;
TALLOC_FREE ( mapped_name ) ;
return ret ;
2005-03-18 16:13:38 +03:00
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_catia_fns = {
2009-08-27 01:55:38 +04:00
. mkdir = catia_mkdir ,
. rmdir = catia_rmdir ,
2009-07-24 04:28:58 +04:00
. opendir = catia_opendir ,
2011-04-21 00:55:25 +04:00
. open_fn = catia_open ,
2009-07-24 04:28:58 +04:00
. rename = catia_rename ,
. stat = catia_stat ,
. lstat = catia_lstat ,
. unlink = catia_unlink ,
. chown = catia_chown ,
. lchown = catia_lchown ,
. chdir = catia_chdir ,
2009-08-27 01:55:38 +04:00
. ntimes = catia_ntimes ,
. realpath = catia_realpath ,
. chflags = catia_chflags ,
. streaminfo = catia_streaminfo ,
. translate_name = catia_translate_name ,
. get_nt_acl = catia_get_nt_acl ,
. chmod_acl = catia_chmod_acl ,
. sys_acl_get_file = catia_sys_acl_get_file ,
. sys_acl_set_file = catia_sys_acl_set_file ,
. sys_acl_delete_def_file = catia_sys_acl_delete_def_file ,
. getxattr = catia_getxattr ,
. lgetxattr = catia_lgetxattr ,
. listxattr = catia_listxattr ,
. llistxattr = catia_llistxattr ,
. removexattr = catia_removexattr ,
. lremovexattr = catia_lremovexattr ,
. setxattr = catia_setxattr ,
. lsetxattr = catia_lsetxattr ,
2005-03-18 16:13:38 +03:00
} ;
2006-07-11 22:01:26 +04:00
NTSTATUS vfs_catia_init ( void )
2005-03-18 16:13:38 +03:00
{
2007-11-17 04:07:11 +03:00
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " catia " ,
2009-07-24 04:28:58 +04:00
& vfs_catia_fns ) ;
2005-03-18 16:13:38 +03:00
}