2006-07-21 19:51:34 +04:00
/*
Unix SMB / Netbios implementation .
VFS module to get and set posix acls
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2006
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-07-21 19:51:34 +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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-07-21 19:51:34 +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"
2012-08-13 14:14:43 +04:00
# include "vfs_aixacl_util.h"
2006-07-21 19:51:34 +04:00
SMB_ACL_T aixacl_sys_acl_get_file ( vfs_handle_struct * handle ,
2012-10-11 07:42:39 +04:00
const char * path_p ,
SMB_ACL_TYPE_T type ,
TALLOC_CTX * mem_ctx )
2006-07-21 19:51:34 +04:00
{
struct acl * file_acl = ( struct acl * ) NULL ;
struct smb_acl_t * result = ( struct smb_acl_t * ) NULL ;
int rc = 0 ;
uid_t user_id ;
/* AIX has no DEFAULT */
if ( type = = SMB_ACL_TYPE_DEFAULT )
return NULL ;
/* Get the acl using statacl */
DEBUG ( 10 , ( " Entering AIX sys_acl_get_file \n " ) ) ;
DEBUG ( 10 , ( " path_p is %s \n " , path_p ) ) ;
file_acl = ( struct acl * ) SMB_MALLOC ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_file: %d \n " , errno ) ) ;
return ( NULL ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
rc = statacl ( ( char * ) path_p , 0 , file_acl , BUFSIZ ) ;
if ( ( rc = = - 1 ) & & ( errno = = ENOSPC ) ) {
struct acl * new_acl = SMB_MALLOC ( file_acl - > acl_len + sizeof ( struct acl ) ) ;
if ( new_acl = = NULL ) {
SAFE_FREE ( file_acl ) ;
errno = ENOMEM ;
return NULL ;
}
file_acl = new_acl ;
rc = statacl ( ( char * ) path_p , 0 , file_acl , file_acl - > acl_len + sizeof ( struct acl ) ) ;
if ( rc = = - 1 ) {
DEBUG ( 0 , ( " statacl returned %d with errno %d \n " , rc , errno ) ) ;
SAFE_FREE ( file_acl ) ;
return ( NULL ) ;
}
}
DEBUG ( 10 , ( " Got facl and returned it \n " ) ) ;
2012-10-11 07:42:39 +04:00
result = aixacl_to_smbacl ( file_acl , mem_ctx ) ;
2006-07-21 19:51:34 +04:00
SAFE_FREE ( file_acl ) ;
return result ;
/*errno = ENOTSUP;
return NULL ; */
}
SMB_ACL_T aixacl_sys_acl_get_fd ( vfs_handle_struct * handle ,
2012-10-11 07:42:39 +04:00
files_struct * fsp ,
TALLOC_CTX * mem_ctx )
2006-07-21 19:51:34 +04:00
{
struct acl * file_acl = ( struct acl * ) NULL ;
struct smb_acl_t * result = ( struct smb_acl_t * ) NULL ;
int rc = 0 ;
uid_t user_id ;
/* Get the acl using fstatacl */
DEBUG ( 10 , ( " Entering AIX sys_acl_get_fd \n " ) ) ;
2008-01-08 01:53:34 +03:00
DEBUG ( 10 , ( " fd is %d \n " , fsp - > fh - > fd ) ) ;
2006-07-21 19:51:34 +04:00
file_acl = ( struct acl * ) SMB_MALLOC ( BUFSIZ ) ;
if ( file_acl = = NULL ) {
errno = ENOMEM ;
DEBUG ( 0 , ( " Error in AIX sys_acl_get_fd is %d \n " , errno ) ) ;
return ( NULL ) ;
}
memset ( file_acl , 0 , BUFSIZ ) ;
2008-01-08 01:53:34 +03:00
rc = fstatacl ( fsp - > fh - > fd , 0 , file_acl , BUFSIZ ) ;
2006-07-21 19:51:34 +04:00
if ( ( rc = = - 1 ) & & ( errno = = ENOSPC ) ) {
struct acl * new_acl = SMB_MALLOC ( file_acl - > acl_len + sizeof ( struct acl ) ) ;
if ( new_acl = = NULL ) {
SAFE_FREE ( file_acl ) ;
errno = ENOMEM ;
return NULL ;
}
file_acl = new_acl ;
2008-01-08 01:53:34 +03:00
rc = fstatacl ( fsp - > fh - > fd , 0 , file_acl , file_acl - > acl_len + sizeof ( struct acl ) ) ;
2006-07-21 19:51:34 +04:00
if ( rc = = - 1 ) {
DEBUG ( 0 , ( " fstatacl returned %d with errno %d \n " , rc , errno ) ) ;
SAFE_FREE ( file_acl ) ;
return ( NULL ) ;
}
}
DEBUG ( 10 , ( " Got facl and returned it \n " ) ) ;
2012-10-11 07:42:39 +04:00
result = aixacl_to_smbacl ( file_acl , mem_ctx ) ;
2006-07-21 19:51:34 +04:00
SAFE_FREE ( file_acl ) ;
return result ;
/*errno = ENOTSUP;
return NULL ; */
}
int aixacl_sys_acl_set_file ( vfs_handle_struct * handle ,
const char * name ,
SMB_ACL_TYPE_T type ,
SMB_ACL_T theacl )
{
struct acl * file_acl = NULL ;
2007-09-28 05:32:08 +04:00
unsigned int rc ;
2006-07-21 19:51:34 +04:00
file_acl = aixacl_smb_to_aixacl ( type , theacl ) ;
if ( ! file_acl )
return - 1 ;
rc = chacl ( ( char * ) name , file_acl , file_acl - > acl_len ) ;
DEBUG ( 10 , ( " errno is %d \n " , errno ) ) ;
DEBUG ( 10 , ( " return code is %d \n " , rc ) ) ;
SAFE_FREE ( file_acl ) ;
DEBUG ( 10 , ( " Exiting the aixacl_sys_acl_set_file \n " ) ) ;
return rc ;
}
int aixacl_sys_acl_set_fd ( vfs_handle_struct * handle ,
files_struct * fsp ,
2008-01-08 03:54:19 +03:00
SMB_ACL_T theacl )
2006-07-21 19:51:34 +04:00
{
struct acl * file_acl = NULL ;
2007-09-28 05:32:08 +04:00
unsigned int rc ;
2006-07-21 19:51:34 +04:00
file_acl = aixacl_smb_to_aixacl ( SMB_ACL_TYPE_ACCESS , theacl ) ;
if ( ! file_acl )
return - 1 ;
2008-01-08 03:54:19 +03:00
rc = fchacl ( fsp - > fh - > fd , file_acl , file_acl - > acl_len ) ;
2006-07-21 19:51:34 +04:00
DEBUG ( 10 , ( " errno is %d \n " , errno ) ) ;
DEBUG ( 10 , ( " return code is %d \n " , rc ) ) ;
SAFE_FREE ( file_acl ) ;
DEBUG ( 10 , ( " Exiting aixacl_sys_acl_set_fd \n " ) ) ;
return rc ;
}
int aixacl_sys_acl_delete_def_file ( vfs_handle_struct * handle ,
const char * path )
{
return 0 ; /* otherwise you can't set acl at upper level */
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_aixacl_fns = {
2011-12-04 08:45:04 +04:00
. sys_acl_get_file_fn = aixacl_sys_acl_get_file ,
. sys_acl_get_fd_fn = aixacl_sys_acl_get_fd ,
2012-10-10 09:52:02 +04:00
. sys_acl_blob_get_file_fn = posix_sys_acl_blob_get_file ,
. sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd ,
2011-12-04 08:45:04 +04:00
. sys_acl_set_file_fn = aixacl_sys_acl_set_file ,
. sys_acl_set_fd_fn = aixacl_sys_acl_set_fd ,
. sys_acl_delete_def_file_fn = aixacl_sys_acl_delete_def_file ,
2006-07-21 19:51:34 +04:00
} ;
2006-12-19 23:16:52 +03:00
NTSTATUS vfs_aixacl_init ( void ) ;
2006-07-21 19:51:34 +04:00
NTSTATUS vfs_aixacl_init ( void )
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " aixacl " ,
2009-07-24 04:28:58 +04:00
& vfs_aixacl_fns ) ;
2006-07-21 19:51:34 +04:00
}