2008-09-17 02:55:06 +04:00
/*
* Store Windows ACLs in xattrs .
*
* Copyright ( C ) Volker Lendecke , 2008
* Copyright ( C ) Jeremy Allison , 2008
*
* 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/>.
*/
2008-09-17 23:34:09 +04:00
/* NOTE: This is an experimental module, not yet finished. JRA. */
2008-09-17 02:55:06 +04:00
# include "includes.h"
# include "librpc/gen_ndr/xattr.h"
# include "librpc/gen_ndr/ndr_xattr.h"
2009-07-25 01:09:42 +04:00
# include "../lib/crypto/crypto.h"
2008-09-17 02:55:06 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
2009-07-27 23:09:40 +04:00
/* Pull in the common functions. */
# include "modules/vfs_acl_common.c"
2008-11-11 04:57:22 +03:00
/*******************************************************************
Pull a security descriptor into a DATA_BLOB from a xattr .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-27 23:09:40 +04:00
static NTSTATUS get_acl_blob ( TALLOC_CTX * ctx ,
2008-09-17 23:34:09 +04:00
vfs_handle_struct * handle ,
2008-09-17 02:55:06 +04:00
files_struct * fsp ,
const char * name ,
DATA_BLOB * pblob )
{
size_t size = 1024 ;
uint8_t * val = NULL ;
uint8_t * tmp ;
ssize_t sizeret ;
2008-10-08 07:16:04 +04:00
int saved_errno = 0 ;
2008-09-17 02:55:06 +04:00
ZERO_STRUCTP ( pblob ) ;
again :
tmp = TALLOC_REALLOC_ARRAY ( ctx , val , uint8_t , size ) ;
if ( tmp = = NULL ) {
TALLOC_FREE ( val ) ;
return NT_STATUS_NO_MEMORY ;
}
val = tmp ;
become_root ( ) ;
2008-09-18 00:44:29 +04:00
if ( fsp & & fsp - > fh - > fd ! = - 1 ) {
2008-09-17 02:55:06 +04:00
sizeret = SMB_VFS_FGETXATTR ( fsp , XATTR_NTACL_NAME , val , size ) ;
} else {
sizeret = SMB_VFS_GETXATTR ( handle - > conn , name ,
XATTR_NTACL_NAME , val , size ) ;
}
if ( sizeret = = - 1 ) {
saved_errno = errno ;
}
unbecome_root ( ) ;
/* Max ACL size is 65536 bytes. */
if ( sizeret = = - 1 ) {
errno = saved_errno ;
if ( ( errno = = ERANGE ) & & ( size ! = 65536 ) ) {
/* Too small, try again. */
size = 65536 ;
goto again ;
}
/* Real error - exit here. */
TALLOC_FREE ( val ) ;
return map_nt_error_from_unix ( errno ) ;
}
pblob - > data = val ;
pblob - > length = sizeret ;
return NT_STATUS_OK ;
}
2008-11-11 04:57:22 +03:00
/*******************************************************************
Store a DATA_BLOB into an xattr given an fsp pointer .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-27 23:09:40 +04:00
static NTSTATUS store_acl_blob_fsp ( vfs_handle_struct * handle ,
2008-11-11 04:57:22 +03:00
files_struct * fsp ,
2008-10-29 23:27:14 +03:00
DATA_BLOB * pblob )
{
int ret ;
int saved_errno = 0 ;
2008-10-30 23:51:28 +03:00
DEBUG ( 10 , ( " store_acl_blob_fsp: storing blob length %u on file %s \n " ,
2009-07-11 05:11:32 +04:00
( unsigned int ) pblob - > length , fsp_str_dbg ( fsp ) ) ) ;
2008-10-29 23:27:14 +03:00
become_root ( ) ;
if ( fsp - > fh - > fd ! = - 1 ) {
ret = SMB_VFS_FSETXATTR ( fsp , XATTR_NTACL_NAME ,
pblob - > data , pblob - > length , 0 ) ;
} else {
2009-07-11 05:11:32 +04:00
ret = SMB_VFS_SETXATTR ( fsp - > conn , fsp - > fsp_name - > base_name ,
2008-10-29 23:27:14 +03:00
XATTR_NTACL_NAME ,
pblob - > data , pblob - > length , 0 ) ;
}
if ( ret ) {
saved_errno = errno ;
}
unbecome_root ( ) ;
if ( ret ) {
errno = saved_errno ;
2008-10-30 23:51:28 +03:00
DEBUG ( 5 , ( " store_acl_blob_fsp: setting attr failed for file %s "
2008-10-29 23:27:14 +03:00
" with error %s \n " ,
2009-07-11 05:11:32 +04:00
fsp_str_dbg ( fsp ) ,
2008-10-29 23:27:14 +03:00
strerror ( errno ) ) ) ;
return map_nt_error_from_unix ( errno ) ;
}
return NT_STATUS_OK ;
}
2008-11-11 04:57:22 +03:00
/*******************************************************************
Store a DATA_BLOB into an xattr given a pathname .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-27 23:09:40 +04:00
static NTSTATUS store_acl_blob_pathname ( vfs_handle_struct * handle ,
2008-10-30 23:51:28 +03:00
const char * fname ,
DATA_BLOB * pblob )
{
2008-11-11 04:57:22 +03:00
connection_struct * conn = handle - > conn ;
2008-10-30 23:51:28 +03:00
int ret ;
int saved_errno = 0 ;
DEBUG ( 10 , ( " store_acl_blob_pathname: storing blob "
" length %u on file %s \n " ,
( unsigned int ) pblob - > length , fname ) ) ;
become_root ( ) ;
ret = SMB_VFS_SETXATTR ( conn , fname ,
XATTR_NTACL_NAME ,
pblob - > data , pblob - > length , 0 ) ;
if ( ret ) {
saved_errno = errno ;
}
unbecome_root ( ) ;
if ( ret ) {
errno = saved_errno ;
DEBUG ( 5 , ( " store_acl_blob_pathname: setting attr failed "
" for file %s with error %s \n " ,
fname ,
strerror ( errno ) ) ) ;
return map_nt_error_from_unix ( errno ) ;
}
return NT_STATUS_OK ;
}
2008-11-19 23:24:53 +03:00
/*********************************************************************
Remove a Windows ACL - we ' re setting the underlying POSIX ACL .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int sys_acl_set_file_xattr ( vfs_handle_struct * handle ,
const char * name ,
SMB_ACL_TYPE_T type ,
SMB_ACL_T theacl )
{
int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE ( handle ,
name ,
type ,
theacl ) ;
if ( ret = = - 1 ) {
return - 1 ;
}
become_root ( ) ;
SMB_VFS_REMOVEXATTR ( handle - > conn , name , XATTR_NTACL_NAME ) ;
unbecome_root ( ) ;
return ret ;
}
/*********************************************************************
Remove a Windows ACL - we ' re setting the underlying POSIX ACL .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int sys_acl_set_fd_xattr ( vfs_handle_struct * handle ,
files_struct * fsp ,
SMB_ACL_T theacl )
{
int ret = SMB_VFS_NEXT_SYS_ACL_SET_FD ( handle ,
fsp ,
theacl ) ;
if ( ret = = - 1 ) {
return - 1 ;
}
become_root ( ) ;
SMB_VFS_FREMOVEXATTR ( fsp , XATTR_NTACL_NAME ) ;
unbecome_root ( ) ;
return ret ;
}
2008-09-17 02:55:06 +04:00
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_acl_xattr_fns = {
2009-07-25 04:06:41 +04:00
. mkdir = mkdir_acl_common ,
. open = open_acl_common ,
. fget_nt_acl = fget_nt_acl_common ,
. get_nt_acl = get_nt_acl_common ,
. fset_nt_acl = fset_nt_acl_common ,
2009-07-24 04:28:58 +04:00
. sys_acl_set_file = sys_acl_set_file_xattr ,
. sys_acl_set_fd = sys_acl_set_fd_xattr
2008-09-17 02:55:06 +04:00
} ;
NTSTATUS vfs_acl_xattr_init ( void )
{
2009-07-24 04:28:58 +04:00
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " acl_xattr " ,
& vfs_acl_xattr_fns ) ;
2008-09-17 02:55:06 +04:00
}