2006-10-21 13:46:12 +04:00
/*
Unix SMB / CIFS implementation .
POSIX NTVFS backend - NT ACLs mapped to NFS4 ACLs , as per
http : //www.suse.de/~agruen/nfs4acl/
Copyright ( C ) Andrew Tridgell 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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-10-21 13:46:12 +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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-10-21 13:46:12 +04:00
*/
# include "includes.h"
# include "vfs_posix.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/unix_privs.h"
2006-10-21 13:46:12 +04:00
# include "librpc/gen_ndr/ndr_nfs4acl.h"
# include "libcli/security/security.h"
2017-04-20 22:24:43 +03:00
NTSTATUS pvfs_acl_nfs4_init ( TALLOC_CTX * ) ;
2011-03-19 02:43:05 +03:00
2006-10-21 13:46:12 +04:00
# define ACE4_IDENTIFIER_GROUP 0x40
/*
load the current ACL from system . nfs4acl
*/
static NTSTATUS pvfs_acl_load_nfs4 ( struct pvfs_state * pvfs , struct pvfs_filename * name , int fd ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * psd )
{
NTSTATUS status ;
struct nfs4acl * acl ;
struct security_descriptor * sd ;
2008-03-29 01:29:01 +03:00
int i , num_ids ;
2009-04-23 18:37:11 +04:00
struct id_map * ids ;
2006-10-21 13:46:12 +04:00
acl = talloc_zero ( mem_ctx , struct nfs4acl ) ;
NT_STATUS_HAVE_NO_MEMORY ( acl ) ;
status = pvfs_xattr_ndr_load ( pvfs , mem_ctx , name - > full_name , fd ,
2017-10-19 13:29:47 +03:00
NFS4ACL_NDR_XATTR_NAME ,
2010-08-27 00:35:09 +04:00
acl , ( void * ) ndr_pull_nfs4acl ) ;
2006-10-21 13:46:12 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( acl ) ;
return status ;
}
* psd = security_descriptor_initialise ( mem_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( * psd ) ;
sd = * psd ;
sd - > type | = acl - > a_flags ;
2008-03-29 01:29:01 +03:00
/* the number of ids to map is the acl count plus uid and gid */
num_ids = acl - > a_count + 2 ;
2009-04-23 18:37:11 +04:00
ids = talloc_array ( sd , struct id_map , num_ids ) ;
2008-03-29 01:29:01 +03:00
NT_STATUS_HAVE_NO_MEMORY ( ids ) ;
2010-05-24 04:16:34 +04:00
ids [ 0 ] . xid . id = name - > st . st_uid ;
ids [ 0 ] . xid . type = ID_TYPE_UID ;
2008-03-29 01:29:01 +03:00
ids [ 0 ] . sid = NULL ;
2009-04-23 18:37:11 +04:00
ids [ 0 ] . status = ID_UNKNOWN ;
2008-03-29 01:29:01 +03:00
2010-05-24 04:16:34 +04:00
ids [ 1 ] . xid . id = name - > st . st_gid ;
ids [ 1 ] . xid . type = ID_TYPE_GID ;
2008-03-29 01:29:01 +03:00
ids [ 1 ] . sid = NULL ;
2009-04-23 18:37:11 +04:00
ids [ 1 ] . status = ID_UNKNOWN ;
2008-03-29 01:29:01 +03:00
for ( i = 0 ; i < acl - > a_count ; i + + ) {
struct nfs4ace * a = & acl - > ace [ i ] ;
2010-05-24 04:16:34 +04:00
ids [ i + 2 ] . xid . id = a - > e_id ;
2008-03-29 01:29:01 +03:00
if ( a - > e_flags & ACE4_IDENTIFIER_GROUP ) {
2010-05-24 04:16:34 +04:00
ids [ i + 2 ] . xid . type = ID_TYPE_GID ;
2008-03-29 01:29:01 +03:00
} else {
2010-05-24 04:16:34 +04:00
ids [ i + 2 ] . xid . type = ID_TYPE_UID ;
2008-03-29 01:29:01 +03:00
}
ids [ i + 2 ] . sid = NULL ;
2009-04-23 18:37:11 +04:00
ids [ i + 2 ] . status = ID_UNKNOWN ;
2008-03-29 01:29:01 +03:00
}
/* Allocate memory for the sids from the security descriptor to be on
* the safe side . */
2016-09-18 15:06:24 +03:00
status = wbc_xids_to_sids ( ids , num_ids ) ;
2006-10-21 13:46:12 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2008-03-29 01:29:01 +03:00
sd - > owner_sid = talloc_steal ( sd , ids [ 0 ] . sid ) ;
sd - > group_sid = talloc_steal ( sd , ids [ 1 ] . sid ) ;
2006-10-21 13:46:12 +04:00
for ( i = 0 ; i < acl - > a_count ; i + + ) {
struct nfs4ace * a = & acl - > ace [ i ] ;
struct security_ace ace ;
ace . type = a - > e_type ;
ace . flags = a - > e_flags ;
ace . access_mask = a - > e_mask ;
2008-03-29 01:29:01 +03:00
ace . trustee = * ids [ i + 2 ] . sid ;
2006-10-21 13:46:12 +04:00
security_descriptor_dacl_add ( sd , & ace ) ;
}
return NT_STATUS_OK ;
}
/*
save the acl for a file into system . nfs4acl
*/
static NTSTATUS pvfs_acl_save_nfs4 ( struct pvfs_state * pvfs , struct pvfs_filename * name , int fd ,
struct security_descriptor * sd )
{
NTSTATUS status ;
void * privs ;
struct nfs4acl acl ;
int i ;
TALLOC_CTX * tmp_ctx ;
2009-04-23 18:37:11 +04:00
struct id_map * ids ;
2006-10-21 13:46:12 +04:00
tmp_ctx = talloc_new ( pvfs ) ;
NT_STATUS_HAVE_NO_MEMORY ( tmp_ctx ) ;
acl . a_version = 0 ;
acl . a_flags = sd - > type ;
acl . a_count = sd - > dacl ? sd - > dacl - > num_aces : 0 ;
acl . a_owner_mask = 0 ;
acl . a_group_mask = 0 ;
acl . a_other_mask = 0 ;
acl . ace = talloc_array ( tmp_ctx , struct nfs4ace , acl . a_count ) ;
if ( ! acl . ace ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-04-23 18:37:11 +04:00
ids = talloc_array ( tmp_ctx , struct id_map , acl . a_count ) ;
2008-03-29 01:29:01 +03:00
if ( ids = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < acl . a_count ; i + + ) {
struct security_ace * ace = & sd - > dacl - > aces [ i ] ;
2010-05-24 04:16:34 +04:00
ZERO_STRUCT ( ids [ i ] . xid ) ;
2008-03-29 01:29:01 +03:00
ids [ i ] . sid = dom_sid_dup ( ids , & ace - > trustee ) ;
if ( ids [ i ] . sid = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-04-23 18:37:11 +04:00
ids [ i ] . status = ID_UNKNOWN ;
2008-03-29 01:29:01 +03:00
}
2016-09-18 15:03:33 +03:00
status = wbc_sids_to_xids ( ids , acl . a_count ) ;
2008-03-29 01:29:01 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( tmp_ctx ) ;
return status ;
}
2006-10-21 13:46:12 +04:00
for ( i = 0 ; i < acl . a_count ; i + + ) {
struct nfs4ace * a = & acl . ace [ i ] ;
struct security_ace * ace = & sd - > dacl - > aces [ i ] ;
a - > e_type = ace - > type ;
a - > e_flags = ace - > flags ;
a - > e_mask = ace - > access_mask ;
2010-05-24 04:16:34 +04:00
if ( ids [ i ] . xid . type ! = ID_TYPE_UID ) {
2006-10-21 13:46:12 +04:00
a - > e_flags | = ACE4_IDENTIFIER_GROUP ;
}
2010-05-24 04:16:34 +04:00
a - > e_id = ids [ i ] . xid . id ;
2006-10-21 13:46:12 +04:00
a - > e_who = " " ;
}
privs = root_privileges ( ) ;
status = pvfs_xattr_ndr_save ( pvfs , name - > full_name , fd ,
2017-10-19 13:29:47 +03:00
NFS4ACL_NDR_XATTR_NAME ,
2010-08-27 00:35:09 +04:00
& acl , ( void * ) ndr_push_nfs4acl ) ;
2006-10-21 13:46:12 +04:00
talloc_free ( privs ) ;
talloc_free ( tmp_ctx ) ;
return status ;
}
/*
initialise pvfs acl NFS4 backend
*/
2017-04-20 22:24:43 +03:00
NTSTATUS pvfs_acl_nfs4_init ( TALLOC_CTX * ctx )
2006-10-21 13:46:12 +04:00
{
struct pvfs_acl_ops ops = {
. name = " nfs4acl " ,
. acl_load = pvfs_acl_load_nfs4 ,
. acl_save = pvfs_acl_save_nfs4
} ;
2017-05-12 01:45:57 +03:00
return pvfs_acl_register ( ctx , & ops ) ;
2006-10-21 13:46:12 +04:00
}