2023-03-03 18:48:25 +01:00
/*
2004-05-28 13:23:30 +00:00
Unix SMB / CIFS implementation .
2023-03-03 18:57:34 +01:00
security descriptor utility functions
2004-05-28 13:23:30 +00:00
Copyright ( C ) Andrew Tridgell 2004
2023-03-03 18:48:25 +01:00
2004-05-28 13:23:30 +00: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-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-05-28 13:23:30 +00:00
( at your option ) any later version .
2023-03-03 18:48:25 +01:00
2004-05-28 13:23:30 +00:00
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 .
2023-03-03 18:48:25 +01:00
2004-05-28 13:23:30 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-05-28 13:23:30 +00:00
*/
2023-03-03 18:41:33 +01:00
# include "replace.h"
2010-10-12 15:27:50 +11:00
# include "libcli/security/security.h"
2022-09-19 22:50:58 +02:00
# include "librpc/ndr/libndr.h"
2004-05-28 13:23:30 +00:00
/*
return a blank security descriptor ( no owners , dacl or sacl )
*/
2004-11-17 14:35:29 +00:00
struct security_descriptor * security_descriptor_initialise ( TALLOC_CTX * mem_ctx )
2004-05-28 13:23:30 +00:00
{
struct security_descriptor * sd ;
2005-01-27 07:08:20 +00:00
sd = talloc ( mem_ctx , struct security_descriptor ) ;
2004-05-28 13:23:30 +00:00
if ( ! sd ) {
return NULL ;
}
sd - > revision = SD_REVISION ;
/* we mark as self relative, even though it isn't while it remains
a pointer in memory because this simplifies the ndr code later .
All SDs that we store / emit are in fact SELF_RELATIVE
*/
sd - > type = SEC_DESC_SELF_RELATIVE ;
sd - > owner_sid = NULL ;
sd - > group_sid = NULL ;
sd - > sacl = NULL ;
sd - > dacl = NULL ;
return sd ;
}
2009-09-14 19:44:41 +03:00
struct security_acl * security_acl_dup ( TALLOC_CTX * mem_ctx ,
2005-04-15 14:45:00 +00:00
const struct security_acl * oacl )
{
struct security_acl * nacl ;
2010-05-25 16:14:37 -04:00
if ( oacl = = NULL ) {
return NULL ;
}
2018-12-12 10:08:53 +01:00
if ( oacl - > aces = = NULL & & oacl - > num_aces > 0 ) {
return NULL ;
}
2005-04-15 14:45:00 +00:00
nacl = talloc ( mem_ctx , struct security_acl ) ;
if ( nacl = = NULL ) {
return NULL ;
}
2018-12-12 10:21:25 +01:00
* nacl = ( struct security_acl ) {
. revision = oacl - > revision ,
. size = oacl - > size ,
. num_aces = oacl - > num_aces ,
} ;
if ( nacl - > num_aces = = 0 ) {
return nacl ;
}
2007-09-08 13:27:14 +00:00
nacl - > aces = ( struct security_ace * ) talloc_memdup ( nacl , oacl - > aces , sizeof ( struct security_ace ) * oacl - > num_aces ) ;
2018-12-12 10:21:25 +01:00
if ( nacl - > aces = = NULL ) {
2005-04-15 14:45:00 +00:00
goto failed ;
}
return nacl ;
failed :
talloc_free ( nacl ) ;
return NULL ;
2023-03-03 18:48:25 +01:00
2005-04-15 14:45:00 +00:00
}
2009-09-20 13:50:34 -07:00
struct security_acl * security_acl_concatenate ( TALLOC_CTX * mem_ctx ,
const struct security_acl * acl1 ,
const struct security_acl * acl2 )
{
struct security_acl * nacl ;
2011-02-16 09:22:43 +01:00
uint32_t i ;
2009-09-20 13:50:34 -07:00
if ( ! acl1 & & ! acl2 )
return NULL ;
if ( ! acl1 ) {
nacl = security_acl_dup ( mem_ctx , acl2 ) ;
return nacl ;
}
if ( ! acl2 ) {
nacl = security_acl_dup ( mem_ctx , acl1 ) ;
return nacl ;
}
nacl = talloc ( mem_ctx , struct security_acl ) ;
if ( nacl = = NULL ) {
return NULL ;
}
nacl - > revision = acl1 - > revision ;
nacl - > size = acl1 - > size + acl2 - > size ;
nacl - > num_aces = acl1 - > num_aces + acl2 - > num_aces ;
if ( nacl - > num_aces = = 0 )
return nacl ;
nacl - > aces = ( struct security_ace * ) talloc_array ( mem_ctx , struct security_ace , acl1 - > num_aces + acl2 - > num_aces ) ;
if ( ( nacl - > aces = = NULL ) & & ( nacl - > num_aces > 0 ) ) {
goto failed ;
}
for ( i = 0 ; i < acl1 - > num_aces ; i + + )
nacl - > aces [ i ] = acl1 - > aces [ i ] ;
for ( i = 0 ; i < acl2 - > num_aces ; i + + )
nacl - > aces [ i + acl1 - > num_aces ] = acl2 - > aces [ i ] ;
return nacl ;
failed :
talloc_free ( nacl ) ;
return NULL ;
}
2023-03-03 18:48:25 +01:00
/*
2004-11-17 14:35:29 +00:00
talloc and copy a security descriptor
*/
2023-03-03 18:48:25 +01:00
struct security_descriptor * security_descriptor_copy ( TALLOC_CTX * mem_ctx ,
2004-11-18 01:02:27 +00:00
const struct security_descriptor * osd )
2004-11-17 14:35:29 +00:00
{
struct security_descriptor * nsd ;
2005-04-15 14:45:00 +00:00
nsd = talloc_zero ( mem_ctx , struct security_descriptor ) ;
if ( ! nsd ) {
return NULL ;
}
if ( osd - > owner_sid ) {
nsd - > owner_sid = dom_sid_dup ( nsd , osd - > owner_sid ) ;
if ( nsd - > owner_sid = = NULL ) {
goto failed ;
}
}
2023-03-03 18:48:25 +01:00
2005-04-15 14:45:00 +00:00
if ( osd - > group_sid ) {
nsd - > group_sid = dom_sid_dup ( nsd , osd - > group_sid ) ;
if ( nsd - > group_sid = = NULL ) {
goto failed ;
}
}
if ( osd - > sacl ) {
nsd - > sacl = security_acl_dup ( nsd , osd - > sacl ) ;
if ( nsd - > sacl = = NULL ) {
goto failed ;
}
}
if ( osd - > dacl ) {
nsd - > dacl = security_acl_dup ( nsd , osd - > dacl ) ;
if ( nsd - > dacl = = NULL ) {
goto failed ;
}
}
2004-11-17 14:35:29 +00:00
2007-10-26 12:56:02 +02:00
nsd - > revision = osd - > revision ;
nsd - > type = osd - > type ;
2004-11-17 14:35:29 +00:00
return nsd ;
2005-04-15 14:45:00 +00:00
failed :
talloc_free ( nsd ) ;
return NULL ;
2004-11-17 14:35:29 +00:00
}
2015-03-26 14:39:35 +01:00
NTSTATUS security_descriptor_for_client ( TALLOC_CTX * mem_ctx ,
const struct security_descriptor * ssd ,
uint32_t sec_info ,
uint32_t access_granted ,
struct security_descriptor * * _csd )
{
struct security_descriptor * csd = NULL ;
uint32_t access_required = 0 ;
* _csd = NULL ;
if ( sec_info & ( SECINFO_OWNER | SECINFO_GROUP ) ) {
access_required | = SEC_STD_READ_CONTROL ;
}
if ( sec_info & SECINFO_DACL ) {
access_required | = SEC_STD_READ_CONTROL ;
}
if ( sec_info & SECINFO_SACL ) {
access_required | = SEC_FLAG_SYSTEM_SECURITY ;
}
if ( access_required & ( ~ access_granted ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
/*
* make a copy . . .
*/
csd = security_descriptor_copy ( mem_ctx , ssd ) ;
if ( csd = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
/*
* . . . and remove everthing not wanted
*/
if ( ! ( sec_info & SECINFO_OWNER ) ) {
TALLOC_FREE ( csd - > owner_sid ) ;
csd - > type & = ~ SEC_DESC_OWNER_DEFAULTED ;
}
if ( ! ( sec_info & SECINFO_GROUP ) ) {
TALLOC_FREE ( csd - > group_sid ) ;
csd - > type & = ~ SEC_DESC_GROUP_DEFAULTED ;
}
if ( ! ( sec_info & SECINFO_DACL ) ) {
TALLOC_FREE ( csd - > dacl ) ;
csd - > type & = ~ (
SEC_DESC_DACL_PRESENT |
SEC_DESC_DACL_DEFAULTED |
SEC_DESC_DACL_AUTO_INHERIT_REQ |
SEC_DESC_DACL_AUTO_INHERITED |
SEC_DESC_DACL_PROTECTED |
SEC_DESC_DACL_TRUSTED ) ;
}
if ( ! ( sec_info & SECINFO_SACL ) ) {
TALLOC_FREE ( csd - > sacl ) ;
csd - > type & = ~ (
SEC_DESC_SACL_PRESENT |
SEC_DESC_SACL_DEFAULTED |
SEC_DESC_SACL_AUTO_INHERIT_REQ |
SEC_DESC_SACL_AUTO_INHERITED |
SEC_DESC_SACL_PROTECTED |
SEC_DESC_SERVER_SECURITY ) ;
}
* _csd = csd ;
return NT_STATUS_OK ;
}
2004-11-18 01:02:27 +00:00
/*
2007-11-02 12:54:19 +01:00
add an ACE to an ACL of a security_descriptor
2004-11-18 01:02:27 +00:00
*/
2007-11-02 12:54:19 +01:00
static NTSTATUS security_descriptor_acl_add ( struct security_descriptor * sd ,
bool add_to_sacl ,
2023-03-16 10:00:11 +01:00
const struct security_ace * ace ,
ssize_t _idx )
2004-11-18 01:02:27 +00:00
{
2007-11-02 12:54:19 +01:00
struct security_acl * acl = NULL ;
2023-03-16 10:00:11 +01:00
ssize_t idx ;
2007-11-02 12:54:19 +01:00
if ( add_to_sacl ) {
acl = sd - > sacl ;
} else {
acl = sd - > dacl ;
}
if ( acl = = NULL ) {
acl = talloc ( sd , struct security_acl ) ;
if ( acl = = NULL ) {
2004-11-18 01:02:27 +00:00
return NT_STATUS_NO_MEMORY ;
}
2007-11-02 12:54:19 +01:00
acl - > revision = SECURITY_ACL_REVISION_NT4 ;
acl - > size = 0 ;
acl - > num_aces = 0 ;
acl - > aces = NULL ;
2004-11-18 01:02:27 +00:00
}
2023-03-16 10:00:11 +01:00
if ( _idx < 0 ) {
idx = ( acl - > num_aces + 1 ) + _idx ;
} else {
idx = _idx ;
}
if ( idx < 0 ) {
return NT_STATUS_ARRAY_BOUNDS_EXCEEDED ;
} else if ( idx > acl - > num_aces ) {
return NT_STATUS_ARRAY_BOUNDS_EXCEEDED ;
}
2007-11-02 12:54:19 +01:00
acl - > aces = talloc_realloc ( acl , acl - > aces ,
struct security_ace , acl - > num_aces + 1 ) ;
if ( acl - > aces = = NULL ) {
2004-11-18 01:02:27 +00:00
return NT_STATUS_NO_MEMORY ;
}
2023-03-16 10:00:11 +01:00
ARRAY_INSERT_ELEMENT ( acl - > aces , acl - > num_aces , * ace , idx ) ;
acl - > num_aces + + ;
2007-01-15 10:47:22 +00:00
2023-03-16 10:00:11 +01:00
switch ( acl - > aces [ idx ] . type ) {
2007-01-15 10:47:22 +00:00
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT :
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT :
2007-11-02 12:54:19 +01:00
acl - > revision = SECURITY_ACL_REVISION_ADS ;
2007-01-15 10:47:22 +00:00
break ;
default :
break ;
}
2007-11-02 12:54:19 +01:00
if ( add_to_sacl ) {
sd - > sacl = acl ;
sd - > type | = SEC_DESC_SACL_PRESENT ;
} else {
sd - > dacl = acl ;
sd - > type | = SEC_DESC_DACL_PRESENT ;
}
2004-12-02 04:34:11 +00:00
2004-11-18 01:02:27 +00:00
return NT_STATUS_OK ;
}
2007-11-02 12:54:19 +01:00
/*
add an ACE to the SACL of a security_descriptor
*/
NTSTATUS security_descriptor_sacl_add ( struct security_descriptor * sd ,
const struct security_ace * ace )
{
2023-03-16 10:00:11 +01:00
return security_descriptor_acl_add ( sd , true , ace , - 1 ) ;
2007-11-02 12:54:19 +01:00
}
2004-11-18 01:02:27 +00:00
/*
2007-11-02 12:54:19 +01:00
add an ACE to the DACL of a security_descriptor
2004-11-18 01:02:27 +00:00
*/
2007-11-02 12:54:19 +01:00
NTSTATUS security_descriptor_dacl_add ( struct security_descriptor * sd ,
const struct security_ace * ace )
{
2023-03-16 10:00:11 +01:00
return security_descriptor_acl_add ( sd , false , ace , - 1 ) ;
2007-11-02 12:54:19 +01:00
}
/*
delete the ACE corresponding to the given trustee in an ACL of a
security_descriptor
*/
static NTSTATUS security_descriptor_acl_del ( struct security_descriptor * sd ,
bool sacl_del ,
2007-12-23 20:56:41 -06:00
const struct dom_sid * trustee )
2004-11-18 01:02:27 +00:00
{
2011-02-16 09:22:43 +01:00
uint32_t i ;
2007-01-15 10:47:22 +00:00
bool found = false ;
2007-11-02 12:54:19 +01:00
struct security_acl * acl = NULL ;
2004-11-18 01:02:27 +00:00
2007-11-02 12:54:19 +01:00
if ( sacl_del ) {
acl = sd - > sacl ;
} else {
acl = sd - > dacl ;
}
if ( acl = = NULL ) {
2004-11-18 01:02:27 +00:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2007-01-15 10:47:22 +00:00
/* there can be multiple ace's for one trustee */
2007-11-02 12:54:19 +01:00
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
if ( dom_sid_equal ( trustee , & acl - > aces [ i ] . trustee ) ) {
2020-03-26 11:04:31 +01:00
ARRAY_DEL_ELEMENT ( acl - > aces , i , acl - > num_aces ) ;
2007-11-02 12:54:19 +01:00
acl - > num_aces - - ;
if ( acl - > num_aces = = 0 ) {
acl - > aces = NULL ;
2004-11-18 01:02:27 +00:00
}
2007-01-15 10:47:22 +00:00
found = true ;
}
}
if ( ! found ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2007-11-02 12:54:19 +01:00
acl - > revision = SECURITY_ACL_REVISION_NT4 ;
2007-01-15 10:47:22 +00:00
2007-11-02 12:54:19 +01:00
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
switch ( acl - > aces [ i ] . type ) {
2007-01-15 10:47:22 +00:00
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT :
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT :
2007-11-02 12:54:19 +01:00
acl - > revision = SECURITY_ACL_REVISION_ADS ;
2004-11-18 01:02:27 +00:00
return NT_STATUS_OK ;
2007-01-15 10:47:22 +00:00
default :
break ; /* only for the switch statement */
2004-11-18 01:02:27 +00:00
}
}
2007-01-15 10:47:22 +00:00
return NT_STATUS_OK ;
2004-11-18 01:02:27 +00:00
}
2007-11-02 12:54:19 +01:00
/*
delete the ACE corresponding to the given trustee in the DACL of a
security_descriptor
*/
NTSTATUS security_descriptor_dacl_del ( struct security_descriptor * sd ,
2007-12-23 20:56:41 -06:00
const struct dom_sid * trustee )
2007-11-02 12:54:19 +01:00
{
return security_descriptor_acl_del ( sd , false , trustee ) ;
}
/*
delete the ACE corresponding to the given trustee in the SACL of a
security_descriptor
*/
NTSTATUS security_descriptor_sacl_del ( struct security_descriptor * sd ,
2007-12-23 20:56:41 -06:00
const struct dom_sid * trustee )
2007-11-02 12:54:19 +01:00
{
return security_descriptor_acl_del ( sd , true , trustee ) ;
}
2004-11-18 01:02:27 +00:00
2022-09-19 22:47:10 +02:00
/*
delete the given ACE in the SACL or DACL of a security_descriptor
*/
static NTSTATUS security_descriptor_acl_del_ace ( struct security_descriptor * sd ,
bool sacl_del ,
const struct security_ace * ace )
{
uint32_t i ;
bool found = false ;
struct security_acl * acl = NULL ;
if ( sacl_del ) {
acl = sd - > sacl ;
} else {
acl = sd - > dacl ;
}
if ( acl = = NULL ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
if ( security_ace_equal ( ace , & acl - > aces [ i ] ) ) {
ARRAY_DEL_ELEMENT ( acl - > aces , i , acl - > num_aces ) ;
acl - > num_aces - - ;
if ( acl - > num_aces = = 0 ) {
acl - > aces = NULL ;
}
found = true ;
i - - ;
}
}
if ( ! found ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
acl - > revision = SECURITY_ACL_REVISION_NT4 ;
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
switch ( acl - > aces [ i ] . type ) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT :
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT :
acl - > revision = SECURITY_ACL_REVISION_ADS ;
return NT_STATUS_OK ;
default :
break ; /* only for the switch statement */
}
}
return NT_STATUS_OK ;
}
NTSTATUS security_descriptor_dacl_del_ace ( struct security_descriptor * sd ,
const struct security_ace * ace )
{
return security_descriptor_acl_del_ace ( sd , false , ace ) ;
}
NTSTATUS security_descriptor_sacl_del_ace ( struct security_descriptor * sd ,
const struct security_ace * ace )
{
return security_descriptor_acl_del_ace ( sd , true , ace ) ;
}
2022-09-19 22:50:58 +02:00
static bool security_ace_object_equal ( const struct security_ace_object * object1 ,
const struct security_ace_object * object2 )
{
if ( object1 = = object2 ) {
return true ;
}
if ( ( object1 = = NULL ) | | ( object2 = = NULL ) ) {
return false ;
}
if ( object1 - > flags ! = object2 - > flags ) {
return false ;
}
if ( object1 - > flags & SEC_ACE_OBJECT_TYPE_PRESENT
& & ! GUID_equal ( & object1 - > type . type , & object2 - > type . type ) ) {
return false ;
}
if ( object1 - > flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
& & ! GUID_equal ( & object1 - > inherited_type . inherited_type ,
& object2 - > inherited_type . inherited_type ) ) {
return false ;
}
return true ;
}
2004-11-18 01:02:27 +00:00
/*
compare two security ace structures
*/
2014-05-28 17:13:32 +02:00
bool security_ace_equal ( const struct security_ace * ace1 ,
2004-11-18 01:02:27 +00:00
const struct security_ace * ace2 )
{
2014-05-28 17:13:32 +02:00
if ( ace1 = = ace2 ) {
return true ;
}
if ( ( ace1 = = NULL ) | | ( ace2 = = NULL ) ) {
return false ;
}
if ( ace1 - > type ! = ace2 - > type ) {
return false ;
}
if ( ace1 - > flags ! = ace2 - > flags ) {
return false ;
}
if ( ace1 - > access_mask ! = ace2 - > access_mask ) {
return false ;
}
2022-09-19 22:50:58 +02:00
if ( ( ace1 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
| | ace1 - > type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
| | ace1 - > type = = SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
| | ace1 - > type = = SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT )
& & ! security_ace_object_equal ( & ace1 - > object . object ,
& ace2 - > object . object ) ) {
return false ;
}
2014-05-28 17:13:32 +02:00
if ( ! dom_sid_equal ( & ace1 - > trustee , & ace2 - > trustee ) ) {
return false ;
}
2007-10-06 22:28:14 +00:00
2014-05-28 17:13:32 +02:00
return true ;
2004-11-18 01:02:27 +00:00
}
/*
compare two security acl structures
*/
2023-03-03 18:48:25 +01:00
bool security_acl_equal ( const struct security_acl * acl1 ,
2004-11-18 01:02:27 +00:00
const struct security_acl * acl2 )
{
2011-02-16 09:22:43 +01:00
uint32_t i ;
2004-11-18 01:02:27 +00:00
2007-10-06 22:28:14 +00:00
if ( acl1 = = acl2 ) return true ;
if ( ! acl1 | | ! acl2 ) return false ;
if ( acl1 - > revision ! = acl2 - > revision ) return false ;
if ( acl1 - > num_aces ! = acl2 - > num_aces ) return false ;
2004-11-18 01:02:27 +00:00
for ( i = 0 ; i < acl1 - > num_aces ; i + + ) {
2007-10-06 22:28:14 +00:00
if ( ! security_ace_equal ( & acl1 - > aces [ i ] , & acl2 - > aces [ i ] ) ) return false ;
2004-11-18 01:02:27 +00:00
}
2023-03-03 18:48:25 +01:00
return true ;
2004-11-18 01:02:27 +00:00
}
/*
compare two security descriptors .
*/
2023-03-03 18:48:25 +01:00
bool security_descriptor_equal ( const struct security_descriptor * sd1 ,
2004-11-18 01:02:27 +00:00
const struct security_descriptor * sd2 )
{
2007-10-06 22:28:14 +00:00
if ( sd1 = = sd2 ) return true ;
if ( ! sd1 | | ! sd2 ) return false ;
if ( sd1 - > revision ! = sd2 - > revision ) return false ;
if ( sd1 - > type ! = sd2 - > type ) return false ;
2004-11-18 01:02:27 +00:00
2007-10-06 22:28:14 +00:00
if ( ! dom_sid_equal ( sd1 - > owner_sid , sd2 - > owner_sid ) ) return false ;
if ( ! dom_sid_equal ( sd1 - > group_sid , sd2 - > group_sid ) ) return false ;
if ( ! security_acl_equal ( sd1 - > sacl , sd2 - > sacl ) ) return false ;
if ( ! security_acl_equal ( sd1 - > dacl , sd2 - > dacl ) ) return false ;
2004-11-18 01:02:27 +00:00
2023-03-03 18:48:25 +01:00
return true ;
2004-11-18 01:02:27 +00:00
}
2004-11-20 00:29:04 +00:00
/*
compare two security descriptors , but allow certain ( missing ) parts
to be masked out of the comparison
*/
2023-03-03 18:48:25 +01:00
bool security_descriptor_mask_equal ( const struct security_descriptor * sd1 ,
const struct security_descriptor * sd2 ,
2005-01-31 16:06:21 +00:00
uint32_t mask )
2004-11-20 00:29:04 +00:00
{
2007-10-06 22:28:14 +00:00
if ( sd1 = = sd2 ) return true ;
if ( ! sd1 | | ! sd2 ) return false ;
if ( sd1 - > revision ! = sd2 - > revision ) return false ;
if ( ( sd1 - > type & mask ) ! = ( sd2 - > type & mask ) ) return false ;
2004-11-20 00:29:04 +00:00
2007-10-06 22:28:14 +00:00
if ( ! dom_sid_equal ( sd1 - > owner_sid , sd2 - > owner_sid ) ) return false ;
if ( ! dom_sid_equal ( sd1 - > group_sid , sd2 - > group_sid ) ) return false ;
if ( ( mask & SEC_DESC_DACL_PRESENT ) & & ! security_acl_equal ( sd1 - > dacl , sd2 - > dacl ) ) return false ;
if ( ( mask & SEC_DESC_SACL_PRESENT ) & & ! security_acl_equal ( sd1 - > sacl , sd2 - > sacl ) ) return false ;
2004-11-20 00:29:04 +00:00
2023-03-03 18:48:25 +01:00
return true ;
2004-11-20 00:29:04 +00:00
}
2004-12-02 04:34:11 +00:00
2007-11-02 12:54:19 +01:00
static struct security_descriptor * security_descriptor_appendv ( struct security_descriptor * sd ,
bool add_ace_to_sacl ,
va_list ap )
2007-10-10 12:42:55 +02:00
{
const char * sidstr ;
while ( ( sidstr = va_arg ( ap , const char * ) ) ) {
struct dom_sid * sid ;
2009-06-18 11:18:05 +02:00
struct security_ace * ace = talloc_zero ( sd , struct security_ace ) ;
2007-10-10 12:42:55 +02:00
NTSTATUS status ;
if ( ace = = NULL ) {
talloc_free ( sd ) ;
return NULL ;
}
ace - > type = va_arg ( ap , unsigned int ) ;
ace - > access_mask = va_arg ( ap , unsigned int ) ;
ace - > flags = va_arg ( ap , unsigned int ) ;
sid = dom_sid_parse_talloc ( ace , sidstr ) ;
if ( sid = = NULL ) {
talloc_free ( sd ) ;
return NULL ;
}
ace - > trustee = * sid ;
2007-11-02 12:54:19 +01:00
if ( add_ace_to_sacl ) {
status = security_descriptor_sacl_add ( sd , ace ) ;
} else {
status = security_descriptor_dacl_add ( sd , ace ) ;
}
2007-10-10 12:42:55 +02:00
/* TODO: check: would talloc_free(ace) here be correct? */
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( sd ) ;
return NULL ;
}
}
return sd ;
2007-10-10 13:49:15 +02:00
}
2007-10-10 12:42:55 +02:00
2007-11-02 12:54:19 +01:00
static struct security_descriptor * security_descriptor_createv ( TALLOC_CTX * mem_ctx ,
uint16_t sd_type ,
const char * owner_sid ,
const char * group_sid ,
bool add_ace_to_sacl ,
va_list ap )
2004-12-02 04:34:11 +00:00
{
struct security_descriptor * sd ;
sd = security_descriptor_initialise ( mem_ctx ) ;
2007-11-02 12:54:19 +01:00
if ( sd = = NULL ) {
return NULL ;
}
2004-12-02 04:34:11 +00:00
2007-10-10 13:12:53 +02:00
sd - > type | = sd_type ;
2004-12-02 04:34:11 +00:00
if ( owner_sid ) {
2005-08-23 09:45:38 +00:00
sd - > owner_sid = dom_sid_parse_talloc ( sd , owner_sid ) ;
2004-12-02 04:34:11 +00:00
if ( sd - > owner_sid = = NULL ) {
talloc_free ( sd ) ;
return NULL ;
}
}
if ( group_sid ) {
2005-08-23 09:45:38 +00:00
sd - > group_sid = dom_sid_parse_talloc ( sd , group_sid ) ;
2004-12-02 04:34:11 +00:00
if ( sd - > group_sid = = NULL ) {
talloc_free ( sd ) ;
return NULL ;
}
}
2007-11-02 12:54:19 +01:00
return security_descriptor_appendv ( sd , add_ace_to_sacl , ap ) ;
}
/*
create a security descriptor using string SIDs . This is used by the
torture code to allow the easy creation of complex ACLs
This is a varargs function . The list of DACL ACEs ends with a NULL sid .
Each ACE contains a set of 4 parameters :
SID , ACCESS_TYPE , MASK , FLAGS
a typical call would be :
sd = security_descriptor_dacl_create ( mem_ctx ,
sd_type_flags ,
mysid ,
mygroup ,
SID_NT_AUTHENTICATED_USERS ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_FILE_ALL ,
SEC_ACE_FLAG_OBJECT_INHERIT ,
NULL ) ;
that would create a sd with one DACL ACE
*/
struct security_descriptor * security_descriptor_dacl_create ( TALLOC_CTX * mem_ctx ,
uint16_t sd_type ,
const char * owner_sid ,
const char * group_sid ,
. . . )
{
struct security_descriptor * sd = NULL ;
va_list ap ;
va_start ( ap , group_sid ) ;
sd = security_descriptor_createv ( mem_ctx , sd_type , owner_sid ,
group_sid , false , ap ) ;
va_end ( ap ) ;
return sd ;
}
struct security_descriptor * security_descriptor_sacl_create ( TALLOC_CTX * mem_ctx ,
uint16_t sd_type ,
const char * owner_sid ,
const char * group_sid ,
. . . )
{
struct security_descriptor * sd = NULL ;
va_list ap ;
2004-12-02 04:34:11 +00:00
va_start ( ap , group_sid ) ;
2007-11-02 12:54:19 +01:00
sd = security_descriptor_createv ( mem_ctx , sd_type , owner_sid ,
group_sid , true , ap ) ;
2004-12-02 04:34:11 +00:00
va_end ( ap ) ;
return sd ;
}
2007-11-02 11:51:26 +01:00
struct security_ace * security_ace_create ( TALLOC_CTX * mem_ctx ,
const char * sid_str ,
enum security_ace_type type ,
uint32_t access_mask ,
uint8_t flags )
{
struct security_ace * ace ;
2014-05-26 20:48:05 +00:00
bool ok ;
2007-11-02 11:51:26 +01:00
ace = talloc_zero ( mem_ctx , struct security_ace ) ;
if ( ace = = NULL ) {
return NULL ;
}
2014-05-26 20:48:05 +00:00
ok = dom_sid_parse ( sid_str , & ace - > trustee ) ;
if ( ! ok ) {
2007-11-02 11:51:26 +01:00
talloc_free ( ace ) ;
return NULL ;
}
ace - > type = type ;
ace - > access_mask = access_mask ;
ace - > flags = flags ;
return ace ;
}
2014-10-14 13:54:05 +02:00
/*******************************************************************
Check for MS NFS ACEs in a sd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool security_descriptor_with_ms_nfs ( const struct security_descriptor * psd )
{
2020-01-28 15:39:29 +01:00
uint32_t i ;
2014-10-14 13:54:05 +02:00
if ( psd - > dacl = = NULL ) {
return false ;
}
for ( i = 0 ; i < psd - > dacl - > num_aces ; i + + ) {
if ( dom_sid_compare_domain (
& global_sid_Unix_NFS ,
& psd - > dacl - > aces [ i ] . trustee ) = = 0 ) {
return true ;
}
}
return false ;
}