2023-03-03 20:48:25 +03:00
/*
2003-10-06 05:24:48 +04:00
* Unix SMB / Netbios implementation .
2009-03-01 19:59:30 +03:00
* struct security_ace handling functions
2003-10-06 05:24:48 +04:00
* Copyright ( C ) Andrew Tridgell 1992 - 1998 ,
* Copyright ( C ) Jeremy R . Allison 1995 - 2003.
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998 ,
* Copyright ( C ) Paul Ashton 1997 - 1998.
2023-03-03 20:48:25 +03:00
*
2003-10-06 05:24: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
2003-10-06 05:24:48 +04:00
* ( at your option ) any later version .
2023-03-03 20:48:25 +03:00
*
2003-10-06 05:24:48 +04: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 20:48:25 +03:00
*
2003-10-06 05:24:48 +04:00
* 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/>.
2003-10-06 05:24:48 +04:00
*/
2023-03-03 20:41:33 +03:00
# include "replace.h"
2009-03-01 19:59:30 +03:00
# include "librpc/gen_ndr/ndr_security.h"
2010-10-12 08:27:50 +04:00
# include "libcli/security/security.h"
2010-02-14 01:58:13 +03:00
# include "lib/util/tsort.h"
2003-10-06 05:24:48 +04:00
2009-03-01 19:59:30 +03:00
/**
* Check if ACE has OBJECT type .
*/
bool sec_ace_object ( uint8_t type )
2003-10-06 05:24:48 +04:00
{
if ( type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT | |
2023-06-04 02:43:13 +03:00
type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT | |
type = = SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT | |
2023-06-04 02:43:57 +03:00
type = = SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT | |
type = = SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT | |
type = = SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT | |
type = = SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT ) {
/*
* MS - DTYP has a reserved value for
* SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT , but we
* don ' t assume that it will be an object ACE just
* because it sounds like one .
*/
2009-03-01 19:59:30 +03:00
return true ;
2003-10-06 05:24:48 +04:00
}
2009-03-01 19:59:30 +03:00
return false ;
2003-10-06 05:24:48 +04:00
}
2022-12-09 01:42:38 +03:00
/**
* Check if ACE is a CALLBACK type , which means it will have a blob of data at
* the end .
*/
bool sec_ace_callback ( uint8_t type )
{
if ( type = = SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK | |
type = = SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK | |
type = = SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT | |
type = = SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT | |
type = = SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK | |
type = = SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT ) {
/*
* While SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK and
* SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT sound like
* callback types , they are reserved values in MS - DTYP ,
* and their eventual use is not defined .
*/
return true ;
}
return false ;
}
2023-08-23 03:44:26 +03:00
/**
* Check if an ACE type is resource attribute , which means it will
* have a blob of data at the end defining an attribute on the object .
* Resource attribute ACEs should only occur in SACLs .
*/
bool sec_ace_resource ( uint8_t type )
{
return type = = SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE ;
}
2022-12-09 01:42:38 +03:00
2023-08-23 03:47:53 +03:00
bool sec_ace_has_extra_blob ( uint8_t type )
{
return sec_ace_callback ( type ) | | sec_ace_resource ( type ) ;
}
2003-10-06 05:24:48 +04:00
/*******************************************************************
2009-03-01 19:59:30 +03:00
Sets up a struct security_ace structure .
2003-10-06 05:24:48 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 19:59:30 +03:00
void init_sec_ace ( struct security_ace * t , const struct dom_sid * sid , enum security_ace_type type ,
uint32_t mask , uint8_t flag )
2003-10-06 05:24:48 +04:00
{
t - > type = type ;
t - > flags = flag ;
2010-05-09 19:20:01 +04:00
t - > size = ndr_size_dom_sid ( sid , 0 ) + 8 ;
2006-09-21 02:23:12 +04:00
t - > access_mask = mask ;
2003-10-06 05:24:48 +04:00
2009-03-01 19:59:30 +03:00
t - > trustee = * sid ;
2023-07-13 12:31:50 +03:00
t - > coda . ignored . data = NULL ;
t - > coda . ignored . length = 0 ;
2003-10-06 05:24:48 +04:00
}
2010-10-09 03:50:40 +04:00
int nt_ace_inherit_comp ( const struct security_ace * a1 , const struct security_ace * a2 )
2003-10-06 05:24:48 +04:00
{
int a1_inh = a1 - > flags & SEC_ACE_FLAG_INHERITED_ACE ;
int a2_inh = a2 - > flags & SEC_ACE_FLAG_INHERITED_ACE ;
if ( a1_inh = = a2_inh )
return 0 ;
if ( ! a1_inh & & a2_inh )
return - 1 ;
return 1 ;
}
/*******************************************************************
Comparison function to apply the order explained below in a group .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-09 03:50:40 +04:00
int nt_ace_canon_comp ( const struct security_ace * a1 , const struct security_ace * a2 )
2003-10-06 05:24:48 +04:00
{
if ( ( a1 - > type = = SEC_ACE_TYPE_ACCESS_DENIED ) & &
( a2 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED ) )
return - 1 ;
if ( ( a2 - > type = = SEC_ACE_TYPE_ACCESS_DENIED ) & &
( a1 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED ) )
return 1 ;
/* Both access denied or access allowed. */
/* 1. ACEs that apply to the object itself */
if ( ! ( a1 - > flags & SEC_ACE_FLAG_INHERIT_ONLY ) & &
( a2 - > flags & SEC_ACE_FLAG_INHERIT_ONLY ) )
return - 1 ;
else if ( ! ( a2 - > flags & SEC_ACE_FLAG_INHERIT_ONLY ) & &
( a1 - > flags & SEC_ACE_FLAG_INHERIT_ONLY ) )
return 1 ;
/* 2. ACEs that apply to a subobject of the object, such as
* a property set or property . */
if ( a1 - > flags & ( SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_OBJECT_INHERIT ) & &
! ( a2 - > flags & ( SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_OBJECT_INHERIT ) ) )
return - 1 ;
else if ( a2 - > flags & ( SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_OBJECT_INHERIT ) & &
! ( a1 - > flags & ( SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_OBJECT_INHERIT ) ) )
return 1 ;
return 0 ;
}
/*******************************************************************
Functions to convert a SEC_DESC ACE DACL list into canonical order .
JRA .
- - - from http : //msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
The following describes the preferred order :
To ensure that noninherited ACEs have precedence over inherited ACEs ,
place all noninherited ACEs in a group before any inherited ACEs .
This ordering ensures , for example , that a noninherited access - denied ACE
is enforced regardless of any inherited ACE that allows access .
Within the groups of noninherited ACEs and inherited ACEs , order ACEs according to ACE type , as the following shows :
1. Access - denied ACEs that apply to the object itself
2. Access - denied ACEs that apply to a subobject of the object , such as a property set or property
3. Access - allowed ACEs that apply to the object itself
4. Access - allowed ACEs that apply to a subobject of the object "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 19:59:30 +03:00
void dacl_sort_into_canonical_order ( struct security_ace * srclist , unsigned int num_aces )
2003-10-06 05:24:48 +04:00
{
unsigned int i ;
if ( ! srclist | | num_aces = = 0 )
return ;
/* Sort so that non-inherited ACE's come first. */
2010-02-14 01:58:13 +03:00
TYPESAFE_QSORT ( srclist , num_aces , nt_ace_inherit_comp ) ;
2003-10-06 05:24:48 +04:00
/* Find the boundary between non-inherited ACEs. */
for ( i = 0 ; i < num_aces ; i + + ) {
2009-03-01 19:59:30 +03:00
struct security_ace * curr_ace = & srclist [ i ] ;
2003-10-06 05:24:48 +04:00
if ( curr_ace - > flags & SEC_ACE_FLAG_INHERITED_ACE )
break ;
}
/* i now points at entry number of the first inherited ACE. */
/* Sort the non-inherited ACEs. */
2010-02-14 01:58:13 +03:00
TYPESAFE_QSORT ( srclist , i , nt_ace_canon_comp ) ;
2003-10-06 05:24:48 +04:00
/* Now sort the inherited ACEs. */
2010-02-14 01:58:13 +03:00
TYPESAFE_QSORT ( & srclist [ i ] , num_aces - i , nt_ace_canon_comp ) ;
2003-10-06 05:24:48 +04:00
}