2006-09-18 06:27:48 +04:00
/*
* NFS4 ACL handling
*
* Copyright ( C ) Jim McDonough , 2006
2019-07-18 22:06:06 +03:00
* Copyright ( C ) Christof Schmitt 2019
2006-09-18 06:27:48 +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
2006-09-18 06:27:48 +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/>.
2006-09-18 06:27:48 +04:00
*/
# include "includes.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2006-09-18 06:27:48 +04:00
# include "nfs4_acls.h"
2010-06-03 18:09:31 +04:00
# include "librpc/gen_ndr/ndr_security.h"
2019-06-26 23:24:16 +03:00
# include "librpc/gen_ndr/idmap.h"
2010-09-26 23:04:39 +04:00
# include "../libcli/security/dom_sid.h"
2010-10-18 17:55:47 +04:00
# include "../libcli/security/security.h"
2011-07-07 19:42:08 +04:00
# include "dbwrap/dbwrap.h"
2011-07-06 18:40:21 +04:00
# include "dbwrap/dbwrap_open.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-03-22 18:50:02 +03:00
# include "passdb/lookup_sid.h"
2011-05-05 13:25:29 +04:00
# include "util_tdb.h"
2011-06-29 09:33:54 +04:00
# include "lib/param/loadparm.h"
2006-09-18 06:27:48 +04:00
2008-01-16 12:18:57 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_ACLS
2006-09-18 06:27:48 +04:00
# define SMBACL4_PARAM_TYPE_NAME "nfs4"
2008-09-08 18:42:06 +04:00
extern const struct generic_mapping file_generic_mapping ;
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T
2006-09-18 06:27:48 +04:00
{
SMB_ACE4PROP_T prop ;
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * next ;
} ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:02:17 +03:00
struct SMB4ACL_T
2006-09-18 06:27:48 +04:00
{
2014-01-20 18:12:42 +04:00
uint16_t controlflags ;
2015-05-03 06:11:02 +03:00
uint32_t naces ;
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * first ;
struct SMB4ACE_T * last ;
2015-08-11 14:02:17 +03:00
} ;
2006-09-18 06:27:48 +04:00
2013-04-15 18:08:46 +04:00
/*
* Gather special parameters for NFS4 ACL handling
*/
2016-08-09 12:28:30 +03:00
int smbacl4_get_vfs_params ( struct connection_struct * conn ,
struct smbacl4_vfs_params * params )
2013-04-15 18:08:46 +04:00
{
static const struct enum_list enum_smbacl4_modes [ ] = {
{ e_simple , " simple " } ,
{ e_special , " special " } ,
{ - 1 , NULL }
} ;
static const struct enum_list enum_smbacl4_acedups [ ] = {
{ e_dontcare , " dontcare " } ,
{ e_reject , " reject " } ,
{ e_ignore , " ignore " } ,
{ e_merge , " merge " } ,
{ - 1 , NULL }
} ;
2013-11-10 14:48:17 +04:00
int enumval ;
2013-04-15 18:08:46 +04:00
2019-07-10 00:41:01 +03:00
* params = ( struct smbacl4_vfs_params ) { 0 } ;
2013-11-10 14:48:17 +04:00
2015-08-11 15:20:07 +03:00
enumval = lp_parm_enum ( SNUM ( conn ) , SMBACL4_PARAM_TYPE_NAME , " mode " ,
2013-11-10 14:48:17 +04:00
enum_smbacl4_modes , e_simple ) ;
if ( enumval = = - 1 ) {
2015-08-11 15:20:07 +03:00
DEBUG ( 10 , ( " value for %s:mode unknown \n " ,
SMBACL4_PARAM_TYPE_NAME ) ) ;
2013-11-10 14:48:17 +04:00
return - 1 ;
}
params - > mode = ( enum smbacl4_mode_enum ) enumval ;
2019-06-19 23:53:54 +03:00
if ( params - > mode = = e_special ) {
DBG_WARNING ( " nfs4:mode special is deprecated. \n " ) ;
}
2013-11-10 14:48:17 +04:00
2015-08-11 15:20:07 +03:00
params - > do_chown = lp_parm_bool ( SNUM ( conn ) , SMBACL4_PARAM_TYPE_NAME ,
2013-04-15 18:08:46 +04:00
" chown " , true ) ;
2013-11-10 14:48:17 +04:00
2015-08-11 15:20:07 +03:00
enumval = lp_parm_enum ( SNUM ( conn ) , SMBACL4_PARAM_TYPE_NAME , " acedup " ,
2019-07-18 20:13:48 +03:00
enum_smbacl4_acedups , e_merge ) ;
2013-11-10 14:48:17 +04:00
if ( enumval = = - 1 ) {
2015-08-11 15:20:07 +03:00
DEBUG ( 10 , ( " value for %s:acedup unknown \n " ,
SMBACL4_PARAM_TYPE_NAME ) ) ;
2013-11-10 14:48:17 +04:00
return - 1 ;
}
params - > acedup = ( enum smbacl4_acedup_enum ) enumval ;
2019-07-17 20:51:18 +03:00
if ( params - > acedup = = e_ignore ) {
DBG_WARNING ( " nfs4:acedup ignore is deprecated. \n " ) ;
}
if ( params - > acedup = = e_reject ) {
DBG_WARNING ( " nfs4:acedup ignore is deprecated. \n " ) ;
}
2013-11-10 14:48:17 +04:00
2013-06-21 01:33:30 +04:00
params - > map_full_control = lp_acl_map_full_control ( SNUM ( conn ) ) ;
2013-04-15 18:08:46 +04:00
2013-06-21 01:33:30 +04:00
DEBUG ( 10 , ( " mode:%s, do_chown:%s, acedup: %s map full control:%s \n " ,
2013-04-15 18:08:46 +04:00
enum_smbacl4_modes [ params - > mode ] . name ,
params - > do_chown ? " true " : " false " ,
2013-06-21 01:33:30 +04:00
enum_smbacl4_acedups [ params - > acedup ] . name ,
params - > map_full_control ? " true " : " false " ) ) ;
2013-04-15 18:08:46 +04:00
return 0 ;
}
2011-06-01 02:37:30 +04:00
/************************************************
Split the ACE flag mapping between nfs4 and Windows
into two separate functions rather than trying to do
it inline . Allows us to carefully control what flags
are mapped to what in one place .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-09-16 01:35:05 +04:00
static uint32_t map_nfs4_ace_flags_to_windows_ace_flags (
uint32_t nfs4_ace_flags )
2011-06-01 02:37:30 +04:00
{
uint32_t win_ace_flags = 0 ;
/* The nfs4 flags <= 0xf map perfectly. */
win_ace_flags = nfs4_ace_flags & ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT |
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
SEC_ACE_FLAG_INHERIT_ONLY ) ;
/* flags greater than 0xf have diverged :-(. */
/* See the nfs4 ace flag definitions here:
http : //www.ietf.org/rfc/rfc3530.txt.
And the Windows ace flag definitions here :
librpc / idl / security . idl . */
if ( nfs4_ace_flags & SMB_ACE4_INHERITED_ACE ) {
win_ace_flags | = SEC_ACE_FLAG_INHERITED_ACE ;
}
return win_ace_flags ;
}
static uint32_t map_windows_ace_flags_to_nfs4_ace_flags ( uint32_t win_ace_flags )
{
uint32_t nfs4_ace_flags = 0 ;
/* The windows flags <= 0xf map perfectly. */
nfs4_ace_flags = win_ace_flags & ( SMB_ACE4_FILE_INHERIT_ACE |
SMB_ACE4_DIRECTORY_INHERIT_ACE |
SMB_ACE4_NO_PROPAGATE_INHERIT_ACE |
SMB_ACE4_INHERIT_ONLY_ACE ) ;
/* flags greater than 0xf have diverged :-(. */
/* See the nfs4 ace flag definitions here:
http : //www.ietf.org/rfc/rfc3530.txt.
And the Windows ace flag definitions here :
librpc / idl / security . idl . */
if ( win_ace_flags & SEC_ACE_FLAG_INHERITED_ACE ) {
nfs4_ace_flags | = SMB_ACE4_INHERITED_ACE ;
}
return nfs4_ace_flags ;
}
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * smb_create_smb4acl ( TALLOC_CTX * mem_ctx )
2006-09-18 06:27:48 +04:00
{
2015-08-12 08:31:01 +03:00
struct SMB4ACL_T * theacl ;
theacl = talloc_zero ( mem_ctx , struct SMB4ACL_T ) ;
2009-02-24 02:03:29 +03:00
if ( theacl = = NULL )
2006-09-18 06:27:48 +04:00
{
2007-04-28 03:18:41 +04:00
DEBUG ( 0 , ( " TALLOC_SIZE failed \n " ) ) ;
2006-09-18 06:27:48 +04:00
errno = ENOMEM ;
return NULL ;
}
2014-01-20 18:12:42 +04:00
theacl - > controlflags = SEC_DESC_SELF_RELATIVE ;
2009-02-24 02:03:29 +03:00
/* theacl->first, last = NULL not needed */
2015-08-11 14:37:42 +03:00
return theacl ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:12:46 +03:00
struct SMB4ACE_T * smb_add_ace4 ( struct SMB4ACL_T * acl , SMB_ACE4PROP_T * prop )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * ace ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:33:40 +03:00
ace = talloc_zero ( acl , struct SMB4ACE_T ) ;
2006-09-18 06:27:48 +04:00
if ( ace = = NULL )
{
2017-08-15 06:58:05 +03:00
DBG_ERR ( " talloc_zero failed \n " ) ;
2006-09-18 06:27:48 +04:00
errno = ENOMEM ;
return NULL ;
}
2017-08-15 07:02:13 +03:00
ace - > prop = * prop ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
if ( acl - > first = = NULL )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:12:46 +03:00
acl - > first = ace ;
acl - > last = ace ;
2006-09-18 06:27:48 +04:00
} else {
2015-08-11 14:37:42 +03:00
acl - > last - > next = ace ;
2015-08-11 14:12:46 +03:00
acl - > last = ace ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:12:46 +03:00
acl - > naces + + ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:37:42 +03:00
return ace ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 13:35:20 +03:00
SMB_ACE4PROP_T * smb_get_ace4 ( struct SMB4ACE_T * ace )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:12:46 +03:00
if ( ace = = NULL ) {
2006-09-18 06:27:48 +04:00
return NULL ;
2015-08-11 14:12:46 +03:00
}
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
return & ace - > prop ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 13:35:20 +03:00
struct SMB4ACE_T * smb_next_ace4 ( struct SMB4ACE_T * ace )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:12:46 +03:00
if ( ace = = NULL ) {
2006-09-18 06:27:48 +04:00
return NULL ;
2015-08-11 14:12:46 +03:00
}
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
return ace - > next ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:12:46 +03:00
struct SMB4ACE_T * smb_first_ace4 ( struct SMB4ACL_T * acl )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:12:46 +03:00
if ( acl = = NULL ) {
2006-09-18 06:27:48 +04:00
return NULL ;
2015-08-11 14:12:46 +03:00
}
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
return acl - > first ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:12:46 +03:00
uint32_t smb_get_naces ( struct SMB4ACL_T * acl )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:12:46 +03:00
if ( acl = = NULL ) {
2006-09-18 06:27:48 +04:00
return 0 ;
2015-08-11 14:12:46 +03:00
}
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
return acl - > naces ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:12:46 +03:00
uint16_t smbacl4_get_controlflags ( struct SMB4ACL_T * acl )
2014-01-20 18:12:42 +04:00
{
2015-08-11 14:12:46 +03:00
if ( acl = = NULL ) {
2014-01-20 18:12:42 +04:00
return 0 ;
2015-08-11 14:12:46 +03:00
}
2014-01-20 18:12:42 +04:00
2015-08-11 14:12:46 +03:00
return acl - > controlflags ;
2014-01-20 18:12:42 +04:00
}
2015-08-11 14:12:46 +03:00
bool smbacl4_set_controlflags ( struct SMB4ACL_T * acl , uint16_t controlflags )
2014-01-20 18:12:42 +04:00
{
2015-08-11 14:12:46 +03:00
if ( acl = = NULL ) {
2014-01-20 18:12:42 +04:00
return false ;
2015-08-11 14:12:46 +03:00
}
2014-01-20 18:12:42 +04:00
2015-08-11 14:12:46 +03:00
acl - > controlflags = controlflags ;
2014-01-20 18:12:42 +04:00
return true ;
}
2019-06-26 23:20:17 +03:00
bool nfs_ace_is_inherit ( SMB_ACE4PROP_T * ace )
{
return ace - > aceFlags & ( SMB_ACE4_INHERIT_ONLY_ACE |
SMB_ACE4_FILE_INHERIT_ACE |
SMB_ACE4_DIRECTORY_INHERIT_ACE ) ;
}
2007-11-09 03:01:55 +03:00
static int smbacl4_GetFileOwner ( struct connection_struct * conn ,
2016-03-11 03:17:32 +03:00
const struct smb_filename * smb_fname ,
2007-11-09 03:01:55 +03:00
SMB_STRUCT_STAT * psbuf )
2006-09-18 06:27:48 +04:00
{
2015-08-11 13:12:53 +03:00
ZERO_STRUCTP ( psbuf ) ;
2007-11-09 03:01:55 +03:00
/* Get the stat struct for the owner info. */
2016-03-19 08:17:30 +03:00
if ( vfs_stat_smb_basename ( conn , smb_fname , psbuf ) ! = 0 )
2007-11-09 03:01:55 +03:00
{
2015-05-01 23:09:36 +03:00
DEBUG ( 8 , ( " vfs_stat_smb_basename failed with error %s \n " ,
2007-11-09 03:01:55 +03:00
strerror ( errno ) ) ) ;
return - 1 ;
}
return 0 ;
}
2019-07-03 01:08:11 +03:00
static void check_for_duplicate_sec_ace ( struct security_ace * nt_ace_list ,
int * good_aces )
{
struct security_ace * last = NULL ;
int i ;
if ( * good_aces < 2 ) {
return ;
}
last = & nt_ace_list [ ( * good_aces ) - 1 ] ;
for ( i = 0 ; i < ( * good_aces ) - 1 ; i + + ) {
struct security_ace * cur = & nt_ace_list [ i ] ;
if ( cur - > type = = last - > type & &
cur - > flags = = last - > flags & &
cur - > access_mask = = last - > access_mask & &
dom_sid_equal ( & cur - > trustee , & last - > trustee ) )
{
struct dom_sid_buf sid_buf ;
DBG_INFO ( " Removing duplicate entry for SID %s. \n " ,
dom_sid_str_buf ( & last - > trustee , & sid_buf ) ) ;
( * good_aces ) - - ;
}
}
}
2012-07-26 19:29:12 +04:00
static bool smbacl4_nfs42win ( TALLOC_CTX * mem_ctx ,
2016-08-09 10:10:19 +03:00
const struct smbacl4_vfs_params * params ,
2015-08-11 14:12:46 +03:00
struct SMB4ACL_T * acl , /* in */
2010-05-21 05:25:01 +04:00
struct dom_sid * psid_owner , /* in */
struct dom_sid * psid_group , /* in */
2009-02-20 19:23:52 +03:00
bool is_directory , /* in */
2010-05-18 05:25:38 +04:00
struct security_ace * * ppnt_ace_list , /* out */
2006-09-18 06:27:48 +04:00
int * pgood_aces /* out */
)
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * aceint ;
2010-05-18 05:25:38 +04:00
struct security_ace * nt_ace_list = NULL ;
2006-09-18 06:27:48 +04:00
int good_aces = 0 ;
2015-02-05 14:47:22 +03:00
DEBUG ( 10 , ( " %s entered \n " , __func__ ) ) ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:34:35 +03:00
nt_ace_list = talloc_zero_array ( mem_ctx , struct security_ace ,
2 * acl - > naces ) ;
2007-06-02 10:28:38 +04:00
if ( nt_ace_list = = NULL )
{
2015-08-11 14:12:46 +03:00
DEBUG ( 10 , ( " talloc error with %d aces " , acl - > naces ) ) ;
2007-06-02 10:28:38 +04:00
errno = ENOMEM ;
2013-05-08 00:58:26 +04:00
return false ;
2006-09-18 06:27:48 +04:00
}
2015-08-11 14:37:42 +03:00
for ( aceint = acl - > first ; aceint ! = NULL ; aceint = aceint - > next ) {
2008-10-09 20:49:03 +04:00
uint32_t mask ;
2010-05-21 05:25:01 +04:00
struct dom_sid sid ;
2018-12-11 19:17:46 +03:00
struct dom_sid_buf buf ;
2006-09-18 06:27:48 +04:00
SMB_ACE4PROP_T * ace = & aceint - > prop ;
2011-06-01 02:37:30 +04:00
uint32_t win_ace_flags ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
DEBUG ( 10 , ( " type: %d, iflags: %x, flags: %x, "
2011-09-16 01:35:05 +04:00
" mask: %x, who: %d \n " ,
2015-08-11 14:12:46 +03:00
ace - > aceType , ace - > flags ,
2011-09-16 01:35:05 +04:00
ace - > aceFlags , ace - > aceMask , ace - > who . id ) ) ;
2006-09-18 06:27:48 +04:00
if ( ace - > flags & SMB_ACE4_ID_SPECIAL ) {
switch ( ace - > who . special_id ) {
case SMB_ACE4_WHO_OWNER :
sid_copy ( & sid , psid_owner ) ;
break ;
case SMB_ACE4_WHO_GROUP :
sid_copy ( & sid , psid_group ) ;
break ;
case SMB_ACE4_WHO_EVERYONE :
sid_copy ( & sid , & global_sid_World ) ;
break ;
default :
DEBUG ( 8 , ( " invalid special who id %d "
" ignored \n " , ace - > who . special_id ) ) ;
2012-04-25 17:10:54 +04:00
continue ;
2006-09-18 06:27:48 +04:00
}
} else {
if ( ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP ) {
gid_to_sid ( & sid , ace - > who . gid ) ;
} else {
uid_to_sid ( & sid , ace - > who . uid ) ;
}
}
DEBUG ( 10 , ( " mapped %d to %s \n " , ace - > who . id ,
2018-12-11 19:17:46 +03:00
dom_sid_str_buf ( & sid , & buf ) ) ) ;
2006-09-18 06:27:48 +04:00
2013-06-21 01:33:30 +04:00
if ( ! is_directory & & params - > map_full_control ) {
/*
* Do we have all access except DELETE_CHILD
* ( not caring about the delete bit ) .
*/
uint32_t test_mask = ( ( ace - > aceMask | SMB_ACE4_DELETE | SMB_ACE4_DELETE_CHILD ) &
SMB_ACE4_ALL_MASKS ) ;
if ( test_mask = = SMB_ACE4_ALL_MASKS ) {
ace - > aceMask | = SMB_ACE4_DELETE_CHILD ;
}
}
2011-09-16 01:35:05 +04:00
win_ace_flags = map_nfs4_ace_flags_to_windows_ace_flags (
ace - > aceFlags ) ;
if ( ! is_directory & &
( win_ace_flags & ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ) ) ) {
2009-08-10 20:18:19 +04:00
/*
* GPFS sets inherits dir_inhert and file_inherit flags
* to files , too , which confuses windows , and seems to
* be wrong anyways . = = > Map these bits away for files .
*/
DEBUG ( 10 , ( " removing inherit flags from nfs4 ace \n " ) ) ;
2011-09-16 01:35:05 +04:00
win_ace_flags & = ~ ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
2009-08-10 20:18:19 +04:00
}
2011-06-01 02:37:30 +04:00
DEBUG ( 10 , ( " Windows mapped ace flags: 0x%x => 0x%x \n " ,
ace - > aceFlags , win_ace_flags ) ) ;
2009-08-10 20:18:19 +04:00
2011-09-08 01:57:11 +04:00
mask = ace - > aceMask ;
2012-04-25 17:10:20 +04:00
/* Mapping of owner@ and group@ to creator owner and
creator group . Keep old behavior in mode special . */
if ( params - > mode ! = e_special & &
ace - > flags & SMB_ACE4_ID_SPECIAL & &
( ace - > who . special_id = = SMB_ACE4_WHO_OWNER | |
ace - > who . special_id = = SMB_ACE4_WHO_GROUP ) ) {
DEBUG ( 10 , ( " Map special entry \n " ) ) ;
if ( ! ( win_ace_flags & SEC_ACE_FLAG_INHERIT_ONLY ) ) {
uint32_t win_ace_flags_current ;
2013-05-17 17:14:58 +04:00
DEBUG ( 10 , ( " Map current sid \n " ) ) ;
2012-04-25 17:10:20 +04:00
win_ace_flags_current = win_ace_flags &
~ ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
init_sec_ace ( & nt_ace_list [ good_aces + + ] , & sid ,
ace - > aceType , mask ,
win_ace_flags_current ) ;
}
if ( ace - > who . special_id = = SMB_ACE4_WHO_OWNER & &
win_ace_flags & ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ) ) {
uint32_t win_ace_flags_creator ;
DEBUG ( 10 , ( " Map creator owner \n " ) ) ;
win_ace_flags_creator = win_ace_flags |
SMB_ACE4_INHERIT_ONLY_ACE ;
init_sec_ace ( & nt_ace_list [ good_aces + + ] ,
& global_sid_Creator_Owner ,
ace - > aceType , mask ,
win_ace_flags_creator ) ;
}
if ( ace - > who . special_id = = SMB_ACE4_WHO_GROUP & &
win_ace_flags & ( SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ) ) {
uint32_t win_ace_flags_creator ;
DEBUG ( 10 , ( " Map creator owner group \n " ) ) ;
win_ace_flags_creator = win_ace_flags |
SMB_ACE4_INHERIT_ONLY_ACE ;
init_sec_ace ( & nt_ace_list [ good_aces + + ] ,
& global_sid_Creator_Group ,
ace - > aceType , mask ,
win_ace_flags_creator ) ;
}
} else {
DEBUG ( 10 , ( " Map normal sid \n " ) ) ;
init_sec_ace ( & nt_ace_list [ good_aces + + ] , & sid ,
ace - > aceType , mask ,
win_ace_flags ) ;
}
2019-07-03 01:08:11 +03:00
check_for_duplicate_sec_ace ( nt_ace_list , & good_aces ) ;
2012-04-25 17:10:20 +04:00
}
2015-08-11 14:36:45 +03:00
nt_ace_list = talloc_realloc ( mem_ctx , nt_ace_list , struct security_ace ,
good_aces ) ;
2013-10-29 19:20:04 +04:00
/* returns a NULL ace list when good_aces is zero. */
if ( good_aces & & nt_ace_list = = NULL ) {
DEBUG ( 10 , ( " realloc error with %d aces " , good_aces ) ) ;
2012-04-25 17:10:20 +04:00
errno = ENOMEM ;
return false ;
2006-09-18 06:27:48 +04:00
}
* ppnt_ace_list = nt_ace_list ;
* pgood_aces = good_aces ;
2013-05-08 00:58:26 +04:00
return true ;
2006-09-18 06:27:48 +04:00
}
2007-11-15 02:46:20 +03:00
static NTSTATUS smb_get_nt_acl_nfs4_common ( const SMB_STRUCT_STAT * sbuf ,
2016-08-09 10:10:19 +03:00
const struct smbacl4_vfs_params * params ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-07-26 19:29:12 +04:00
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * ppdesc ,
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * theacl )
2006-09-18 06:27:48 +04:00
{
2012-07-26 19:29:12 +04:00
int good_aces = 0 ;
2010-05-21 05:25:01 +04:00
struct dom_sid sid_owner , sid_group ;
2006-09-18 06:27:48 +04:00
size_t sd_size = 0 ;
2010-05-18 05:25:38 +04:00
struct security_ace * nt_ace_list = NULL ;
2010-05-18 05:30:40 +04:00
struct security_acl * psa = NULL ;
2012-10-10 04:50:27 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2015-08-11 15:13:43 +03:00
bool ok ;
2006-09-18 06:27:48 +04:00
2013-08-22 17:01:17 +04:00
if ( theacl = = NULL ) {
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2007-10-13 23:06:49 +04:00
return NT_STATUS_ACCESS_DENIED ; /* special because we
2013-08-22 17:01:17 +04:00
* need to think through
* the null case . */
2013-04-14 12:13:42 +04:00
}
2006-09-18 06:27:48 +04:00
2009-05-14 17:34:42 +04:00
uid_to_sid ( & sid_owner , sbuf - > st_ex_uid ) ;
gid_to_sid ( & sid_group , sbuf - > st_ex_gid ) ;
2006-09-18 06:27:48 +04:00
2015-08-11 15:16:04 +03:00
ok = smbacl4_nfs42win ( frame , params , theacl , & sid_owner , & sid_group ,
2015-08-11 15:13:43 +03:00
S_ISDIR ( sbuf - > st_ex_mode ) ,
& nt_ace_list , & good_aces ) ;
if ( ! ok ) {
2006-09-18 06:27:48 +04:00
DEBUG ( 8 , ( " smbacl4_nfs42win failed \n " ) ) ;
2012-10-10 04:50:27 +04:00
TALLOC_FREE ( frame ) ;
2007-10-13 23:06:49 +04:00
return map_nt_error_from_unix ( errno ) ;
2006-09-18 06:27:48 +04:00
}
2012-10-10 04:50:27 +04:00
psa = make_sec_acl ( frame , NT4_ACL_REVISION , good_aces , nt_ace_list ) ;
2006-09-18 06:27:48 +04:00
if ( psa = = NULL ) {
DEBUG ( 2 , ( " make_sec_acl failed \n " ) ) ;
2012-10-10 04:50:27 +04:00
TALLOC_FREE ( frame ) ;
2007-10-13 23:06:49 +04:00
return NT_STATUS_NO_MEMORY ;
2006-09-18 06:27:48 +04:00
}
DEBUG ( 10 , ( " after make sec_acl \n " ) ) ;
2011-09-16 01:35:05 +04:00
* ppdesc = make_sec_desc (
2014-01-20 18:12:42 +04:00
mem_ctx , SD_REVISION , smbacl4_get_controlflags ( theacl ) ,
2011-09-16 01:35:05 +04:00
( security_info & SECINFO_OWNER ) ? & sid_owner : NULL ,
( security_info & SECINFO_GROUP ) ? & sid_group : NULL ,
NULL , psa , & sd_size ) ;
2006-09-18 06:27:48 +04:00
if ( * ppdesc = = NULL ) {
DEBUG ( 2 , ( " make_sec_desc failed \n " ) ) ;
2012-10-10 04:50:27 +04:00
TALLOC_FREE ( frame ) ;
2007-10-13 23:06:49 +04:00
return NT_STATUS_NO_MEMORY ;
2006-09-18 06:27:48 +04:00
}
2011-09-16 01:35:05 +04:00
DEBUG ( 10 , ( " smb_get_nt_acl_nfs4_common successfully exited with "
" sd_size %d \n " ,
2010-06-03 18:09:31 +04:00
( int ) ndr_size_security_descriptor ( * ppdesc , 0 ) ) ) ;
2007-10-13 23:06:49 +04:00
2012-10-10 04:50:27 +04:00
TALLOC_FREE ( frame ) ;
2007-10-13 23:06:49 +04:00
return NT_STATUS_OK ;
2006-09-18 06:27:48 +04:00
}
2007-11-15 02:46:20 +03:00
NTSTATUS smb_fget_nt_acl_nfs4 ( files_struct * fsp ,
2016-08-09 12:07:38 +03:00
const struct smbacl4_vfs_params * pparams ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2011-09-16 01:35:05 +04:00
struct security_descriptor * * ppdesc ,
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * theacl )
2007-11-15 02:46:20 +03:00
{
2016-08-09 10:07:13 +03:00
struct smbacl4_vfs_params params ;
2007-11-15 02:46:20 +03:00
2009-07-11 05:11:32 +04:00
DEBUG ( 10 , ( " smb_fget_nt_acl_nfs4 invoked for %s \n " , fsp_str_dbg ( fsp ) ) ) ;
2007-11-15 02:46:20 +03:00
2019-07-18 21:16:33 +03:00
if ( ! VALID_STAT ( fsp - > fsp_name - > st ) ) {
NTSTATUS status ;
2016-09-11 14:30:44 +03:00
2019-07-18 21:16:33 +03:00
status = vfs_stat_fsp ( fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2016-09-11 14:30:44 +03:00
}
2007-11-15 02:46:20 +03:00
}
2016-08-09 12:31:12 +03:00
if ( pparams = = NULL ) {
/* Special behaviours */
if ( smbacl4_get_vfs_params ( fsp - > conn , & params ) ) {
return NT_STATUS_NO_MEMORY ;
}
pparams = & params ;
2012-07-26 19:29:12 +04:00
}
2019-07-18 21:16:33 +03:00
return smb_get_nt_acl_nfs4_common ( & fsp - > fsp_name - > st , pparams ,
security_info ,
2012-07-26 19:29:12 +04:00
mem_ctx , ppdesc , theacl ) ;
2007-11-15 02:46:20 +03:00
}
NTSTATUS smb_get_nt_acl_nfs4 ( struct connection_struct * conn ,
2016-03-11 02:56:51 +03:00
const struct smb_filename * smb_fname ,
2016-08-09 12:07:38 +03:00
const struct smbacl4_vfs_params * pparams ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2011-09-16 01:35:05 +04:00
struct security_descriptor * * ppdesc ,
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * theacl )
2007-11-15 02:46:20 +03:00
{
SMB_STRUCT_STAT sbuf ;
2016-08-09 10:07:13 +03:00
struct smbacl4_vfs_params params ;
2016-09-11 14:30:44 +03:00
const SMB_STRUCT_STAT * psbuf = NULL ;
2007-11-15 02:46:20 +03:00
2016-03-11 02:56:51 +03:00
DEBUG ( 10 , ( " smb_get_nt_acl_nfs4 invoked for %s \n " ,
smb_fname - > base_name ) ) ;
2007-11-15 02:46:20 +03:00
2016-09-11 14:30:44 +03:00
if ( VALID_STAT ( smb_fname - > st ) ) {
psbuf = & smb_fname - > st ;
}
if ( psbuf = = NULL ) {
if ( smbacl4_GetFileOwner ( conn , smb_fname , & sbuf ) ) {
return map_nt_error_from_unix ( errno ) ;
}
psbuf = & sbuf ;
2007-11-15 02:46:20 +03:00
}
2016-08-09 12:31:12 +03:00
if ( pparams = = NULL ) {
/* Special behaviours */
if ( smbacl4_get_vfs_params ( conn , & params ) ) {
return NT_STATUS_NO_MEMORY ;
}
pparams = & params ;
2012-07-26 19:29:12 +04:00
}
2016-09-11 14:30:44 +03:00
return smb_get_nt_acl_nfs4_common ( psbuf , pparams , security_info ,
2012-07-26 19:29:12 +04:00
mem_ctx , ppdesc , theacl ) ;
2007-11-15 02:46:20 +03:00
}
2015-08-11 14:12:46 +03:00
static void smbacl4_dump_nfs4acl ( int level , struct SMB4ACL_T * acl )
2006-09-18 06:27:48 +04:00
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * aceint ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:12:46 +03:00
DEBUG ( level , ( " NFS4ACL: size=%d \n " , acl - > naces ) ) ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:37:42 +03:00
for ( aceint = acl - > first ; aceint ! = NULL ; aceint = aceint - > next ) {
2006-09-18 06:27:48 +04:00
SMB_ACE4PROP_T * ace = & aceint - > prop ;
2011-09-16 01:35:05 +04:00
DEBUG ( level , ( " \t ACE: type=%d, flags=0x%x, fflags=0x%x, "
" mask=0x%x, id=%d \n " ,
ace - > aceType ,
ace - > aceFlags , ace - > flags ,
ace - > aceMask ,
ace - > who . id ) ) ;
2006-09-18 06:27:48 +04:00
}
}
2013-05-02 18:50:55 +04:00
/*
2006-09-18 06:27:48 +04:00
* Find 2 NFS4 who - special ACE property ( non - copy ! ! ! )
* match nonzero if " special " and who is equal
* return ace if found matching ; otherwise NULL
*/
static SMB_ACE4PROP_T * smbacl4_find_equal_special (
2015-08-11 14:12:46 +03:00
struct SMB4ACL_T * acl ,
2006-09-18 06:27:48 +04:00
SMB_ACE4PROP_T * aceNew )
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * aceint ;
2006-09-18 06:27:48 +04:00
2015-08-11 14:37:42 +03:00
for ( aceint = acl - > first ; aceint ! = NULL ; aceint = aceint - > next ) {
2006-09-18 06:27:48 +04:00
SMB_ACE4PROP_T * ace = & aceint - > prop ;
2012-07-26 19:29:12 +04:00
DEBUG ( 10 , ( " ace type:0x%x flags:0x%x aceFlags:0x%x "
2009-07-05 18:03:15 +04:00
" new type:0x%x flags:0x%x aceFlags:0x%x \n " ,
ace - > aceType , ace - > flags , ace - > aceFlags ,
aceNew - > aceType , aceNew - > flags , aceNew - > aceFlags ) ) ;
2006-09-18 06:27:48 +04:00
if ( ace - > flags = = aceNew - > flags & &
ace - > aceType = = aceNew - > aceType & &
2011-07-28 11:49:34 +04:00
ace - > aceFlags = = aceNew - > aceFlags )
{
2006-09-18 06:27:48 +04:00
/* keep type safety; e.g. gid is an u.short */
if ( ace - > flags & SMB_ACE4_ID_SPECIAL )
{
2011-09-16 01:35:05 +04:00
if ( ace - > who . special_id = =
aceNew - > who . special_id )
2006-09-18 06:27:48 +04:00
return ace ;
} else {
if ( ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP )
{
if ( ace - > who . gid = = aceNew - > who . gid )
return ace ;
} else {
if ( ace - > who . uid = = aceNew - > who . uid )
return ace ;
}
}
}
}
return NULL ;
}
2019-07-17 01:20:25 +03:00
static int smbacl4_MergeIgnoreReject ( enum smbacl4_acedup_enum acedup ,
struct SMB4ACL_T * theacl ,
SMB_ACE4PROP_T * ace ,
bool * paddNewACE )
{
int result = 0 ;
SMB_ACE4PROP_T * ace4found = smbacl4_find_equal_special ( theacl , ace ) ;
if ( ace4found )
{
switch ( acedup )
{
case e_merge : /* "merge" flags */
* paddNewACE = false ;
ace4found - > aceFlags | = ace - > aceFlags ;
ace4found - > aceMask | = ace - > aceMask ;
break ;
case e_ignore : /* leave out this record */
* paddNewACE = false ;
break ;
case e_reject : /* do an error */
DBG_INFO ( " ACL rejected by duplicate nt ace. \n " ) ;
errno = EINVAL ; /* SHOULD be set on any _real_ error */
result = - 1 ;
break ;
default :
break ;
}
}
return result ;
}
2008-01-16 12:18:57 +03:00
2019-07-17 01:30:36 +03:00
static int nfs4_acl_add_ace ( enum smbacl4_acedup_enum acedup ,
struct SMB4ACL_T * nfs4_acl ,
SMB_ACE4PROP_T * nfs4_ace )
{
bool add_ace = true ;
if ( acedup ! = e_dontcare ) {
int ret ;
ret = smbacl4_MergeIgnoreReject ( acedup , nfs4_acl ,
nfs4_ace , & add_ace ) ;
if ( ret = = - 1 ) {
return - 1 ;
}
}
if ( add_ace ) {
smb_add_ace4 ( nfs4_acl , nfs4_ace ) ;
}
return 0 ;
}
2019-07-18 21:49:29 +03:00
static int nfs4_acl_add_sec_ace ( bool is_directory ,
const struct smbacl4_vfs_params * params ,
uid_t ownerUID ,
gid_t ownerGID ,
const struct security_ace * ace_nt ,
struct SMB4ACL_T * nfs4_acl )
2006-09-18 06:27:48 +04:00
{
2018-12-11 19:17:46 +03:00
struct dom_sid_buf buf ;
2019-07-17 01:30:36 +03:00
SMB_ACE4PROP_T nfs4_ace = { 0 } ;
2019-07-17 20:49:47 +03:00
SMB_ACE4PROP_T nfs4_ace_2 = { 0 } ;
bool add_ace2 = false ;
int ret ;
2018-12-11 19:17:46 +03:00
DEBUG ( 10 , ( " got ace for %s \n " ,
dom_sid_str_buf ( & ace_nt - > trustee , & buf ) ) ) ;
2006-09-18 06:27:48 +04:00
2011-09-16 01:35:05 +04:00
/* only ACCESS|DENY supported right now */
2019-07-17 01:56:12 +03:00
nfs4_ace . aceType = ace_nt - > type ;
2011-09-16 01:35:05 +04:00
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags =
map_windows_ace_flags_to_nfs4_ace_flags ( ace_nt - > flags ) ;
2012-09-25 05:25:36 +04:00
/* remove inheritance flags on files */
2019-06-12 02:15:10 +03:00
if ( ! is_directory ) {
2012-09-25 05:25:36 +04:00
DEBUG ( 10 , ( " Removing inheritance flags from a file \n " ) ) ;
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags & = ~ ( SMB_ACE4_FILE_INHERIT_ACE |
SMB_ACE4_DIRECTORY_INHERIT_ACE |
SMB_ACE4_NO_PROPAGATE_INHERIT_ACE |
SMB_ACE4_INHERIT_ONLY_ACE ) ;
2012-09-25 05:25:36 +04:00
}
2019-07-17 01:56:12 +03:00
nfs4_ace . aceMask = ace_nt - > access_mask & ( SEC_STD_ALL | SEC_FILE_ALL ) ;
2006-09-18 06:27:48 +04:00
2019-07-17 01:56:12 +03:00
se_map_generic ( & nfs4_ace . aceMask , & file_generic_mapping ) ;
2008-09-08 18:42:06 +04:00
2010-09-26 23:04:39 +04:00
if ( dom_sid_equal ( & ace_nt - > trustee , & global_sid_World ) ) {
2019-07-17 01:56:12 +03:00
nfs4_ace . who . special_id = SMB_ACE4_WHO_EVERYONE ;
nfs4_ace . flags | = SMB_ACE4_ID_SPECIAL ;
2012-05-10 16:19:41 +04:00
} else if ( params - > mode ! = e_special & &
dom_sid_equal ( & ace_nt - > trustee ,
& global_sid_Creator_Owner ) ) {
DEBUG ( 10 , ( " Map creator owner \n " ) ) ;
2019-07-17 01:56:12 +03:00
nfs4_ace . who . special_id = SMB_ACE4_WHO_OWNER ;
nfs4_ace . flags | = SMB_ACE4_ID_SPECIAL ;
2012-05-10 16:19:41 +04:00
/* A non inheriting creator owner entry has no effect. */
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags | = SMB_ACE4_INHERIT_ONLY_ACE ;
if ( ! ( nfs4_ace . aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE )
& & ! ( nfs4_ace . aceFlags & SMB_ACE4_FILE_INHERIT_ACE ) ) {
2019-07-17 01:30:36 +03:00
return 0 ;
2012-05-10 16:19:41 +04:00
}
} else if ( params - > mode ! = e_special & &
dom_sid_equal ( & ace_nt - > trustee ,
& global_sid_Creator_Group ) ) {
DEBUG ( 10 , ( " Map creator owner group \n " ) ) ;
2019-07-17 01:56:12 +03:00
nfs4_ace . who . special_id = SMB_ACE4_WHO_GROUP ;
nfs4_ace . flags | = SMB_ACE4_ID_SPECIAL ;
2012-05-10 16:19:41 +04:00
/* A non inheriting creator group entry has no effect. */
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags | = SMB_ACE4_INHERIT_ONLY_ACE ;
if ( ! ( nfs4_ace . aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE )
& & ! ( nfs4_ace . aceFlags & SMB_ACE4_FILE_INHERIT_ACE ) ) {
2019-07-17 01:30:36 +03:00
return 0 ;
2012-05-10 16:19:41 +04:00
}
2006-09-18 06:27:48 +04:00
} else {
2019-06-26 23:24:16 +03:00
struct unixid unixid ;
bool ok ;
2011-09-16 01:24:51 +04:00
2019-06-26 23:24:16 +03:00
ok = sids_to_unixids ( & ace_nt - > trustee , 1 , & unixid ) ;
if ( ! ok ) {
DBG_WARNING ( " Could not convert %s to uid or gid. \n " ,
dom_sid_str_buf ( & ace_nt - > trustee , & buf ) ) ;
2019-07-17 01:30:36 +03:00
return 0 ;
2019-06-26 23:24:16 +03:00
}
2019-07-15 23:15:32 +03:00
if ( dom_sid_compare_domain ( & ace_nt - > trustee ,
& global_sid_Unix_NFS ) = = 0 ) {
2019-07-17 01:30:36 +03:00
return 0 ;
2019-07-15 23:15:32 +03:00
}
switch ( unixid . type ) {
case ID_TYPE_BOTH :
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags | = SMB_ACE4_IDENTIFIER_GROUP ;
nfs4_ace . who . gid = unixid . id ;
2019-07-17 20:49:47 +03:00
if ( ownerUID = = unixid . id & &
! nfs_ace_is_inherit ( & nfs4_ace ) )
{
/*
* IDMAP_TYPE_BOTH for owner . Add
* additional user entry , which can be
* mapped to special : owner to reflect
* the permissions in the modebits .
*
* This only applies to non - inheriting
* entries as only these are replaced
* with SPECIAL_OWNER in nfs4 : mode = simple .
*/
nfs4_ace_2 = ( SMB_ACE4PROP_T ) {
. who . uid = unixid . id ,
. aceFlags = ( nfs4_ace . aceFlags &
~ SMB_ACE4_IDENTIFIER_GROUP ) ,
. aceMask = nfs4_ace . aceMask ,
. aceType = nfs4_ace . aceType ,
} ;
add_ace2 = true ;
}
2019-07-15 23:15:32 +03:00
break ;
case ID_TYPE_GID :
2019-07-17 01:56:12 +03:00
nfs4_ace . aceFlags | = SMB_ACE4_IDENTIFIER_GROUP ;
nfs4_ace . who . gid = unixid . id ;
2019-07-15 23:15:32 +03:00
break ;
case ID_TYPE_UID :
2019-07-17 01:56:12 +03:00
nfs4_ace . who . uid = unixid . id ;
2019-07-15 23:15:32 +03:00
break ;
case ID_TYPE_NOT_SPECIFIED :
default :
DBG_WARNING ( " Could not convert %s to uid or gid. \n " ,
dom_sid_str_buf ( & ace_nt - > trustee , & buf ) ) ;
2019-07-17 01:30:36 +03:00
return 0 ;
2006-09-18 06:27:48 +04:00
}
}
2019-07-17 20:49:47 +03:00
ret = nfs4_acl_add_ace ( params - > acedup , nfs4_acl , & nfs4_ace ) ;
if ( ret ! = 0 ) {
return - 1 ;
}
if ( ! add_ace2 ) {
return 0 ;
}
return nfs4_acl_add_ace ( params - > acedup , nfs4_acl , & nfs4_ace_2 ) ;
2006-09-18 06:27:48 +04:00
}
2019-07-17 01:20:25 +03:00
static void smbacl4_substitute_special ( struct SMB4ACL_T * acl ,
uid_t ownerUID ,
gid_t ownerGID )
2013-05-02 18:50:55 +04:00
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * aceint ;
2013-05-02 18:50:55 +04:00
2015-08-11 14:37:42 +03:00
for ( aceint = acl - > first ; aceint ! = NULL ; aceint = aceint - > next ) {
2013-05-02 18:50:55 +04:00
SMB_ACE4PROP_T * ace = & aceint - > prop ;
DEBUG ( 10 , ( " ace type: %d, iflags: %x, flags: %x, "
" mask: %x, who: %d \n " ,
ace - > aceType , ace - > flags , ace - > aceFlags ,
ace - > aceMask , ace - > who . id ) ) ;
if ( ! ( ace - > flags & SMB_ACE4_ID_SPECIAL ) & &
! ( ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP ) & &
ace - > who . uid = = ownerUID ) {
ace - > flags | = SMB_ACE4_ID_SPECIAL ;
ace - > who . special_id = SMB_ACE4_WHO_OWNER ;
DEBUG ( 10 , ( " replaced with special owner ace \n " ) ) ;
}
if ( ! ( ace - > flags & SMB_ACE4_ID_SPECIAL ) & &
ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP & &
ace - > who . uid = = ownerGID ) {
ace - > flags | = SMB_ACE4_ID_SPECIAL ;
ace - > who . special_id = SMB_ACE4_WHO_GROUP ;
DEBUG ( 10 , ( " replaced with special group ace \n " ) ) ;
}
}
}
2019-06-19 23:42:19 +03:00
static void smbacl4_substitute_simple ( struct SMB4ACL_T * acl ,
uid_t ownerUID ,
gid_t ownerGID )
2013-05-02 18:53:35 +04:00
{
2015-08-11 14:04:05 +03:00
struct SMB4ACE_T * aceint ;
2013-05-02 18:53:35 +04:00
2015-08-11 14:37:42 +03:00
for ( aceint = acl - > first ; aceint ! = NULL ; aceint = aceint - > next ) {
2013-05-02 18:53:35 +04:00
SMB_ACE4PROP_T * ace = & aceint - > prop ;
DEBUG ( 10 , ( " ace type: %d, iflags: %x, flags: %x, "
" mask: %x, who: %d \n " ,
ace - > aceType , ace - > flags , ace - > aceFlags ,
ace - > aceMask , ace - > who . id ) ) ;
if ( ! ( ace - > flags & SMB_ACE4_ID_SPECIAL ) & &
! ( ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP ) & &
ace - > who . uid = = ownerUID & &
2019-06-26 23:20:17 +03:00
! nfs_ace_is_inherit ( ace ) ) {
2013-05-02 18:53:35 +04:00
ace - > flags | = SMB_ACE4_ID_SPECIAL ;
ace - > who . special_id = SMB_ACE4_WHO_OWNER ;
DEBUG ( 10 , ( " replaced with special owner ace \n " ) ) ;
}
if ( ! ( ace - > flags & SMB_ACE4_ID_SPECIAL ) & &
ace - > aceFlags & SMB_ACE4_IDENTIFIER_GROUP & &
2019-06-26 01:21:06 +03:00
ace - > who . gid = = ownerGID & &
2019-06-26 23:20:17 +03:00
! nfs_ace_is_inherit ( ace ) ) {
2013-05-02 18:53:35 +04:00
ace - > flags | = SMB_ACE4_ID_SPECIAL ;
ace - > who . special_id = SMB_ACE4_WHO_GROUP ;
DEBUG ( 10 , ( " replaced with special group ace \n " ) ) ;
}
}
}
2015-08-11 13:35:20 +03:00
static struct SMB4ACL_T * smbacl4_win2nfs4 (
2013-04-14 12:13:42 +04:00
TALLOC_CTX * mem_ctx ,
2019-06-12 02:15:10 +03:00
bool is_directory ,
2010-05-18 05:30:40 +04:00
const struct security_acl * dacl ,
2016-08-09 10:10:19 +03:00
const struct smbacl4_vfs_params * pparams ,
2006-09-18 06:27:48 +04:00
uid_t ownerUID ,
gid_t ownerGID
)
{
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * theacl ;
2015-05-03 06:11:02 +03:00
uint32_t i ;
2006-09-18 06:27:48 +04:00
DEBUG ( 10 , ( " smbacl4_win2nfs4 invoked \n " ) ) ;
2013-04-14 12:13:42 +04:00
theacl = smb_create_smb4acl ( mem_ctx ) ;
2009-02-24 02:03:29 +03:00
if ( theacl = = NULL )
2006-09-18 06:27:48 +04:00
return NULL ;
for ( i = 0 ; i < dacl - > num_aces ; i + + ) {
2019-07-17 01:30:36 +03:00
int ret ;
2006-09-18 06:27:48 +04:00
2019-07-18 21:49:29 +03:00
ret = nfs4_acl_add_sec_ace ( is_directory , pparams ,
ownerUID , ownerGID ,
dacl - > aces + i , theacl ) ;
2019-07-17 01:30:36 +03:00
if ( ret = = - 1 ) {
return NULL ;
2019-07-02 23:20:44 +03:00
}
2006-09-18 06:27:48 +04:00
}
2013-05-02 18:53:35 +04:00
if ( pparams - > mode = = e_simple ) {
smbacl4_substitute_simple ( theacl , ownerUID , ownerGID ) ;
}
2013-05-02 18:50:55 +04:00
if ( pparams - > mode = = e_special ) {
smbacl4_substitute_special ( theacl , ownerUID , ownerGID ) ;
}
2009-02-24 02:03:29 +03:00
return theacl ;
2006-09-18 06:27:48 +04:00
}
2013-04-14 11:31:42 +04:00
NTSTATUS smb_set_nt_acl_nfs4 ( vfs_handle_struct * handle , files_struct * fsp ,
2016-08-09 12:07:38 +03:00
const struct smbacl4_vfs_params * pparams ,
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 ,
2006-09-18 06:27:48 +04:00
set_nfs4acl_native_fn_t set_nfs4_native )
{
2016-08-09 10:07:13 +03:00
struct smbacl4_vfs_params params ;
2015-08-11 13:35:20 +03:00
struct SMB4ACL_T * theacl = NULL ;
2019-06-12 02:15:10 +03:00
bool result , is_directory ;
2006-09-18 06:27:48 +04:00
2009-01-23 03:21:02 +03:00
bool set_acl_as_root = false ;
int saved_errno ;
2019-07-18 01:29:06 +03:00
NTSTATUS status ;
2013-04-14 12:13:42 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2006-09-18 06:27:48 +04:00
2009-07-11 05:11:32 +04:00
DEBUG ( 10 , ( " smb_set_nt_acl_nfs4 invoked for %s \n " , fsp_str_dbg ( fsp ) ) ) ;
2006-09-18 06:27:48 +04:00
2010-06-03 01:35:44 +04:00
if ( ( security_info_sent & ( SECINFO_DACL |
2010-06-03 01:25:18 +04:00
SECINFO_GROUP | SECINFO_OWNER ) ) = = 0 )
2006-09-18 06:27:48 +04:00
{
DEBUG ( 9 , ( " security_info_sent (0x%x) ignored \n " ,
security_info_sent ) ) ;
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2011-09-16 01:35:05 +04:00
return NT_STATUS_OK ; /* won't show error - later to be
* refined . . . */
2006-09-18 06:27:48 +04:00
}
2020-02-27 19:01:10 +03:00
if ( security_descriptor_with_ms_nfs ( psd ) ) {
2021-02-23 23:13:37 +03:00
TALLOC_FREE ( frame ) ;
2020-02-27 19:01:10 +03:00
return NT_STATUS_OK ;
}
2016-08-09 12:31:12 +03:00
if ( pparams = = NULL ) {
/* Special behaviours */
if ( smbacl4_get_vfs_params ( fsp - > conn , & params ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
pparams = & params ;
2013-04-14 12:13:42 +04:00
}
2006-09-18 06:27:48 +04:00
2019-07-18 01:29:06 +03:00
status = vfs_stat_fsp ( fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2019-07-18 01:29:06 +03:00
return status ;
2013-04-14 12:13:42 +04:00
}
2006-09-18 06:27:48 +04:00
2019-07-18 01:29:06 +03:00
is_directory = S_ISDIR ( fsp - > fsp_name - > st . st_ex_mode ) ;
2019-06-12 02:15:10 +03:00
2016-08-09 12:31:12 +03:00
if ( pparams - > do_chown ) {
2022-11-30 02:51:10 +03:00
/*
* When the chown succeeds , the special entries in the
* file system ACL refer to the new owner . In order to
* apply the complete information from the DACL ,
* setting the ACL then has to succeed . Track this
* case with set_acl_as_root and set the ACL as root
* accordingly .
*/
2022-07-13 02:32:08 +03:00
status = chown_if_needed ( fsp , security_info_sent , psd ,
& set_acl_as_root ) ;
2007-06-27 02:49:10 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2007-06-27 02:49:10 +04:00
return status ;
2007-03-20 11:17:27 +03:00
}
2006-09-18 06:27:48 +04:00
}
2010-06-03 01:35:44 +04:00
if ( ! ( security_info_sent & SECINFO_DACL ) | | psd - > dacl = = NULL ) {
2011-09-16 01:35:05 +04:00
DEBUG ( 10 , ( " no dacl found; security_info_sent = 0x%x \n " ,
security_info_sent ) ) ;
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2009-01-23 03:21:02 +03:00
return NT_STATUS_OK ;
}
2006-09-18 06:27:48 +04:00
2019-06-12 02:15:10 +03:00
theacl = smbacl4_win2nfs4 ( frame , is_directory , psd - > dacl , pparams ,
2019-07-18 01:29:06 +03:00
fsp - > fsp_name - > st . st_ex_uid ,
fsp - > fsp_name - > st . st_ex_gid ) ;
2013-04-14 12:13:42 +04:00
if ( ! theacl ) {
TALLOC_FREE ( frame ) ;
2009-01-23 03:21:02 +03:00
return map_nt_error_from_unix ( errno ) ;
2013-04-14 12:13:42 +04:00
}
2006-09-18 06:27:48 +04:00
2014-01-20 18:12:42 +04:00
smbacl4_set_controlflags ( theacl , psd - > type ) ;
2009-02-24 02:03:29 +03:00
smbacl4_dump_nfs4acl ( 10 , theacl ) ;
2006-09-18 06:27:48 +04:00
2009-01-23 03:21:02 +03:00
if ( set_acl_as_root ) {
become_root ( ) ;
}
2013-04-14 11:31:42 +04:00
result = set_nfs4_native ( handle , fsp , theacl ) ;
2009-01-23 03:21:02 +03:00
saved_errno = errno ;
if ( set_acl_as_root ) {
unbecome_root ( ) ;
}
2013-04-14 12:13:42 +04:00
TALLOC_FREE ( frame ) ;
2013-05-08 00:58:26 +04:00
if ( result ! = true ) {
2009-01-23 03:21:02 +03:00
errno = saved_errno ;
2011-09-16 01:35:05 +04:00
DEBUG ( 10 , ( " set_nfs4_native failed with %s \n " ,
strerror ( errno ) ) ) ;
2009-01-23 03:21:02 +03:00
return map_nt_error_from_unix ( errno ) ;
2008-01-16 12:18:57 +03:00
}
2006-09-18 06:27:48 +04:00
DEBUG ( 10 , ( " smb_set_nt_acl_nfs4 succeeded \n " ) ) ;
2007-06-27 02:49:10 +04:00
return NT_STATUS_OK ;
2006-09-18 06:27:48 +04:00
}