2016-06-02 09:38:31 +03:00
/*
Unix SMB / CIFS implementation .
Wrap VxFS xattr calls .
Copyright ( C ) Veritas Technologies LLC < www . veritas . com > 2016
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "smbd/smbd.h"
# include "system/filesys.h"
# include "string.h"
2017-08-27 14:54:32 +03:00
# include "vfs_vxfs.h"
2016-06-02 09:38:31 +03:00
/*
* Available under GPL at
* http : //www.veritas.com/community/downloads/vxfsmisc-library
*/
# define LIBVXFS " / usr / lib64 / vxfsmisc.so"
static int ( * vxfs_setxattr_fd_func ) ( int fd , const char * name ,
const void * value , size_t len , int flags ) ;
static int ( * vxfs_getxattr_fd_func ) ( int fd , const char * name , void * value ,
size_t * len ) ;
static int ( * vxfs_removexattr_fd_func ) ( int fd , const char * name ) ;
static int ( * vxfs_listxattr_fd_func ) ( int fd , void * value , size_t * len ) ;
2017-08-27 14:54:32 +03:00
static int ( * vxfs_setwxattr_fd_func ) ( int fd ) ;
static int ( * vxfs_checkwxattr_fd_func ) ( int fd ) ;
2016-06-02 09:38:31 +03:00
int vxfs_setxattr_fd ( int fd , const char * name , const void * value ,
size_t len , int flags )
{
int ret = - 1 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_setxattr_fd fd %d name %s len %zu flags %d \n " ,
fd , name , len , flags ) ;
2016-06-02 09:38:31 +03:00
if ( vxfs_setxattr_fd_func = = NULL ) {
errno = ENOSYS ;
return ret ;
}
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " Calling vxfs_setxattr_fd \n " ) ;
2016-06-02 09:38:31 +03:00
ret = vxfs_setxattr_fd_func ( fd , name , value , len , flags ) ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " vxfs_setxattr_fd ret = %d \n " , ret ) ;
2016-06-02 09:38:31 +03:00
if ( ret ) {
errno = ret ;
ret = - 1 ;
}
return ret ;
}
int vxfs_getxattr_fd ( int fd , const char * name , void * value , size_t len )
{
int ret ;
size_t size = len ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_getxattr_fd fd %d name %s len %zu \n " ,
fd , name , len ) ;
2016-06-02 09:38:31 +03:00
if ( vxfs_getxattr_fd_func = = NULL ) {
errno = ENOSYS ;
return - 1 ;
}
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " Calling vxfs_getxattr_fd with %s \n " , name ) ;
2016-06-02 09:38:31 +03:00
ret = vxfs_getxattr_fd_func ( fd , name , value , & size ) ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " vxfs_getxattr_fd ret = %d \n " , ret ) ;
2016-06-02 09:38:31 +03:00
if ( ret ) {
errno = ret ;
if ( ret = = EFBIG ) {
errno = ERANGE ;
}
return - 1 ;
}
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " vxfs_getxattr_fd done with size %zu \n " , size ) ;
2016-06-02 09:38:31 +03:00
return size ;
}
int vxfs_getxattr_path ( const char * path , const char * name , void * value ,
size_t len )
{
int ret , fd = - 1 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_getxattr_path path %s name %s len %zu \n " ,
path , name , len ) ;
2016-06-02 09:38:31 +03:00
fd = open ( path , O_RDONLY ) ;
if ( fd = = - 1 ) {
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " file not opened: vxfs_getxattr_path for %s \n " ,
path ) ;
2016-06-02 09:38:31 +03:00
return - 1 ;
}
ret = vxfs_getxattr_fd ( fd , name , value , len ) ;
close ( fd ) ;
return ret ;
}
int vxfs_removexattr_fd ( int fd , const char * name )
{
int ret = 0 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_removexattr_fd fd %d name %s \n " , fd , name ) ;
2016-06-02 09:38:31 +03:00
if ( vxfs_removexattr_fd_func = = NULL ) {
errno = ENOSYS ;
return - 1 ;
}
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " Calling vxfs_removexattr_fd with %s \n " , name ) ;
2016-06-02 09:38:31 +03:00
ret = vxfs_removexattr_fd_func ( fd , name ) ;
if ( ret ) {
errno = ret ;
ret = - 1 ;
}
return ret ;
}
int vxfs_listxattr_fd ( int fd , char * list , size_t size )
{
int ret ;
size_t len = size ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_listxattr_fd fd %d list %s size %zu \n " , fd , list , size ) ;
2016-06-02 09:38:31 +03:00
if ( vxfs_listxattr_fd_func = = NULL ) {
errno = ENOSYS ;
return - 1 ;
}
ret = vxfs_listxattr_fd_func ( fd , list , & len ) ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " vxfs_listxattr_fd: returned ret = %d \n " , ret ) ;
DBG_DEBUG ( " In vxfs_listxattr_fd done with len %zu \n " , len ) ;
2016-06-02 09:38:31 +03:00
if ( ret ) {
errno = ret ;
if ( ret = = EFBIG ) {
errno = ERANGE ;
}
return - 1 ;
}
return len ;
}
2017-08-27 14:54:32 +03:00
int vxfs_setwxattr_fd ( int fd )
{
int ret = 0 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_setwxattr_fd fd %d \n " , fd ) ;
2017-08-27 14:54:32 +03:00
if ( vxfs_setwxattr_fd_func = = NULL ) {
errno = ENOSYS ;
return - 1 ;
}
ret = vxfs_setwxattr_fd_func ( fd ) ;
DBG_DEBUG ( " ret = %d \n " , ret ) ;
if ( ret ! = 0 ) {
errno = ret ;
ret = - 1 ;
}
return ret ;
}
2018-07-10 08:47:42 +03:00
int vxfs_setwxattr_path ( const char * path , bool is_dir )
2017-08-27 14:54:32 +03:00
{
int ret , fd = - 1 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_setwxattr_path path %s is_dir %d \n " , path , is_dir ) ;
2017-08-27 14:54:32 +03:00
2018-07-10 08:47:42 +03:00
if ( is_dir ) {
fd = open ( path , O_RDONLY | O_DIRECTORY ) ;
} else {
fd = open ( path , O_WRONLY ) ;
}
2017-08-27 14:54:32 +03:00
if ( fd = = - 1 ) {
DBG_DEBUG ( " file %s not opened, errno:%s \n " ,
path , strerror ( errno ) ) ;
return - 1 ;
}
ret = vxfs_setwxattr_fd ( fd ) ;
DBG_DEBUG ( " ret = %d \n " , ret ) ;
close ( fd ) ;
return ret ;
}
int vxfs_checkwxattr_fd ( int fd )
{
int ret ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_checkwxattr_fd fd %d \n " , fd ) ;
2017-08-27 14:54:32 +03:00
if ( vxfs_checkwxattr_fd_func = = NULL ) {
errno = ENOSYS ;
return - 1 ;
}
ret = vxfs_checkwxattr_fd_func ( fd ) ;
DBG_DEBUG ( " ret = %d \n " , ret ) ;
if ( ret ! = 0 ) {
errno = ret ;
ret = - 1 ;
}
return ret ;
}
int vxfs_checkwxattr_path ( const char * path )
{
int ret , fd = - 1 ;
2022-03-03 17:13:24 +03:00
DBG_DEBUG ( " In vxfs_checkwxattr_path path %s \n " , path ) ;
2017-08-27 14:54:32 +03:00
2018-07-10 08:47:42 +03:00
fd = open ( path , O_RDONLY ) ;
2017-08-27 14:54:32 +03:00
if ( fd = = - 1 ) {
DBG_DEBUG ( " file %s not opened, errno:%s \n " ,
path , strerror ( errno ) ) ;
return - 1 ;
}
ret = vxfs_checkwxattr_fd ( fd ) ;
close ( fd ) ;
return ret ;
}
2016-06-02 09:38:31 +03:00
static bool load_lib_vxfs_function ( void * lib_handle , void * fn_ptr ,
const char * fnc_name )
{
void * * vlib_handle = ( void * * ) lib_handle ;
void * * fn_pointer = ( void * * ) fn_ptr ;
* fn_pointer = dlsym ( * vlib_handle , fnc_name ) ;
if ( * fn_pointer = = NULL ) {
DEBUG ( 10 , ( " Cannot find symbol for %s \n " , fnc_name ) ) ;
return true ;
}
return false ;
}
void vxfs_init ( )
{
static void * lib_handle = NULL ;
if ( lib_handle ! = NULL ) {
return ;
}
lib_handle = dlopen ( LIBVXFS , RTLD_LAZY ) ;
if ( lib_handle = = NULL ) {
DEBUG ( 10 , ( " Cannot get lib handle \n " ) ) ;
return ;
}
DEBUG ( 10 , ( " Calling vxfs_init \n " ) ) ;
load_lib_vxfs_function ( & lib_handle , & vxfs_setxattr_fd_func ,
" vxfs_nxattr_set " ) ;
load_lib_vxfs_function ( & lib_handle , & vxfs_getxattr_fd_func ,
" vxfs_nxattr_get " ) ;
load_lib_vxfs_function ( & lib_handle , & vxfs_removexattr_fd_func ,
" vxfs_nxattr_remove " ) ;
load_lib_vxfs_function ( & lib_handle , & vxfs_listxattr_fd_func ,
" vxfs_nxattr_list " ) ;
2017-08-27 14:54:32 +03:00
load_lib_vxfs_function ( & lib_handle , & vxfs_setwxattr_fd_func ,
" vxfs_wattr_set " ) ;
load_lib_vxfs_function ( & lib_handle , & vxfs_checkwxattr_fd_func ,
" vxfs_wattr_check " ) ;
2016-06-02 09:38:31 +03:00
}