2004-12-17 03:39:29 +00:00
/*
Unix SMB / CIFS implementation .
POSIX NTVFS backend - xattr support using filesystem xattrs
Copyright ( C ) Andrew Tridgell 2004
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-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-12-17 03:39:29 +00:00
( 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
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-12-17 03:39:29 +00:00
*/
# include "includes.h"
# include "vfs_posix.h"
2006-06-02 14:06:30 +00:00
2004-12-17 03:39:29 +00:00
/*
pull a xattr as a blob , from either a file or a file descriptor
*/
NTSTATUS pull_xattr_blob_system ( struct pvfs_state * pvfs ,
TALLOC_CTX * mem_ctx ,
const char * attr_name ,
const char * fname ,
int fd ,
size_t estimated_size ,
DATA_BLOB * blob )
{
int ret ;
2005-05-02 15:59:34 +00:00
* blob = data_blob_talloc ( mem_ctx , NULL , estimated_size + 16 ) ;
2004-12-17 03:39:29 +00:00
if ( blob - > data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
again :
if ( fd ! = - 1 ) {
2012-06-01 13:41:46 +10:00
ret = fgetxattr ( fd , attr_name , blob - > data , estimated_size ) ;
2004-12-17 03:39:29 +00:00
} else {
2012-06-01 13:41:46 +10:00
ret = getxattr ( fname , attr_name , blob - > data , estimated_size ) ;
2004-12-17 03:39:29 +00:00
}
if ( ret = = - 1 & & errno = = ERANGE ) {
estimated_size * = 2 ;
2005-01-07 04:39:16 +00:00
blob - > data = talloc_realloc ( mem_ctx , blob - > data ,
uint8_t , estimated_size ) ;
2004-12-17 03:39:29 +00:00
if ( blob - > data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
blob - > length = estimated_size ;
goto again ;
}
2006-09-09 23:50:44 +00:00
if ( ret = = - 1 & & errno = = EPERM ) {
struct stat statbuf ;
if ( fd ! = - 1 ) {
ret = fstat ( fd , & statbuf ) ;
} else {
ret = stat ( fname , & statbuf ) ;
}
if ( ret = = 0 ) {
/* check if this is a directory and the sticky bit is set */
if ( S_ISDIR ( statbuf . st_mode ) & & ( statbuf . st_mode & S_ISVTX ) ) {
/* pretend we could not find the xattr */
data_blob_free ( blob ) ;
return NT_STATUS_NOT_FOUND ;
} else {
2008-07-24 14:19:49 +10:00
/* if not this was probably a legitimate error
2006-09-09 23:50:44 +00:00
* reset ret and errno to the correct values */
errno = EPERM ;
ret = - 1 ;
}
}
}
2004-12-17 03:39:29 +00:00
if ( ret = = - 1 ) {
data_blob_free ( blob ) ;
return pvfs_map_errno ( pvfs , errno ) ;
}
blob - > length = ret ;
return NT_STATUS_OK ;
}
/*
push a xattr as a blob , from either a file or a file descriptor
*/
NTSTATUS push_xattr_blob_system ( struct pvfs_state * pvfs ,
const char * attr_name ,
const char * fname ,
int fd ,
const DATA_BLOB * blob )
{
int ret ;
if ( fd ! = - 1 ) {
2012-06-01 13:41:46 +10:00
ret = fsetxattr ( fd , attr_name , blob - > data , blob - > length , 0 ) ;
2004-12-17 03:39:29 +00:00
} else {
2012-06-01 13:41:46 +10:00
ret = setxattr ( fname , attr_name , blob - > data , blob - > length , 0 ) ;
2004-12-17 03:39:29 +00:00
}
if ( ret = = - 1 ) {
return pvfs_map_errno ( pvfs , errno ) ;
}
return NT_STATUS_OK ;
}
/*
delete a xattr
*/
NTSTATUS delete_xattr_system ( struct pvfs_state * pvfs , const char * attr_name ,
const char * fname , int fd )
{
int ret ;
if ( fd ! = - 1 ) {
2012-06-01 13:41:46 +10:00
ret = fremovexattr ( fd , attr_name ) ;
2004-12-17 03:39:29 +00:00
} else {
2012-06-01 13:41:46 +10:00
ret = removexattr ( fname , attr_name ) ;
2004-12-17 03:39:29 +00:00
}
if ( ret = = - 1 ) {
return pvfs_map_errno ( pvfs , errno ) ;
}
return NT_STATUS_OK ;
}
/*
unlink a file - cleanup any xattrs
*/
NTSTATUS unlink_xattr_system ( struct pvfs_state * pvfs , const char * fname )
{
/* nothing needs to be done for filesystem based xattrs */
return NT_STATUS_OK ;
}