2006-11-09 23:29:31 +03:00
/*
Unix SMB / CIFS implementation .
Wrap gpfs calls in vfs functions .
Copyright ( C ) Christian Ambach < cambach1 @ de . ibm . com > 2006
Major code contributions by Chetan Shringarpure < chetan . sh @ in . ibm . com >
2006-12-08 21:56:01 +03:00
and Gomati Mohanan < gomati . mohanan @ in . ibm . com >
2006-11-09 23:29:31 +03: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
2006-11-09 23:29:31 +03: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-11-09 23:29:31 +03:00
*/
# include "includes.h"
2006-12-08 21:56:01 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
# include <gpfs_gpl.h>
# include "nfs4_acls.h"
2006-11-09 23:29:31 +03:00
static int vfs_gpfs_kernel_flock ( vfs_handle_struct * handle , files_struct * fsp ,
int fd , uint32 share_mode )
{
START_PROFILE ( syscall_kernel_flock ) ;
kernel_flock ( fsp - > fh - > fd , share_mode ) ;
if ( ! set_gpfs_sharemode ( fsp , fsp - > access_mask , fsp - > share_access ) ) {
return - 1 ;
}
END_PROFILE ( syscall_kernel_flock ) ;
return 0 ;
}
2007-02-14 05:37:14 +03:00
static int vfs_gpfs_setlease ( vfs_handle_struct * handle , files_struct * fsp ,
int fd , int leasetype )
{
int ret ;
START_PROFILE ( syscall_linux_setlease ) ;
if ( linux_set_lease_sighandler ( fd ) = = - 1 )
return - 1 ;
ret = set_gpfs_lease ( fd , leasetype ) ;
if ( ret < 0 ) {
/* This must have come from GPFS not being available */
/* or some other error, hence call the default */
ret = linux_setlease ( fd , leasetype ) ;
}
END_PROFILE ( syscall_linux_setlease ) ;
return ret ;
}
2006-12-08 21:56:01 +03:00
static void gpfs_dumpacl ( int level , struct gpfs_acl * gacl )
{
int i ;
if ( gacl = = NULL )
{
DEBUG ( 0 , ( " gpfs acl is NULL \n " ) ) ;
return ;
}
DEBUG ( level , ( " gpfs acl: nace: %d, type:%d, version:%d, level:%d, len:%d \n " ,
gacl - > acl_nace , gacl - > acl_type , gacl - > acl_version , gacl - > acl_level , gacl - > acl_len ) ) ;
for ( i = 0 ; i < gacl - > acl_nace ; i + + )
{
struct gpfs_ace_v4 * gace = gacl - > ace_v4 + i ;
DEBUG ( level , ( " \t ace[%d]: type:%d, flags:0x%x, mask:0x%x, iflags:0x%x, who:%u \n " ,
i , gace - > aceType , gace - > aceFlags , gace - > aceMask ,
gace - > aceIFlags , gace - > aceWho ) ) ;
}
}
static struct gpfs_acl * gpfs_getacl_alloc ( const char * fname , gpfs_aclType_t type )
{
struct gpfs_acl * acl ;
size_t len = 200 ;
int ret ;
2007-08-30 23:48:31 +04:00
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
2006-12-08 21:56:01 +03:00
2007-04-28 03:18:41 +04:00
acl = ( struct gpfs_acl * ) TALLOC_SIZE ( mem_ctx , len ) ;
2006-12-08 21:56:01 +03:00
if ( acl = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
acl - > acl_len = len ;
acl - > acl_level = 0 ;
acl - > acl_version = 0 ;
acl - > acl_type = type ;
ret = smbd_gpfs_getacl ( ( char * ) fname , GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA , acl ) ;
if ( ( ret ! = 0 ) & & ( errno = = ENOSPC ) ) {
2007-04-28 03:18:41 +04:00
struct gpfs_acl * new_acl = ( struct gpfs_acl * ) TALLOC_SIZE (
2006-12-08 21:56:01 +03:00
mem_ctx , acl - > acl_len + sizeof ( struct gpfs_acl ) ) ;
if ( new_acl = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
new_acl - > acl_len = acl - > acl_len ;
new_acl - > acl_level = acl - > acl_level ;
new_acl - > acl_version = acl - > acl_version ;
new_acl - > acl_type = acl - > acl_type ;
acl = new_acl ;
ret = smbd_gpfs_getacl ( ( char * ) fname , GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA , acl ) ;
}
if ( ret ! = 0 )
{
DEBUG ( 8 , ( " smbd_gpfs_getacl failed with %s \n " , strerror ( errno ) ) ) ;
return NULL ;
}
return acl ;
}
2007-06-02 10:28:38 +04:00
/* Tries to get nfs4 acls and returns SMB ACL allocated.
* On failure returns 1 if it got non - NFSv4 ACL to prompt
* retry with POSIX ACL checks .
* On failure returns - 1 if there is system ( GPFS ) error , check errno .
* Returns 0 on success
*/
static int gpfs_get_nfs4_acl ( const char * fname , SMB4ACL_T * * ppacl )
2006-12-08 21:56:01 +03:00
{
int i ;
struct gpfs_acl * gacl = NULL ;
2007-06-02 10:28:38 +04:00
DEBUG ( 10 , ( " gpfs_get_nfs4_acl invoked for %s \n " , fname ) ) ;
2006-12-08 21:56:01 +03:00
/* First get the real acl length */
2007-06-02 10:28:38 +04:00
gacl = gpfs_getacl_alloc ( fname , GPFS_ACL_TYPE_NFS4 ) ;
2006-12-08 21:56:01 +03:00
if ( gacl = = NULL ) {
DEBUG ( 9 , ( " gpfs_getacl failed for %s with %s \n " ,
2007-06-02 10:28:38 +04:00
fname , strerror ( errno ) ) ) ;
return - 1 ;
2006-12-08 21:56:01 +03:00
}
if ( gacl - > acl_type ! = GPFS_ACL_TYPE_NFS4 ) {
DEBUG ( 10 , ( " Got non-nfsv4 acl \n " ) ) ;
2007-06-02 10:28:38 +04:00
/* Retry with POSIX ACLs check */
return 1 ;
2006-12-08 21:56:01 +03:00
}
* ppacl = smb_create_smb4acl ( ) ;
DEBUG ( 10 , ( " len: %d, level: %d, version: %d, nace: %d \n " ,
gacl - > acl_len , gacl - > acl_level , gacl - > acl_version ,
gacl - > acl_nace ) ) ;
for ( i = 0 ; i < gacl - > acl_nace ; i + + ) {
struct gpfs_ace_v4 * gace = & gacl - > ace_v4 [ i ] ;
SMB_ACE4PROP_T smbace ;
DEBUG ( 10 , ( " type: %d, iflags: %x, flags: %x, mask: %x, "
" who: %d \n " , gace - > aceType , gace - > aceIFlags ,
gace - > aceFlags , gace - > aceMask , gace - > aceWho ) ) ;
2007-06-02 10:28:38 +04:00
memset ( & smbace , 0 , sizeof ( SMB4ACE_T ) ) ;
2006-12-08 21:56:01 +03:00
if ( gace - > aceIFlags & ACE4_IFLAG_SPECIAL_ID ) {
smbace . flags | = SMB_ACE4_ID_SPECIAL ;
switch ( gace - > aceWho ) {
case ACE4_SPECIAL_OWNER :
smbace . who . special_id = SMB_ACE4_WHO_OWNER ;
break ;
case ACE4_SPECIAL_GROUP :
smbace . who . special_id = SMB_ACE4_WHO_GROUP ;
break ;
case ACE4_SPECIAL_EVERYONE :
smbace . who . special_id = SMB_ACE4_WHO_EVERYONE ;
break ;
default :
DEBUG ( 8 , ( " invalid special gpfs id %d "
" ignored \n " , gace - > aceWho ) ) ;
continue ; /* don't add it */
}
} else {
if ( gace - > aceFlags & ACE4_FLAG_GROUP_ID )
smbace . who . gid = gace - > aceWho ;
else
smbace . who . uid = gace - > aceWho ;
}
2007-06-02 10:28:38 +04:00
/* remove redundent deny entries */
if ( i > 0 & & gace - > aceType = = SMB_ACE4_ACCESS_DENIED_ACE_TYPE ) {
struct gpfs_ace_v4 * prev = & gacl - > ace_v4 [ i - 1 ] ;
if ( prev - > aceType = = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE & &
prev - > aceFlags = = gace - > aceFlags & &
prev - > aceIFlags = = gace - > aceIFlags & &
( gace - > aceMask & prev - > aceMask ) = = 0 & &
gace - > aceWho = = prev - > aceWho ) {
/* its redundent - skip it */
continue ;
}
}
2006-12-08 21:56:01 +03:00
smbace . aceType = gace - > aceType ;
smbace . aceFlags = gace - > aceFlags ;
smbace . aceMask = gace - > aceMask ;
smb_add_ace4 ( * ppacl , & smbace ) ;
}
2007-06-02 10:28:38 +04:00
return 0 ;
2006-12-08 21:56:01 +03:00
}
static size_t gpfsacl_get_nt_acl_common ( files_struct * fsp ,
uint32 security_info , SEC_DESC * * ppdesc )
{
SMB4ACL_T * pacl = NULL ;
2007-06-02 10:28:38 +04:00
int result ;
2006-12-08 21:56:01 +03:00
* ppdesc = NULL ;
2007-06-02 10:28:38 +04:00
result = gpfs_get_nfs4_acl ( fsp - > fsp_name , & pacl ) ;
if ( result = = 0 )
return smb_get_nt_acl_nfs4 ( fsp , security_info , ppdesc , pacl ) ;
if ( result > 0 ) {
2006-12-08 21:56:01 +03:00
DEBUG ( 10 , ( " retrying with posix acl... \n " ) ) ;
return get_nt_acl ( fsp , security_info , ppdesc ) ;
}
2007-06-02 10:28:38 +04:00
/* GPFS ACL was not read, something wrong happened, error code is set in errno */
return 0 ;
2006-12-08 21:56:01 +03:00
}
size_t gpfsacl_fget_nt_acl ( vfs_handle_struct * handle ,
files_struct * fsp , int fd , uint32 security_info ,
SEC_DESC * * ppdesc )
{
return gpfsacl_get_nt_acl_common ( fsp , security_info , ppdesc ) ;
}
size_t gpfsacl_get_nt_acl ( vfs_handle_struct * handle ,
files_struct * fsp , const char * name ,
uint32 security_info , SEC_DESC * * ppdesc )
{
return gpfsacl_get_nt_acl_common ( fsp , security_info , ppdesc ) ;
}
static BOOL gpfsacl_process_smbacl ( files_struct * fsp , SMB4ACL_T * smbacl )
{
int ret ;
gpfs_aclLen_t gacl_len ;
SMB4ACE_T * smbace ;
struct gpfs_acl * gacl ;
2007-08-30 23:48:31 +04:00
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
2006-12-08 21:56:01 +03:00
gacl_len = sizeof ( struct gpfs_acl ) +
( smb_get_naces ( smbacl ) - 1 ) * sizeof ( gpfs_ace_v4_t ) ;
2007-04-28 03:18:41 +04:00
gacl = TALLOC_SIZE ( mem_ctx , gacl_len ) ;
2006-12-08 21:56:01 +03:00
if ( gacl = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
errno = ENOMEM ;
return False ;
}
gacl - > acl_len = gacl_len ;
gacl - > acl_level = 0 ;
gacl - > acl_version = GPFS_ACL_VERSION_NFS4 ;
gacl - > acl_type = GPFS_ACL_TYPE_NFS4 ;
gacl - > acl_nace = 0 ; /* change later... */
for ( smbace = smb_first_ace4 ( smbacl ) ; smbace ! = NULL ; smbace = smb_next_ace4 ( smbace ) ) {
struct gpfs_ace_v4 * gace = & gacl - > ace_v4 [ gacl - > acl_nace ] ;
SMB_ACE4PROP_T * aceprop = smb_get_ace4 ( smbace ) ;
gace - > aceType = aceprop - > aceType ;
gace - > aceFlags = aceprop - > aceFlags ;
gace - > aceMask = aceprop - > aceMask ;
gace - > aceIFlags = ( aceprop - > flags & SMB_ACE4_ID_SPECIAL ) ? ACE4_IFLAG_SPECIAL_ID : 0 ;
if ( aceprop - > flags & SMB_ACE4_ID_SPECIAL )
{
switch ( aceprop - > who . special_id )
{
case SMB_ACE4_WHO_EVERYONE :
gace - > aceWho = ACE4_SPECIAL_EVERYONE ;
break ;
case SMB_ACE4_WHO_OWNER :
gace - > aceWho = ACE4_SPECIAL_OWNER ;
break ;
case SMB_ACE4_WHO_GROUP :
gace - > aceWho = ACE4_SPECIAL_GROUP ;
break ;
default :
DEBUG ( 8 , ( " unsupported special_id %d \n " , aceprop - > who . special_id ) ) ;
continue ; /* don't add it !!! */
}
} else {
/* just only for the type safety... */
if ( aceprop - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP )
gace - > aceWho = aceprop - > who . gid ;
else
gace - > aceWho = aceprop - > who . uid ;
}
gacl - > acl_nace + + ;
}
ret = smbd_gpfs_putacl ( fsp - > fsp_name , GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA , gacl ) ;
if ( ret ! = 0 ) {
DEBUG ( 8 , ( " gpfs_putacl failed with %s \n " , strerror ( errno ) ) ) ;
gpfs_dumpacl ( 8 , gacl ) ;
return False ;
}
DEBUG ( 10 , ( " gpfs_putacl succeeded \n " ) ) ;
return True ;
}
2007-06-27 02:49:10 +04:00
static NTSTATUS gpfsacl_set_nt_acl_internal ( files_struct * fsp , uint32 security_info_sent , SEC_DESC * psd )
2006-12-08 21:56:01 +03:00
{
struct gpfs_acl * acl ;
2007-06-27 02:49:10 +04:00
NTSTATUS result = NT_STATUS_ACCESS_DENIED ;
2006-12-08 21:56:01 +03:00
acl = gpfs_getacl_alloc ( fsp - > fsp_name , GPFS_ACL_TYPE_ACCESS ) ;
if ( acl = = NULL )
2007-06-27 02:49:10 +04:00
return result ;
2006-12-08 21:56:01 +03:00
if ( acl - > acl_version & GPFS_ACL_VERSION_NFS4 )
{
result = smb_set_nt_acl_nfs4 (
fsp , security_info_sent , psd ,
gpfsacl_process_smbacl ) ;
} else { /* assume POSIX ACL - by default... */
result = set_nt_acl ( fsp , security_info_sent , psd ) ;
}
return result ;
}
2007-06-27 02:49:10 +04:00
static NTSTATUS gpfsacl_fset_nt_acl ( vfs_handle_struct * handle , files_struct * fsp , int fd , uint32 security_info_sent , SEC_DESC * psd )
2006-12-08 21:56:01 +03:00
{
return gpfsacl_set_nt_acl_internal ( fsp , security_info_sent , psd ) ;
}
2007-06-27 02:49:10 +04:00
static NTSTATUS gpfsacl_set_nt_acl ( vfs_handle_struct * handle , files_struct * fsp , char * name , uint32 security_info_sent , SEC_DESC * psd )
2006-12-08 21:56:01 +03:00
{
return gpfsacl_set_nt_acl_internal ( fsp , security_info_sent , psd ) ;
}
static SMB_ACL_T gpfs2smb_acl ( const struct gpfs_acl * pacl )
{
SMB_ACL_T result ;
int i ;
result = sys_acl_init ( pacl - > acl_nace ) ;
if ( result = = NULL ) {
errno = ENOMEM ;
return NULL ;
}
result - > count = pacl - > acl_nace ;
for ( i = 0 ; i < pacl - > acl_nace ; i + + ) {
struct smb_acl_entry * ace = & result - > acl [ i ] ;
const struct gpfs_ace_v1 * g_ace = & pacl - > ace_v1 [ i ] ;
DEBUG ( 10 , ( " Converting type %d id %lu perm %x \n " ,
( int ) g_ace - > ace_type , ( unsigned long ) g_ace - > ace_who ,
( int ) g_ace - > ace_perm ) ) ;
switch ( g_ace - > ace_type ) {
case GPFS_ACL_USER :
ace - > a_type = SMB_ACL_USER ;
ace - > uid = ( uid_t ) g_ace - > ace_who ;
break ;
case GPFS_ACL_USER_OBJ :
ace - > a_type = SMB_ACL_USER_OBJ ;
break ;
case GPFS_ACL_GROUP :
ace - > a_type = SMB_ACL_GROUP ;
ace - > gid = ( gid_t ) g_ace - > ace_who ;
break ;
case GPFS_ACL_GROUP_OBJ :
ace - > a_type = SMB_ACL_GROUP_OBJ ;
break ;
case GPFS_ACL_OTHER :
ace - > a_type = SMB_ACL_OTHER ;
break ;
case GPFS_ACL_MASK :
ace - > a_type = SMB_ACL_MASK ;
break ;
default :
DEBUG ( 10 , ( " Got invalid ace_type: %d \n " ,
g_ace - > ace_type ) ) ;
errno = EINVAL ;
SAFE_FREE ( result ) ;
return NULL ;
}
ace - > a_perm = 0 ;
ace - > a_perm | = ( g_ace - > ace_perm & ACL_PERM_READ ) ?
SMB_ACL_READ : 0 ;
ace - > a_perm | = ( g_ace - > ace_perm & ACL_PERM_WRITE ) ?
SMB_ACL_WRITE : 0 ;
ace - > a_perm | = ( g_ace - > ace_perm & ACL_PERM_EXECUTE ) ?
SMB_ACL_EXECUTE : 0 ;
DEBUGADD ( 10 , ( " Converted to %d perm %x \n " ,
ace - > a_type , ace - > a_perm ) ) ;
}
return result ;
}
static SMB_ACL_T gpfsacl_get_posix_acl ( const char * path , gpfs_aclType_t type )
{
struct gpfs_acl * pacl ;
SMB_ACL_T result = NULL ;
pacl = gpfs_getacl_alloc ( path , type ) ;
if ( pacl = = NULL ) {
DEBUG ( 10 , ( " gpfs_getacl failed for %s with %s \n " ,
path , strerror ( errno ) ) ) ;
if ( errno = = 0 ) {
errno = EINVAL ;
}
goto done ;
}
if ( pacl - > acl_version ! = GPFS_ACL_VERSION_POSIX ) {
DEBUG ( 10 , ( " Got acl version %d, expected %d \n " ,
pacl - > acl_version , GPFS_ACL_VERSION_POSIX ) ) ;
errno = EINVAL ;
goto done ;
}
DEBUG ( 10 , ( " len: %d, level: %d, version: %d, nace: %d \n " ,
pacl - > acl_len , pacl - > acl_level , pacl - > acl_version ,
pacl - > acl_nace ) ) ;
result = gpfs2smb_acl ( pacl ) ;
if ( result = = NULL ) {
goto done ;
}
done :
if ( errno ! = 0 ) {
SAFE_FREE ( result ) ;
}
return result ;
}
SMB_ACL_T gpfsacl_sys_acl_get_file ( vfs_handle_struct * handle ,
const char * path_p ,
SMB_ACL_TYPE_T type )
{
gpfs_aclType_t gpfs_type ;
switch ( type ) {
case SMB_ACL_TYPE_ACCESS :
gpfs_type = GPFS_ACL_TYPE_ACCESS ;
break ;
case SMB_ACL_TYPE_DEFAULT :
gpfs_type = GPFS_ACL_TYPE_DEFAULT ;
break ;
default :
DEBUG ( 0 , ( " Got invalid type: %d \n " , type ) ) ;
smb_panic ( " exiting " ) ;
}
return gpfsacl_get_posix_acl ( path_p , gpfs_type ) ;
}
SMB_ACL_T gpfsacl_sys_acl_get_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
int fd )
{
return gpfsacl_get_posix_acl ( fsp - > fsp_name , GPFS_ACL_TYPE_ACCESS ) ;
}
static struct gpfs_acl * smb2gpfs_acl ( const SMB_ACL_T pacl ,
SMB_ACL_TYPE_T type )
{
gpfs_aclLen_t len ;
struct gpfs_acl * result ;
int i ;
union gpfs_ace_union
{
gpfs_ace_v1_t ace_v1 [ 1 ] ; /* when GPFS_ACL_VERSION_POSIX */
gpfs_ace_v4_t ace_v4 [ 1 ] ; /* when GPFS_ACL_VERSION_NFS4 */
} ;
DEBUG ( 10 , ( " smb2gpfs_acl: Got ACL with %d entries \n " , pacl - > count ) ) ;
len = sizeof ( struct gpfs_acl ) - sizeof ( union gpfs_ace_union ) +
( pacl - > count ) * sizeof ( gpfs_ace_v1_t ) ;
result = SMB_MALLOC ( len ) ;
if ( result = = NULL ) {
errno = ENOMEM ;
return result ;
}
result - > acl_len = len ;
result - > acl_level = 0 ;
result - > acl_version = GPFS_ACL_VERSION_POSIX ;
result - > acl_type = ( type = = SMB_ACL_TYPE_DEFAULT ) ?
GPFS_ACL_TYPE_DEFAULT : GPFS_ACL_TYPE_ACCESS ;
result - > acl_nace = pacl - > count ;
for ( i = 0 ; i < pacl - > count ; i + + ) {
const struct smb_acl_entry * ace = & pacl - > acl [ i ] ;
struct gpfs_ace_v1 * g_ace = & result - > ace_v1 [ i ] ;
DEBUG ( 10 , ( " Converting type %d perm %x \n " ,
( int ) ace - > a_type , ( int ) ace - > a_perm ) ) ;
g_ace - > ace_perm = 0 ;
switch ( ace - > a_type ) {
case SMB_ACL_USER :
g_ace - > ace_type = GPFS_ACL_USER ;
g_ace - > ace_who = ( gpfs_uid_t ) ace - > uid ;
break ;
case SMB_ACL_USER_OBJ :
g_ace - > ace_type = GPFS_ACL_USER_OBJ ;
g_ace - > ace_perm | = ACL_PERM_CONTROL ;
g_ace - > ace_who = 0 ;
break ;
case SMB_ACL_GROUP :
g_ace - > ace_type = GPFS_ACL_GROUP ;
g_ace - > ace_who = ( gpfs_uid_t ) ace - > gid ;
break ;
case SMB_ACL_GROUP_OBJ :
g_ace - > ace_type = GPFS_ACL_GROUP_OBJ ;
g_ace - > ace_who = 0 ;
break ;
case SMB_ACL_MASK :
g_ace - > ace_type = GPFS_ACL_MASK ;
g_ace - > ace_perm = 0x8f ;
g_ace - > ace_who = 0 ;
break ;
case SMB_ACL_OTHER :
g_ace - > ace_type = GPFS_ACL_OTHER ;
g_ace - > ace_who = 0 ;
break ;
default :
DEBUG ( 10 , ( " Got invalid ace_type: %d \n " , ace - > a_type ) ) ;
errno = EINVAL ;
SAFE_FREE ( result ) ;
return NULL ;
}
g_ace - > ace_perm | = ( ace - > a_perm & SMB_ACL_READ ) ?
ACL_PERM_READ : 0 ;
g_ace - > ace_perm | = ( ace - > a_perm & SMB_ACL_WRITE ) ?
ACL_PERM_WRITE : 0 ;
g_ace - > ace_perm | = ( ace - > a_perm & SMB_ACL_EXECUTE ) ?
ACL_PERM_EXECUTE : 0 ;
DEBUGADD ( 10 , ( " Converted to %d id %d perm %x \n " ,
g_ace - > ace_type , g_ace - > ace_who , g_ace - > ace_perm ) ) ;
}
return result ;
}
int gpfsacl_sys_acl_set_file ( vfs_handle_struct * handle ,
const char * name ,
SMB_ACL_TYPE_T type ,
SMB_ACL_T theacl )
{
struct gpfs_acl * gpfs_acl ;
int result ;
gpfs_acl = smb2gpfs_acl ( theacl , type ) ;
if ( gpfs_acl = = NULL ) {
return - 1 ;
}
result = smbd_gpfs_putacl ( ( char * ) name , GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA , gpfs_acl ) ;
SAFE_FREE ( gpfs_acl ) ;
return result ;
}
int gpfsacl_sys_acl_set_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
int fd , SMB_ACL_T theacl )
{
2007-04-10 19:41:22 +04:00
return gpfsacl_sys_acl_set_file ( handle , fsp - > fsp_name , SMB_ACL_TYPE_ACCESS , theacl ) ;
2006-12-08 21:56:01 +03:00
}
int gpfsacl_sys_acl_delete_def_file ( vfs_handle_struct * handle ,
const char * path )
{
errno = ENOTSUP ;
return - 1 ;
}
2007-06-02 10:28:38 +04:00
static int vfs_gpfs_chmod ( vfs_handle_struct * handle , const char * path , mode_t mode )
{
SMB_STRUCT_STAT st ;
if ( SMB_VFS_NEXT_STAT ( handle , path , & st ) ! = 0 ) {
return - 1 ;
}
/* avoid chmod() if possible, to preserve acls */
if ( ( st . st_mode & ~ S_IFMT ) = = mode ) {
return 0 ;
}
return SMB_VFS_NEXT_CHMOD ( handle , path , mode ) ;
}
static int vfs_gpfs_fchmod ( vfs_handle_struct * handle , files_struct * fsp , int fd , mode_t mode )
{
SMB_STRUCT_STAT st ;
if ( SMB_VFS_NEXT_FSTAT ( handle , fsp , fd , & st ) ! = 0 ) {
return - 1 ;
}
/* avoid chmod() if possible, to preserve acls */
if ( ( st . st_mode & ~ S_IFMT ) = = mode ) {
return 0 ;
}
return SMB_VFS_NEXT_FCHMOD ( handle , fsp , fd , mode ) ;
}
2006-12-08 21:56:01 +03:00
/* VFS operations structure */
2006-11-09 23:29:31 +03:00
static vfs_op_tuple gpfs_op_tuples [ ] = {
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( vfs_gpfs_kernel_flock ) , SMB_VFS_OP_KERNEL_FLOCK ,
SMB_VFS_LAYER_OPAQUE } ,
{ SMB_VFS_OP ( vfs_gpfs_setlease ) , SMB_VFS_OP_LINUX_SETLEASE ,
SMB_VFS_LAYER_OPAQUE } ,
{ SMB_VFS_OP ( gpfsacl_fget_nt_acl ) , SMB_VFS_OP_FGET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-11-09 23:29:31 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_get_nt_acl ) , SMB_VFS_OP_GET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
2007-02-14 05:37:14 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_fset_nt_acl ) , SMB_VFS_OP_FSET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_set_nt_acl ) , SMB_VFS_OP_SET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_sys_acl_get_file ) , SMB_VFS_OP_SYS_ACL_GET_FILE ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_sys_acl_get_fd ) , SMB_VFS_OP_SYS_ACL_GET_FD ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_sys_acl_set_file ) , SMB_VFS_OP_SYS_ACL_SET_FILE ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_sys_acl_set_fd ) , SMB_VFS_OP_SYS_ACL_SET_FD ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( gpfsacl_sys_acl_delete_def_file ) ,
SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( vfs_gpfs_chmod ) , SMB_VFS_OP_CHMOD ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( vfs_gpfs_fchmod ) , SMB_VFS_OP_FCHMOD ,
SMB_VFS_LAYER_TRANSPARENT } ,
2006-12-08 21:56:01 +03:00
2007-06-02 10:28:38 +04:00
{ SMB_VFS_OP ( NULL ) , SMB_VFS_OP_NOOP , SMB_VFS_LAYER_NOOP }
2006-11-09 23:29:31 +03:00
} ;
2006-12-19 23:16:52 +03:00
NTSTATUS vfs_gpfs_init ( void ) ;
2006-11-09 23:29:31 +03:00
NTSTATUS vfs_gpfs_init ( void )
{
init_gpfs ( ) ;
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " gpfs " ,
gpfs_op_tuples ) ;
}