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/>.
*/
# include "includes.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2008-09-17 02:55:06 +04:00
# include "librpc/gen_ndr/xattr.h"
# include "librpc/gen_ndr/ndr_xattr.h"
2015-11-08 13:34:40 +03:00
# include "../lib/crypto/sha256.h"
2011-03-24 16:15:54 +03:00
# include "auth.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. */
2010-10-16 02:56:09 +04:00
# define ACL_MODULE_NAME "acl_xattr"
2009-07-27 23:09:40 +04:00
# 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 ,
2016-03-12 02:50:57 +03:00
const struct smb_filename * smb_fname ,
2008-09-17 02:55:06 +04:00
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 :
2011-06-07 05:10:15 +04:00
tmp = talloc_realloc ( ctx , val , uint8_t , size ) ;
2008-09-17 02:55:06 +04:00
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 {
2016-03-12 02:50:57 +03:00
sizeret = SMB_VFS_GETXATTR ( handle - > conn , smb_fname - > base_name ,
2008-09-17 02:55:06 +04:00
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 ) {
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 ) ,
2012-05-15 18:47:14 +04:00
strerror ( saved_errno ) ) ) ;
errno = saved_errno ;
return map_nt_error_from_unix ( saved_errno ) ;
2008-10-29 23:27:14 +03:00
}
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 ;
}
2009-11-07 08:53:07 +03:00
static int connect_acl_xattr ( struct vfs_handle_struct * handle ,
const char * service ,
const char * user )
{
2009-12-01 02:53:04 +03:00
int ret = SMB_VFS_NEXT_CONNECT ( handle , service , user ) ;
2016-08-24 11:01:17 +03:00
bool ok ;
2009-12-01 02:53:04 +03:00
if ( ret < 0 ) {
return ret ;
}
2016-08-24 11:01:17 +03:00
ok = init_acl_common_config ( handle ) ;
if ( ! ok ) {
DBG_ERR ( " init_acl_common_config failed \n " ) ;
return - 1 ;
}
2010-10-16 06:54:51 +04:00
/* Ensure we have the parameters correct if we're
2009-11-07 08:53:07 +03:00
* using this module . */
2009-11-12 05:35:18 +03:00
DEBUG ( 2 , ( " connect_acl_xattr: setting 'inherit acls = true' "
2010-10-16 06:54:51 +04:00
" 'dos filemode = true' and "
" 'force unknown acl user = true' for service %s \n " ,
2009-11-07 08:53:07 +03:00
service ) ) ;
2009-11-12 05:35:18 +03:00
lp_do_parameter ( SNUM ( handle - > conn ) , " inherit acls " , " true " ) ;
lp_do_parameter ( SNUM ( handle - > conn ) , " dos filemode " , " true " ) ;
2010-10-16 06:54:51 +04:00
lp_do_parameter ( SNUM ( handle - > conn ) , " force unknown acl user " , " true " ) ;
2009-11-12 05:35:18 +03:00
2009-11-07 08:53:07 +03:00
return 0 ;
}
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-11-07 08:53:07 +03:00
. connect_fn = connect_acl_xattr ,
2011-12-04 08:45:04 +04:00
. rmdir_fn = rmdir_acl_common ,
. unlink_fn = unlink_acl_common ,
. chmod_fn = chmod_acl_module_common ,
. fchmod_fn = fchmod_acl_module_common ,
. fget_nt_acl_fn = fget_nt_acl_common ,
. get_nt_acl_fn = get_nt_acl_common ,
. fset_nt_acl_fn = fset_nt_acl_common ,
. chmod_acl_fn = chmod_acl_acl_module_common ,
. fchmod_acl_fn = fchmod_acl_acl_module_common ,
. sys_acl_set_file_fn = sys_acl_set_file_xattr ,
. sys_acl_set_fd_fn = sys_acl_set_fd_xattr
2008-09-17 02:55:06 +04:00
} ;
2015-08-13 19:16:20 +03:00
static_decl_vfs ;
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
}