2007-05-15 03:55:11 +04:00
/*
* Convert ZFS / NFSv4 acls to NT acls and vice versa .
*
* Copyright ( C ) Jiri Sasek , 2007
* based on the foobar . c module which is copyrighted by Volker Lendecke
*
2007-07-12 22:49:44 +04:00
* Many thanks to Axel Apitz for help to fix the special ace ' s handling
* issues .
*
2007-05-15 03:55:11 +04: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
2007-05-15 03:55:11 +04: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 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-05-15 03:55:11 +04:00
*
*/
# include "includes.h"
2011-03-30 17:14:05 +04:00
# include "system/filesys.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2007-05-15 03:55:11 +04:00
# include "nfs4_acls.h"
2018-11-20 17:54:28 +03:00
# ifdef HAVE_FREEBSD_SUNACL_H
2011-01-29 11:19:54 +03:00
# include "sunacl.h"
# endif
2007-05-15 03:55:11 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
# define ZFSACL_MODULE_NAME "zfsacl"
2019-08-30 22:15:37 +03:00
struct zfsacl_config_data {
struct smbacl4_vfs_params nfs4_params ;
2019-08-30 22:30:57 +03:00
bool zfsacl_map_dacl_protected ;
2019-08-30 22:15:37 +03:00
bool zfsacl_denymissingspecial ;
2020-09-24 18:42:16 +03:00
bool zfsacl_block_special ;
2019-08-30 22:15:37 +03:00
} ;
2007-05-15 03:55:11 +04:00
/* zfs_get_nt_acl()
* read the local file ' s acls and return it in NT form
* using the NFSv4 format conversion
*/
2017-09-06 17:53:23 +03:00
static NTSTATUS zfs_get_nt_acl_common ( struct connection_struct * conn ,
TALLOC_CTX * mem_ctx ,
2017-09-06 17:44:12 +03:00
const struct smb_filename * smb_fname ,
2020-08-20 17:18:35 +03:00
const ace_t * acebuf ,
int naces ,
2019-10-19 16:37:45 +03:00
struct SMB4ACL_T * * ppacl ,
struct zfsacl_config_data * config )
2007-05-15 03:55:11 +04:00
{
2020-08-20 17:18:35 +03:00
int i ;
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * pacl ;
2017-09-06 17:53:23 +03:00
SMB_STRUCT_STAT sbuf ;
const SMB_STRUCT_STAT * psbuf = NULL ;
int ret ;
2019-08-30 22:30:57 +03:00
bool inherited_is_present = false ;
2017-10-28 17:13:16 +03:00
bool is_dir ;
2017-09-06 17:53:23 +03:00
if ( VALID_STAT ( smb_fname - > st ) ) {
psbuf = & smb_fname - > st ;
}
if ( psbuf = = NULL ) {
ret = vfs_stat_smb_basename ( conn , smb_fname , & sbuf ) ;
if ( ret ! = 0 ) {
DBG_INFO ( " stat [%s]failed: %s \n " ,
smb_fname_str_dbg ( smb_fname ) , strerror ( errno ) ) ;
return map_nt_error_from_unix ( errno ) ;
}
psbuf = & sbuf ;
}
2017-10-28 17:13:16 +03:00
is_dir = S_ISDIR ( psbuf - > st_ex_mode ) ;
2017-09-06 17:56:47 +03:00
2007-08-30 23:48:31 +04:00
mem_ctx = talloc_tos ( ) ;
2020-08-20 17:18:35 +03:00
2007-05-15 03:55:11 +04:00
/* create SMB4ACL data */
2013-04-14 12:13:42 +04:00
if ( ( pacl = smb_create_smb4acl ( mem_ctx ) ) = = NULL ) {
2007-11-12 14:49:40 +03:00
return NT_STATUS_NO_MEMORY ;
}
2007-05-15 03:55:11 +04:00
for ( i = 0 ; i < naces ; i + + ) {
SMB_ACE4PROP_T aceprop ;
2020-08-20 17:41:36 +03:00
uint16_t special = 0 ;
2007-05-15 03:55:11 +04:00
2015-05-03 06:11:02 +03:00
aceprop . aceType = ( uint32_t ) acebuf [ i ] . a_type ;
aceprop . aceFlags = ( uint32_t ) acebuf [ i ] . a_flags ;
aceprop . aceMask = ( uint32_t ) acebuf [ i ] . a_access_mask ;
aceprop . who . id = ( uint32_t ) acebuf [ i ] . a_who ;
2007-07-12 22:49:44 +04:00
2020-09-24 18:42:16 +03:00
if ( config - > zfsacl_block_special & &
( aceprop . aceMask = = 0 ) & &
( aceprop . aceFlags & ACE_EVERYONE ) & &
( aceprop . aceFlags & ACE_INHERITED_ACE ) )
{
continue ;
}
2017-09-06 17:28:10 +03:00
/*
* Windows clients expect SYNC on acls to correctly allow
* rename , cf bug # 7909. But not on DENY ace entries , cf bug
* # 8442.
*/
if ( aceprop . aceType = = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE ) {
aceprop . aceMask | = SMB_ACE4_SYNCHRONIZE ;
}
2020-08-20 17:41:36 +03:00
special = acebuf [ i ] . a_flags & ( ACE_OWNER | ACE_GROUP | ACE_EVERYONE ) ;
2020-09-24 23:04:12 +03:00
if ( is_dir & &
( aceprop . aceMask & SMB_ACE4_ADD_FILE ) & &
( special ! = 0 ) )
{
2017-10-28 17:13:16 +03:00
aceprop . aceMask | = SMB_ACE4_DELETE_CHILD ;
}
2019-08-30 22:30:57 +03:00
# ifdef ACE_INHERITED_ACE
if ( aceprop . aceFlags & ACE_INHERITED_ACE ) {
inherited_is_present = true ;
}
# endif
2020-08-20 17:41:36 +03:00
switch ( special ) {
case ( ACE_OWNER ) :
2007-07-12 22:49:44 +04:00
aceprop . flags = SMB_ACE4_ID_SPECIAL ;
aceprop . who . special_id = SMB_ACE4_WHO_OWNER ;
2020-08-20 17:41:36 +03:00
break ;
case ( ACE_GROUP ) :
2007-07-12 22:49:44 +04:00
aceprop . flags = SMB_ACE4_ID_SPECIAL ;
aceprop . who . special_id = SMB_ACE4_WHO_GROUP ;
2020-08-20 17:41:36 +03:00
break ;
case ( ACE_EVERYONE ) :
2007-07-12 22:49:44 +04:00
aceprop . flags = SMB_ACE4_ID_SPECIAL ;
aceprop . who . special_id = SMB_ACE4_WHO_EVERYONE ;
2020-08-20 17:41:36 +03:00
break ;
default :
2007-07-12 22:49:44 +04:00
aceprop . flags = 0 ;
}
2020-08-20 17:42:17 +03:00
if ( smb_add_ace4 ( pacl , & aceprop ) = = NULL ) {
2007-10-13 23:06:49 +04:00
return NT_STATUS_NO_MEMORY ;
2020-08-20 17:42:17 +03:00
}
2007-05-15 03:55:11 +04:00
}
2019-08-30 22:30:57 +03:00
# ifdef ACE_INHERITED_ACE
if ( ! inherited_is_present & & config - > zfsacl_map_dacl_protected ) {
DBG_DEBUG ( " Setting SEC_DESC_DACL_PROTECTED on [%s] \n " ,
smb_fname_str_dbg ( smb_fname ) ) ;
smbacl4_set_controlflags ( pacl ,
SEC_DESC_DACL_PROTECTED |
SEC_DESC_SELF_RELATIVE ) ;
}
# endif
2007-11-16 20:33:39 +03:00
* ppacl = pacl ;
return NT_STATUS_OK ;
2007-05-15 03:55:11 +04:00
}
/* call-back function processing the NT acl -> ZFS acl using NFSv4 conv. */
2015-08-11 13:35:20 +03:00
static bool zfs_process_smbacl ( vfs_handle_struct * handle , files_struct * fsp ,
struct SMB4ACL_T * smbacl )
2007-05-15 03:55:11 +04:00
{
2020-08-20 17:18:35 +03:00
int naces = smb_get_naces ( smbacl ) , i , rv ;
2007-05-15 03:55:11 +04:00
ace_t * acebuf ;
2015-08-11 13:35:20 +03:00
struct SMB4ACE_T * smbace ;
2007-05-15 03:55:11 +04:00
TALLOC_CTX * mem_ctx ;
2010-01-11 14:10:47 +03:00
bool have_special_id = false ;
2020-09-24 18:42:16 +03:00
bool must_add_empty_ace = false ;
2019-08-30 22:15:37 +03:00
struct zfsacl_config_data * config = NULL ;
2021-01-25 11:55:40 +03:00
int fd ;
2019-08-30 22:15:37 +03:00
SMB_VFS_HANDLE_GET_DATA ( handle , config ,
struct zfsacl_config_data ,
return False ) ;
2007-05-15 03:55:11 +04:00
2020-09-24 18:42:16 +03:00
if ( config - > zfsacl_block_special & & S_ISDIR ( fsp - > fsp_name - > st . st_ex_mode ) ) {
naces + + ;
must_add_empty_ace = true ;
}
2007-05-15 03:55:11 +04:00
/* allocate the field of ZFS aces */
2007-08-30 23:48:31 +04:00
mem_ctx = talloc_tos ( ) ;
2007-05-15 03:55:11 +04:00
acebuf = ( ace_t * ) talloc_size ( mem_ctx , sizeof ( ace_t ) * naces ) ;
if ( acebuf = = NULL ) {
errno = ENOMEM ;
return False ;
}
/* handle all aces */
for ( smbace = smb_first_ace4 ( smbacl ) , i = 0 ;
smbace ! = NULL ;
smbace = smb_next_ace4 ( smbace ) , i + + ) {
SMB_ACE4PROP_T * aceprop = smb_get_ace4 ( smbace ) ;
acebuf [ i ] . a_type = aceprop - > aceType ;
acebuf [ i ] . a_flags = aceprop - > aceFlags ;
acebuf [ i ] . a_access_mask = aceprop - > aceMask ;
2011-01-13 21:16:13 +03:00
/* SYNC on acls is a no-op on ZFS.
See bug # 7909. */
acebuf [ i ] . a_access_mask & = ~ SMB_ACE4_SYNCHRONIZE ;
2007-05-15 03:55:11 +04:00
acebuf [ i ] . a_who = aceprop - > who . id ;
2007-07-12 22:49:44 +04:00
if ( aceprop - > flags & SMB_ACE4_ID_SPECIAL ) {
switch ( aceprop - > who . special_id ) {
case SMB_ACE4_WHO_EVERYONE :
acebuf [ i ] . a_flags | = ACE_EVERYONE ;
break ;
case SMB_ACE4_WHO_OWNER :
acebuf [ i ] . a_flags | = ACE_OWNER ;
break ;
case SMB_ACE4_WHO_GROUP :
2013-04-28 12:20:04 +04:00
acebuf [ i ] . a_flags | = ACE_GROUP | ACE_IDENTIFIER_GROUP ;
2007-07-12 22:49:44 +04:00
break ;
default :
DEBUG ( 8 , ( " unsupported special_id %d \n " , \
aceprop - > who . special_id ) ) ;
continue ; /* don't add it !!! */
}
2010-01-11 14:10:47 +03:00
have_special_id = true ;
2007-07-12 22:49:44 +04:00
}
2007-05-15 03:55:11 +04:00
}
2020-09-24 18:42:16 +03:00
if ( must_add_empty_ace ) {
acebuf [ i ] . a_type = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE ;
2020-11-30 14:28:00 +03:00
acebuf [ i ] . a_flags = SMB_ACE4_DIRECTORY_INHERIT_ACE |
SMB_ACE4_FILE_INHERIT_ACE |
2020-11-30 14:28:58 +03:00
ACE_EVERYONE |
ACE_INHERITED_ACE ;
2020-09-24 18:42:16 +03:00
acebuf [ i ] . a_access_mask = 0 ;
i + + ;
}
2010-01-11 14:10:47 +03:00
2019-08-30 22:15:37 +03:00
if ( ! have_special_id & & config - > zfsacl_denymissingspecial ) {
2010-01-11 14:10:47 +03:00
errno = EACCES ;
return false ;
}
2007-05-15 03:55:11 +04:00
SMB_ASSERT ( i = = naces ) ;
/* store acl */
2021-01-25 11:55:40 +03:00
fd = fsp_get_io_fd ( fsp ) ;
if ( fd ! = - 1 ) {
rv = facl ( fd , ACE_SETACL , naces , acebuf ) ;
2020-08-20 17:18:35 +03:00
}
else {
rv = acl ( fsp - > fsp_name - > base_name , ACE_SETACL , naces , acebuf ) ;
}
if ( rv ! = 0 ) {
2007-05-15 03:55:11 +04:00
if ( errno = = ENOSYS ) {
2007-12-04 10:19:40 +03:00
DEBUG ( 9 , ( " acl(ACE_SETACL, %s): Operation is not "
" supported on the filesystem where the file "
2009-07-11 05:11:32 +04:00
" reside " , fsp_str_dbg ( fsp ) ) ) ;
2007-05-15 03:55:11 +04:00
} else {
2009-07-11 05:11:32 +04:00
DEBUG ( 9 , ( " acl(ACE_SETACL, %s): %s " , fsp_str_dbg ( fsp ) ,
strerror ( errno ) ) ) ;
2007-05-15 03:55:11 +04:00
}
2020-08-20 17:18:35 +03:00
return false ;
2007-05-15 03:55:11 +04:00
}
return True ;
}
/* zfs_set_nt_acl()
* set the local file ' s acls obtaining it in NT form
* using the NFSv4 format conversion
*/
2007-06-27 02:49:10 +04:00
static NTSTATUS zfs_set_nt_acl ( vfs_handle_struct * handle , files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info_sent ,
2008-10-08 04:50:01 +04:00
const struct security_descriptor * psd )
2007-05-15 03:55:11 +04:00
{
2019-10-19 16:36:15 +03:00
struct zfsacl_config_data * config = NULL ;
SMB_VFS_HANDLE_GET_DATA ( handle , config ,
struct zfsacl_config_data ,
return NT_STATUS_INTERNAL_ERROR ) ;
return smb_set_nt_acl_nfs4 ( handle ,
fsp ,
& config - > nfs4_params ,
security_info_sent ,
psd ,
zfs_process_smbacl ) ;
2007-05-15 03:55:11 +04:00
}
2020-08-20 17:18:35 +03:00
static int get_zfsacl ( TALLOC_CTX * mem_ctx ,
const struct smb_filename * smb_fname ,
ace_t * * outbuf )
{
int naces , rv ;
ace_t * acebuf = NULL ;
naces = acl ( smb_fname - > base_name , ACE_GETACLCNT , 0 , NULL ) ;
if ( naces = = - 1 ) {
int dbg_level = 10 ;
if ( errno = = ENOSYS ) {
dbg_level = 1 ;
}
DEBUG ( dbg_level , ( " acl(ACE_GETACLCNT, %s): %s " ,
smb_fname - > base_name , strerror ( errno ) ) ) ;
return naces ;
}
acebuf = talloc_size ( mem_ctx , sizeof ( ace_t ) * naces ) ;
if ( acebuf = = NULL ) {
errno = ENOMEM ;
return - 1 ;
}
rv = acl ( smb_fname - > base_name , ACE_GETACL , naces , acebuf ) ;
if ( rv = = - 1 ) {
DBG_DEBUG ( " acl(ACE_GETACL, %s) failed: %s " ,
smb_fname - > base_name , strerror ( errno ) ) ;
return - 1 ;
}
* outbuf = acebuf ;
return naces ;
}
static int fget_zfsacl ( TALLOC_CTX * mem_ctx ,
struct files_struct * fsp ,
ace_t * * outbuf )
{
int naces , rv ;
ace_t * acebuf = NULL ;
2021-01-25 11:55:40 +03:00
int fd ;
2020-08-20 17:18:35 +03:00
2021-01-25 11:55:40 +03:00
fd = fsp_get_io_fd ( fsp ) ;
if ( fd = = - 1 ) {
2020-08-20 17:18:35 +03:00
return get_zfsacl ( mem_ctx , fsp - > fsp_name , outbuf ) ;
}
2021-01-25 11:55:40 +03:00
naces = facl ( fd , ACE_GETACLCNT , 0 , NULL ) ;
2020-08-20 17:18:35 +03:00
if ( naces = = - 1 ) {
int dbg_level = 10 ;
if ( errno = = ENOSYS ) {
dbg_level = 1 ;
}
DEBUG ( dbg_level , ( " facl(ACE_GETACLCNT, %s): %s " ,
fsp_str_dbg ( fsp ) , strerror ( errno ) ) ) ;
return naces ;
}
acebuf = talloc_size ( mem_ctx , sizeof ( ace_t ) * naces ) ;
if ( acebuf = = NULL ) {
errno = ENOMEM ;
return - 1 ;
}
2021-01-25 11:55:40 +03:00
rv = facl ( fd , ACE_GETACL , naces , acebuf ) ;
2020-08-20 17:18:35 +03:00
if ( rv = = - 1 ) {
DBG_DEBUG ( " acl(ACE_GETACL, %s): %s " ,
fsp_str_dbg ( fsp ) , strerror ( errno ) ) ;
return - 1 ;
}
* outbuf = acebuf ;
return naces ;
}
2007-10-13 23:06:49 +04:00
static NTSTATUS zfsacl_fget_nt_acl ( struct vfs_handle_struct * handle ,
2012-10-10 04:50:27 +04:00
struct files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * ppdesc )
2007-05-15 03:55:11 +04:00
{
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * pacl ;
2007-11-16 20:33:39 +03:00
NTSTATUS status ;
2019-10-19 16:37:45 +03:00
struct zfsacl_config_data * config = NULL ;
2020-08-20 17:18:35 +03:00
ace_t * acebuf = NULL ;
int naces ;
2019-10-19 16:37:45 +03:00
SMB_VFS_HANDLE_GET_DATA ( handle , config ,
struct zfsacl_config_data ,
return NT_STATUS_INTERNAL_ERROR ) ;
2013-04-14 12:13:42 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-11-16 20:33:39 +03:00
2020-08-20 17:18:35 +03:00
naces = fget_zfsacl ( talloc_tos ( ) , fsp , & acebuf ) ;
if ( naces = = - 1 ) {
status = map_nt_error_from_unix ( errno ) ;
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2017-12-05 10:28:28 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_NOT_SUPPORTED ) ) {
return status ;
}
status = make_default_filesystem_acl ( mem_ctx ,
DEFAULT_ACL_POSIX ,
fsp - > fsp_name - > base_name ,
& fsp - > fsp_name - > st ,
ppdesc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
( * ppdesc ) - > type | = SEC_DESC_DACL_PROTECTED ;
return NT_STATUS_OK ;
2007-11-16 20:33:39 +03:00
}
2020-08-20 17:18:35 +03:00
status = zfs_get_nt_acl_common ( handle - > conn ,
frame ,
fsp - > fsp_name ,
acebuf ,
naces ,
& pacl ,
config ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return status ;
}
2016-08-09 12:07:38 +03:00
status = smb_fget_nt_acl_nfs4 ( fsp , NULL , security_info , mem_ctx ,
ppdesc , pacl ) ;
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
return status ;
2007-05-15 03:55:11 +04:00
}
2007-06-09 03:08:41 +04:00
2020-04-14 00:15:44 +03:00
static NTSTATUS zfsacl_get_nt_acl_at ( struct vfs_handle_struct * handle ,
struct files_struct * dirfsp ,
const struct smb_filename * smb_fname ,
uint32_t security_info ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * ppdesc )
{
struct SMB4ACL_T * pacl = NULL ;
NTSTATUS status ;
struct zfsacl_config_data * config = NULL ;
TALLOC_CTX * frame = NULL ;
2020-08-20 17:18:35 +03:00
int naces ;
ace_t * acebuf = NULL ;
2020-04-14 00:15:44 +03:00
SMB_ASSERT ( dirfsp = = handle - > conn - > cwd_fsp ) ;
SMB_VFS_HANDLE_GET_DATA ( handle ,
config ,
struct zfsacl_config_data ,
return NT_STATUS_INTERNAL_ERROR ) ;
frame = talloc_stackframe ( ) ;
2020-08-20 17:18:35 +03:00
naces = get_zfsacl ( frame , smb_fname , & acebuf ) ;
if ( naces = = - 1 ) {
status = map_nt_error_from_unix ( errno ) ;
2020-04-14 00:15:44 +03:00
TALLOC_FREE ( frame ) ;
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_NOT_SUPPORTED ) ) {
return status ;
}
if ( ! VALID_STAT ( smb_fname - > st ) ) {
DBG_ERR ( " No stat info for [%s] \n " ,
smb_fname_str_dbg ( smb_fname ) ) ;
return NT_STATUS_INTERNAL_ERROR ;
}
status = make_default_filesystem_acl ( mem_ctx ,
DEFAULT_ACL_POSIX ,
smb_fname - > base_name ,
& smb_fname - > st ,
ppdesc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
( * ppdesc ) - > type | = SEC_DESC_DACL_PROTECTED ;
return NT_STATUS_OK ;
}
2020-08-20 17:18:35 +03:00
status = zfs_get_nt_acl_common ( handle - > conn ,
frame ,
smb_fname ,
acebuf ,
naces ,
& pacl ,
config ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return status ;
}
2020-04-14 00:15:44 +03:00
status = smb_get_nt_acl_nfs4 ( handle - > conn ,
smb_fname ,
NULL ,
security_info ,
mem_ctx ,
ppdesc ,
pacl ) ;
TALLOC_FREE ( frame ) ;
return status ;
}
2007-06-27 02:49:10 +04:00
static NTSTATUS zfsacl_fset_nt_acl ( vfs_handle_struct * handle ,
2007-05-15 03:55:11 +04:00
files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info_sent ,
2010-05-18 12:29:34 +04:00
const struct security_descriptor * psd )
2007-05-15 03:55:11 +04:00
{
return zfs_set_nt_acl ( handle , fsp , security_info_sent , psd ) ;
}
2008-11-17 02:55:16 +03:00
/* nils.goroll@hamburg.de 2008-06-16 :
See also
- https : //bugzilla.samba.org/show_bug.cgi?id=5446
- http : //bugs.opensolaris.org/view_bug.do?bug_id=6688240
Solaris supports NFSv4 and ZFS ACLs through a common system call , acl ( 2 )
with ACE_SETACL / ACE_GETACL / ACE_GETACLCNT , which is being wrapped for
use by samba in this module .
As the acl ( 2 ) interface is identical for ZFS and for NFS , this module ,
vfs_zfsacl , can not only be used for ZFS , but also for sharing NFSv4
mounts on Solaris .
But while " traditional " POSIX DRAFT ACLs ( using acl ( 2 ) with SETACL
/ GETACL / GETACLCNT ) fail for ZFS , the Solaris NFS client
2020-05-27 16:31:07 +03:00
implements a compatibility wrapper , which will make calls to
2008-11-17 02:55:16 +03:00
traditional ACL calls though vfs_solarisacl succeed . As the
compatibility wrapper ' s implementation is ( by design ) incomplete ,
we want to make sure that it is never being called .
2020-05-27 16:31:07 +03:00
As long as Samba does not support an explicit method for a module
2008-11-17 02:55:16 +03:00
to define conflicting vfs methods , we should override all conflicting
methods here .
For this to work , we need to make sure that this module is initialised
* after * vfs_solarisacl
Function declarations taken from vfs_solarisacl
*/
2011-01-06 19:09:56 +03:00
static SMB_ACL_T zfsacl_fail__sys_acl_get_file ( vfs_handle_struct * handle ,
2017-05-24 03:11:18 +03:00
const struct smb_filename * smb_fname ,
SMB_ACL_TYPE_T type ,
TALLOC_CTX * mem_ctx )
2008-11-17 02:55:16 +03:00
{
return ( SMB_ACL_T ) NULL ;
}
2011-01-06 19:09:56 +03:00
static SMB_ACL_T zfsacl_fail__sys_acl_get_fd ( vfs_handle_struct * handle ,
2013-04-14 12:13:42 +04:00
files_struct * fsp ,
TALLOC_CTX * mem_ctx )
2008-11-17 02:55:16 +03:00
{
return ( SMB_ACL_T ) NULL ;
}
2011-01-06 19:09:56 +03:00
static int zfsacl_fail__sys_acl_set_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
2020-12-14 18:28:26 +03:00
SMB_ACL_TYPE_T type ,
2011-01-06 19:09:56 +03:00
SMB_ACL_T theacl )
2008-11-17 02:55:16 +03:00
{
2008-11-17 12:29:41 +03:00
return - 1 ;
2008-11-17 02:55:16 +03:00
}
2011-01-06 19:09:56 +03:00
static int zfsacl_fail__sys_acl_delete_def_file ( vfs_handle_struct * handle ,
2017-05-24 01:33:31 +03:00
const struct smb_filename * smb_fname )
2008-11-17 02:55:16 +03:00
{
2008-11-17 12:29:41 +03:00
return - 1 ;
2008-11-17 02:55:16 +03:00
}
2017-05-24 03:35:59 +03:00
static int zfsacl_fail__sys_acl_blob_get_file ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
TALLOC_CTX * mem_ctx ,
char * * blob_description ,
DATA_BLOB * blob )
2012-10-10 10:00:42 +04:00
{
return - 1 ;
}
2012-12-27 23:57:14 +04:00
static int zfsacl_fail__sys_acl_blob_get_fd ( vfs_handle_struct * handle , files_struct * fsp , TALLOC_CTX * mem_ctx , char * * blob_description , DATA_BLOB * blob )
2012-10-10 10:00:42 +04:00
{
return - 1 ;
}
2019-08-30 22:15:37 +03:00
static int zfsacl_connect ( struct vfs_handle_struct * handle ,
const char * service , const char * user )
{
struct zfsacl_config_data * config = NULL ;
int ret ;
ret = SMB_VFS_NEXT_CONNECT ( handle , service , user ) ;
if ( ret < 0 ) {
return ret ;
}
config = talloc_zero ( handle - > conn , struct zfsacl_config_data ) ;
if ( ! config ) {
DBG_ERR ( " talloc_zero() failed \n " ) ;
errno = ENOMEM ;
return - 1 ;
}
2019-08-30 22:30:57 +03:00
config - > zfsacl_map_dacl_protected = lp_parm_bool ( SNUM ( handle - > conn ) ,
" zfsacl " , " map_dacl_protected " , false ) ;
2019-08-30 22:15:37 +03:00
config - > zfsacl_denymissingspecial = lp_parm_bool ( SNUM ( handle - > conn ) ,
" zfsacl " , " denymissingspecial " , false ) ;
2020-09-24 18:42:16 +03:00
config - > zfsacl_block_special = lp_parm_bool ( SNUM ( handle - > conn ) ,
" zfsacl " , " block_special " , true ) ;
2019-08-30 22:15:37 +03:00
ret = smbacl4_get_vfs_params ( handle - > conn , & config - > nfs4_params ) ;
if ( ret < 0 ) {
TALLOC_FREE ( config ) ;
return ret ;
}
SMB_VFS_HANDLE_SET_DATA ( handle , config ,
NULL , struct zfsacl_config_data ,
return - 1 ) ;
return 0 ;
}
2007-05-15 03:55:11 +04:00
/* VFS operations structure */
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers zfsacl_fns = {
2019-08-30 22:15:37 +03:00
. connect_fn = zfsacl_connect ,
2011-12-04 08:45:04 +04:00
. sys_acl_get_file_fn = zfsacl_fail__sys_acl_get_file ,
. sys_acl_get_fd_fn = zfsacl_fail__sys_acl_get_fd ,
2012-10-10 10:00:42 +04:00
. sys_acl_blob_get_file_fn = zfsacl_fail__sys_acl_blob_get_file ,
. sys_acl_blob_get_fd_fn = zfsacl_fail__sys_acl_blob_get_fd ,
2011-12-04 08:45:04 +04:00
. sys_acl_set_fd_fn = zfsacl_fail__sys_acl_set_fd ,
. sys_acl_delete_def_file_fn = zfsacl_fail__sys_acl_delete_def_file ,
. fget_nt_acl_fn = zfsacl_fget_nt_acl ,
2020-04-14 00:15:44 +03:00
. get_nt_acl_at_fn = zfsacl_get_nt_acl_at ,
2011-12-04 08:45:04 +04:00
. fset_nt_acl_fn = zfsacl_fset_nt_acl ,
2007-05-15 03:55:11 +04:00
} ;
2017-12-16 01:32:12 +03:00
static_decl_vfs ;
2017-04-20 22:24:43 +03:00
NTSTATUS vfs_zfsacl_init ( TALLOC_CTX * ctx )
2007-05-15 03:55:11 +04:00
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " zfsacl " ,
2009-07-24 04:28:58 +04:00
& zfsacl_fns ) ;
2007-05-15 03:55:11 +04:00
}