2009-09-14 20:44:41 +04:00
/*
Copyright ( C ) Nadezhda Ivanova 2009
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
the Free Software Foundation ; either version 3 of the License , or
( 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
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/*
* Name : create_descriptor
*
* Component : routines for calculating and creating security descriptors
2010-10-24 00:50:29 +04:00
* as described in MS - DTYP 2.5 .3 . x
2009-09-14 20:44:41 +04:00
*
* Description :
*
*
* Author : Nadezhda Ivanova
*/
# include "includes.h"
# include "libcli/security/security.h"
2009-11-03 14:30:06 +03:00
# include "librpc/gen_ndr/ndr_security.h"
2009-09-14 20:44:41 +04:00
2009-09-21 00:50:34 +04:00
/* Todos:
* build the security token dacl as follows :
* SYSTEM : GA , OWNER : GA , LOGIN_SID : GW | GE
* Need session id information for the login SID . Probably
* the best place for this is during token creation
*
* Implement SD Invariants
* ACE sorting rules
* LDAP_SERVER_SD_FLAGS_OID control
* ADTS 7.1 .3 .3 needs to be clarified
*/
2009-09-14 20:44:41 +04:00
/* the mapping function for generic rights for DS.(GA,GR,GW,GX)
* The mapping function is passed as an argument to the
* descriptor calculating routine and depends on the security
* manager that calls the calculating routine .
* TODO : need similar mappings for the file system and
* registry security managers in order to make this code
* generic for all security managers
*/
uint32_t map_generic_rights_ds ( uint32_t access_mask )
{
2010-04-20 01:23:42 +04:00
if ( access_mask & SEC_GENERIC_ALL ) {
2009-09-14 20:44:41 +04:00
access_mask | = SEC_ADS_GENERIC_ALL ;
2011-01-11 13:20:43 +03:00
access_mask & = ~ SEC_GENERIC_ALL ;
2009-09-14 20:44:41 +04:00
}
2010-04-20 01:23:42 +04:00
if ( access_mask & SEC_GENERIC_EXECUTE ) {
2009-09-14 20:44:41 +04:00
access_mask | = SEC_ADS_GENERIC_EXECUTE ;
2011-01-11 13:20:43 +03:00
access_mask & = ~ SEC_GENERIC_EXECUTE ;
2009-09-14 20:44:41 +04:00
}
2010-04-20 01:23:42 +04:00
if ( access_mask & SEC_GENERIC_WRITE ) {
2009-09-14 20:44:41 +04:00
access_mask | = SEC_ADS_GENERIC_WRITE ;
access_mask & = ~ SEC_GENERIC_WRITE ;
}
2010-04-20 01:23:42 +04:00
if ( access_mask & SEC_GENERIC_READ ) {
2009-09-14 20:44:41 +04:00
access_mask | = SEC_ADS_GENERIC_READ ;
access_mask & = ~ SEC_GENERIC_READ ;
}
return access_mask ;
}
2009-09-21 00:50:34 +04:00
/* Not sure what this has to be,
* and it does not seem to have any influence */
static bool object_in_list ( struct GUID * object_list , struct GUID * object )
{
2012-12-11 05:00:38 +04:00
size_t i ;
if ( object_list = = NULL ) {
return true ;
}
if ( GUID_all_zero ( object ) ) {
return true ;
}
for ( i = 0 ; ; i + + ) {
if ( GUID_all_zero ( & object_list [ i ] ) ) {
return false ;
}
if ( ! GUID_equal ( & object_list [ i ] , object ) ) {
continue ;
}
return true ;
}
return false ;
2009-09-21 00:50:34 +04:00
}
2012-12-11 05:00:38 +04:00
2011-01-11 13:20:43 +03:00
/* returns true if the ACE gontains generic information
* that needs to be processed additionally */
2014-05-27 11:04:38 +04:00
static bool desc_ace_has_generic ( struct security_ace * ace )
2011-01-11 13:20:43 +03:00
{
if ( ace - > access_mask & SEC_GENERIC_ALL | | ace - > access_mask & SEC_GENERIC_READ | |
ace - > access_mask & SEC_GENERIC_WRITE | | ace - > access_mask & SEC_GENERIC_EXECUTE ) {
return true ;
}
2014-05-27 11:04:38 +04:00
if ( dom_sid_equal ( & ace - > trustee , & global_sid_Creator_Owner ) | |
dom_sid_equal ( & ace - > trustee , & global_sid_Creator_Group ) ) {
2011-01-11 13:20:43 +03:00
return true ;
}
return false ;
}
/* creates an ace in which the generic information is expanded */
2014-05-27 11:03:18 +04:00
static void desc_expand_generic ( struct security_ace * new_ace ,
2011-01-11 13:20:43 +03:00
struct dom_sid * owner ,
struct dom_sid * group )
{
new_ace - > access_mask = map_generic_rights_ds ( new_ace - > access_mask ) ;
2014-05-27 11:03:18 +04:00
if ( dom_sid_equal ( & new_ace - > trustee , & global_sid_Creator_Owner ) ) {
2011-01-11 13:20:43 +03:00
new_ace - > trustee = * owner ;
}
2014-05-27 11:03:18 +04:00
if ( dom_sid_equal ( & new_ace - > trustee , & global_sid_Creator_Group ) ) {
2011-01-11 13:20:43 +03:00
new_ace - > trustee = * group ;
}
new_ace - > flags = 0x0 ;
}
2009-09-21 00:50:34 +04:00
static struct security_acl * calculate_inherited_from_parent ( TALLOC_CTX * mem_ctx ,
2010-04-20 01:23:42 +04:00
struct security_acl * acl ,
bool is_container ,
struct dom_sid * owner ,
struct dom_sid * group ,
struct GUID * object_list )
2009-09-21 00:50:34 +04:00
{
2010-09-09 22:31:38 +04:00
uint32_t i ;
2009-09-21 00:50:34 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
2010-04-20 01:23:42 +04:00
struct security_acl * tmp_acl = talloc_zero ( mem_ctx , struct security_acl ) ;
if ( ! tmp_acl ) {
2009-09-21 00:50:34 +04:00
return NULL ;
2010-04-20 01:23:42 +04:00
}
2009-09-21 00:50:34 +04:00
2010-04-15 14:54:23 +04:00
if ( ! acl ) {
return NULL ;
}
2009-09-21 00:50:34 +04:00
2010-04-20 01:23:42 +04:00
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
2009-09-21 00:50:34 +04:00
struct security_ace * ace = & acl - > aces [ i ] ;
if ( ( ace - > flags & SEC_ACE_FLAG_CONTAINER_INHERIT ) | |
2009-11-15 23:31:44 +03:00
( ace - > flags & SEC_ACE_FLAG_OBJECT_INHERIT ) ) {
2013-01-22 18:38:07 +04:00
struct GUID inherited_object = GUID_zero ( ) ;
2011-01-11 13:20:43 +03:00
tmp_acl - > aces = talloc_realloc ( tmp_acl , tmp_acl - > aces ,
struct security_ace ,
2009-09-21 00:50:34 +04:00
tmp_acl - > num_aces + 1 ) ;
if ( tmp_acl - > aces = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NULL ;
}
tmp_acl - > aces [ tmp_acl - > num_aces ] = * ace ;
tmp_acl - > aces [ tmp_acl - > num_aces ] . flags | = SEC_ACE_FLAG_INHERITED_ACE ;
2011-01-18 16:56:19 +03:00
/* remove IO flag from the child's ace */
if ( ace - > flags & SEC_ACE_FLAG_INHERIT_ONLY & &
2014-05-27 11:04:38 +04:00
! desc_ace_has_generic ( ace ) ) {
2011-01-18 16:56:19 +03:00
tmp_acl - > aces [ tmp_acl - > num_aces ] . flags & = ~ SEC_ACE_FLAG_INHERIT_ONLY ;
}
2009-09-21 00:50:34 +04:00
if ( is_container & & ( ace - > flags & SEC_ACE_FLAG_OBJECT_INHERIT ) )
tmp_acl - > aces [ tmp_acl - > num_aces ] . flags | = SEC_ACE_FLAG_INHERIT_ONLY ;
2013-01-22 18:38:07 +04:00
switch ( ace - > type ) {
case SEC_ACE_TYPE_ACCESS_ALLOWED :
case SEC_ACE_TYPE_ACCESS_DENIED :
case SEC_ACE_TYPE_SYSTEM_AUDIT :
case SEC_ACE_TYPE_SYSTEM_ALARM :
case SEC_ACE_TYPE_ALLOWED_COMPOUND :
break ;
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT :
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT :
2012-12-11 06:17:42 +04:00
if ( ace - > object . object . flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT ) {
inherited_object = ace - > object . object . inherited_type . inherited_type ;
}
if ( ! object_in_list ( object_list , & inherited_object ) ) {
2009-09-21 00:50:34 +04:00
tmp_acl - > aces [ tmp_acl - > num_aces ] . flags | = SEC_ACE_FLAG_INHERIT_ONLY ;
}
2013-01-22 18:38:07 +04:00
break ;
2009-09-21 00:50:34 +04:00
}
2013-01-22 18:38:07 +04:00
2009-09-21 00:50:34 +04:00
tmp_acl - > num_aces + + ;
2010-04-20 01:23:42 +04:00
if ( is_container ) {
if ( ! ( ace - > flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT ) & &
2014-05-27 11:04:38 +04:00
( desc_ace_has_generic ( ace ) ) ) {
2011-01-11 13:20:43 +03:00
tmp_acl - > aces = talloc_realloc ( tmp_acl ,
tmp_acl - > aces ,
struct security_ace ,
2010-04-20 01:23:42 +04:00
tmp_acl - > num_aces + 1 ) ;
if ( tmp_acl - > aces = = NULL ) {
talloc_free ( tmp_ctx ) ;
return NULL ;
}
tmp_acl - > aces [ tmp_acl - > num_aces ] = * ace ;
2014-05-27 11:03:18 +04:00
desc_expand_generic ( & tmp_acl - > aces [ tmp_acl - > num_aces ] ,
2011-01-11 13:20:43 +03:00
owner ,
group ) ;
tmp_acl - > aces [ tmp_acl - > num_aces ] . flags = SEC_ACE_FLAG_INHERITED_ACE ;
2010-04-20 01:23:42 +04:00
tmp_acl - > num_aces + + ;
2009-09-21 00:50:34 +04:00
}
}
}
2010-04-20 01:23:42 +04:00
}
if ( tmp_acl - > num_aces = = 0 ) {
2010-04-15 14:54:23 +04:00
return NULL ;
}
2010-04-20 01:23:42 +04:00
if ( acl ) {
tmp_acl - > revision = acl - > revision ;
}
return tmp_acl ;
2009-09-21 00:50:34 +04:00
}
2010-04-20 01:23:42 +04:00
static struct security_acl * process_user_acl ( TALLOC_CTX * mem_ctx ,
struct security_acl * acl ,
bool is_container ,
struct dom_sid * owner ,
struct dom_sid * group ,
2011-02-10 13:39:22 +03:00
struct GUID * object_list ,
bool is_protected )
2009-09-21 00:50:34 +04:00
{
2010-09-09 22:31:38 +04:00
uint32_t i ;
2009-09-21 00:50:34 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
struct security_acl * tmp_acl = talloc_zero ( tmp_ctx , struct security_acl ) ;
struct security_acl * new_acl ;
2010-04-15 14:54:23 +04:00
if ( ! acl )
return NULL ;
2009-09-21 00:50:34 +04:00
if ( ! tmp_acl )
return NULL ;
2009-09-25 03:53:06 +04:00
tmp_acl - > revision = acl - > revision ;
2017-09-07 02:19:01 +03:00
DBG_DEBUG ( " acl revision %d \n " , acl - > revision ) ;
2009-09-25 03:53:06 +04:00
2009-09-21 00:50:34 +04:00
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
struct security_ace * ace = & acl - > aces [ i ] ;
2011-02-10 13:39:22 +03:00
/* Remove ID flags from user-provided ACEs
* if we break inheritance , ignore them otherwise */
if ( ace - > flags & SEC_ACE_FLAG_INHERITED_ACE ) {
if ( is_protected ) {
ace - > flags & = ~ SEC_ACE_FLAG_INHERITED_ACE ;
} else {
continue ;
}
}
2010-04-20 01:23:42 +04:00
if ( ace - > flags & SEC_ACE_FLAG_INHERIT_ONLY & &
! ( ace - > flags & SEC_ACE_FLAG_CONTAINER_INHERIT | |
ace - > flags & SEC_ACE_FLAG_OBJECT_INHERIT ) )
continue ;
2009-09-21 00:50:34 +04:00
2011-01-11 13:20:43 +03:00
tmp_acl - > aces = talloc_realloc ( tmp_acl ,
tmp_acl - > aces ,
struct security_ace ,
2009-09-21 00:50:34 +04:00
tmp_acl - > num_aces + 1 ) ;
tmp_acl - > aces [ tmp_acl - > num_aces ] = * ace ;
tmp_acl - > num_aces + + ;
2011-01-11 13:20:43 +03:00
if ( ace - > flags & SEC_ACE_FLAG_INHERIT_ONLY ) {
continue ;
}
/* if the ACE contains CO, CG, GA, GE, GR or GW, and is inheritable
* it has to be expanded to two aces , the original as IO ,
* and another one where these are translated */
2014-05-27 11:04:38 +04:00
if ( desc_ace_has_generic ( ace ) ) {
2011-01-11 13:20:43 +03:00
if ( ! ( ace - > flags & SEC_ACE_FLAG_CONTAINER_INHERIT ) ) {
2014-05-27 11:03:18 +04:00
desc_expand_generic ( & tmp_acl - > aces [ tmp_acl - > num_aces - 1 ] ,
2011-01-11 13:20:43 +03:00
owner ,
group ) ;
} else {
2011-01-13 16:22:15 +03:00
/*The original ACE becomes read only */
tmp_acl - > aces [ tmp_acl - > num_aces - 1 ] . flags | = SEC_ACE_FLAG_INHERIT_ONLY ;
tmp_acl - > aces = talloc_realloc ( tmp_acl , tmp_acl - > aces ,
struct security_ace ,
tmp_acl - > num_aces + 1 ) ;
/* add a new ACE with expanded generic info */
tmp_acl - > aces [ tmp_acl - > num_aces ] = * ace ;
2014-05-27 11:03:18 +04:00
desc_expand_generic ( & tmp_acl - > aces [ tmp_acl - > num_aces ] ,
2011-01-13 16:22:15 +03:00
owner ,
group ) ;
tmp_acl - > num_aces + + ;
2011-01-11 13:20:43 +03:00
}
}
2009-09-21 00:50:34 +04:00
}
new_acl = security_acl_dup ( mem_ctx , tmp_acl ) ;
2009-11-03 14:30:06 +03:00
if ( new_acl )
new_acl - > revision = acl - > revision ;
2009-09-21 00:50:34 +04:00
talloc_free ( tmp_ctx ) ;
return new_acl ;
}
2009-11-03 14:30:06 +03:00
static void cr_descr_log_descriptor ( struct security_descriptor * sd ,
const char * message ,
int level )
{
if ( sd ) {
DEBUG ( level , ( " %s: %s \n " , message ,
ndr_print_struct_string ( 0 , ( ndr_print_fn_t ) ndr_print_security_descriptor ,
" " , sd ) ) ) ;
}
else {
DEBUG ( level , ( " %s: NULL \n " , message ) ) ;
}
}
2011-05-05 14:52:29 +04:00
#if 0
2009-11-03 14:30:06 +03:00
static void cr_descr_log_acl ( struct security_acl * acl ,
const char * message ,
int level )
{
if ( acl ) {
DEBUG ( level , ( " %s: %s \n " , message ,
ndr_print_struct_string ( 0 , ( ndr_print_fn_t ) ndr_print_security_acl ,
" " , acl ) ) ) ;
}
else {
DEBUG ( level , ( " %s: NULL \n " , message ) ) ;
}
}
2011-05-05 14:52:29 +04:00
# endif
2009-11-03 14:30:06 +03:00
2010-04-15 14:54:23 +04:00
static bool compute_acl ( struct security_descriptor * parent_sd ,
2009-09-21 00:50:34 +04:00
struct security_descriptor * creator_sd ,
bool is_container ,
uint32_t inherit_flags ,
struct GUID * object_list ,
uint32_t ( * generic_map ) ( uint32_t access_mask ) ,
struct security_token * token ,
struct security_descriptor * new_sd ) /* INOUT argument */
{
2010-04-20 01:23:42 +04:00
struct security_acl * user_dacl , * user_sacl , * inherited_dacl , * inherited_sacl ;
2009-11-03 14:30:06 +03:00
int level = 10 ;
2010-04-15 14:54:23 +04:00
if ( ! parent_sd | | ! ( inherit_flags & SEC_DACL_AUTO_INHERIT ) ) {
inherited_dacl = NULL ;
} else if ( creator_sd & & ( creator_sd - > type & SEC_DESC_DACL_PROTECTED ) ) {
inherited_dacl = NULL ;
} else {
inherited_dacl = calculate_inherited_from_parent ( new_sd ,
parent_sd - > dacl ,
is_container ,
2010-04-20 01:23:42 +04:00
new_sd - > owner_sid ,
new_sd - > group_sid ,
2010-04-15 14:54:23 +04:00
object_list ) ;
2009-09-21 00:50:34 +04:00
}
2009-11-03 14:30:06 +03:00
2010-04-15 14:54:23 +04:00
if ( ! parent_sd | | ! ( inherit_flags & SEC_SACL_AUTO_INHERIT ) ) {
inherited_sacl = NULL ;
} else if ( creator_sd & & ( creator_sd - > type & SEC_DESC_SACL_PROTECTED ) ) {
inherited_sacl = NULL ;
} else {
inherited_sacl = calculate_inherited_from_parent ( new_sd ,
parent_sd - > sacl ,
is_container ,
2010-04-20 01:23:42 +04:00
new_sd - > owner_sid ,
new_sd - > group_sid ,
2010-04-15 14:54:23 +04:00
object_list ) ;
}
if ( ! creator_sd | | ( inherit_flags & SEC_DEFAULT_DESCRIPTOR ) ) {
user_dacl = NULL ;
user_sacl = NULL ;
} else {
2010-04-20 01:23:42 +04:00
user_dacl = process_user_acl ( new_sd ,
creator_sd - > dacl ,
is_container ,
new_sd - > owner_sid ,
new_sd - > group_sid ,
2011-02-10 13:39:22 +03:00
object_list ,
creator_sd - > type & SEC_DESC_DACL_PROTECTED ) ;
2010-04-20 01:23:42 +04:00
user_sacl = process_user_acl ( new_sd ,
creator_sd - > sacl ,
is_container ,
new_sd - > owner_sid ,
new_sd - > group_sid ,
2011-02-10 13:39:22 +03:00
object_list ,
creator_sd - > type & SEC_DESC_SACL_PROTECTED ) ;
2009-09-21 00:50:34 +04:00
}
2010-04-15 14:54:23 +04:00
cr_descr_log_descriptor ( parent_sd , __location__ " parent_sd " , level ) ;
cr_descr_log_descriptor ( creator_sd , __location__ " creator_sd " , level ) ;
new_sd - > dacl = security_acl_concatenate ( new_sd , user_dacl , inherited_dacl ) ;
if ( new_sd - > dacl ) {
2009-09-21 00:50:34 +04:00
new_sd - > type | = SEC_DESC_DACL_PRESENT ;
2010-04-15 14:54:23 +04:00
}
if ( inherited_dacl ) {
new_sd - > type | = SEC_DESC_DACL_AUTO_INHERITED ;
}
2009-09-21 00:50:34 +04:00
2010-04-15 14:54:23 +04:00
new_sd - > sacl = security_acl_concatenate ( new_sd , user_sacl , inherited_sacl ) ;
if ( new_sd - > sacl ) {
2009-09-21 00:50:34 +04:00
new_sd - > type | = SEC_DESC_SACL_PRESENT ;
2010-04-15 14:54:23 +04:00
}
if ( inherited_sacl ) {
new_sd - > type | = SEC_DESC_SACL_AUTO_INHERITED ;
}
2009-09-21 00:50:34 +04:00
/* This is a hack to handle the fact that
* apprantly any AI flag provided by the user is preserved */
if ( creator_sd )
new_sd - > type | = creator_sd - > type ;
2009-11-03 14:30:06 +03:00
cr_descr_log_descriptor ( new_sd , __location__ " final sd " , level ) ;
2009-09-21 00:50:34 +04:00
return true ;
}
2009-09-14 20:44:41 +04:00
struct security_descriptor * create_security_descriptor ( TALLOC_CTX * mem_ctx ,
struct security_descriptor * parent_sd ,
struct security_descriptor * creator_sd ,
bool is_container ,
struct GUID * object_list ,
uint32_t inherit_flags ,
struct security_token * token ,
struct dom_sid * default_owner , /* valid only for DS, NULL for the other RSs */
struct dom_sid * default_group , /* valid only for DS, NULL for the other RSs */
uint32_t ( * generic_map ) ( uint32_t access_mask ) )
{
struct security_descriptor * new_sd ;
struct dom_sid * new_owner = NULL ;
struct dom_sid * new_group = NULL ;
new_sd = security_descriptor_initialise ( mem_ctx ) ;
2009-09-25 03:53:06 +04:00
if ( ! new_sd ) {
2009-09-14 20:44:41 +04:00
return NULL ;
2009-09-25 03:53:06 +04:00
}
if ( ! creator_sd | | ! creator_sd - > owner_sid ) {
if ( ( inherit_flags & SEC_OWNER_FROM_PARENT ) & & parent_sd ) {
2009-09-14 20:44:41 +04:00
new_owner = parent_sd - > owner_sid ;
2009-09-25 03:53:06 +04:00
} else if ( ! default_owner ) {
2010-08-20 06:15:15 +04:00
new_owner = & token - > sids [ PRIMARY_USER_SID_INDEX ] ;
2009-09-25 03:53:06 +04:00
} else {
2009-09-14 20:44:41 +04:00
new_owner = default_owner ;
2009-09-25 03:53:06 +04:00
new_sd - > type | = SEC_DESC_OWNER_DEFAULTED ;
}
} else {
2009-09-14 20:44:41 +04:00
new_owner = creator_sd - > owner_sid ;
2009-09-25 03:53:06 +04:00
}
2009-09-14 20:44:41 +04:00
if ( ! creator_sd | | ! creator_sd - > group_sid ) {
2009-09-25 03:53:06 +04:00
if ( ( inherit_flags & SEC_GROUP_FROM_PARENT ) & & parent_sd ) {
2009-09-14 20:44:41 +04:00
new_group = parent_sd - > group_sid ;
2010-08-20 06:15:15 +04:00
} else if ( ! default_group & & token - > num_sids > PRIMARY_GROUP_SID_INDEX ) {
new_group = & token - > sids [ PRIMARY_GROUP_SID_INDEX ] ;
2009-09-25 03:53:06 +04:00
} else if ( ! default_group ) {
2010-08-14 07:30:51 +04:00
/* This will happen only for anonymous, which has no other groups */
2010-08-20 06:15:15 +04:00
new_group = & token - > sids [ PRIMARY_USER_SID_INDEX ] ;
2009-09-25 03:53:06 +04:00
} else {
new_group = default_group ;
new_sd - > type | = SEC_DESC_GROUP_DEFAULTED ;
}
} else {
2009-09-14 20:44:41 +04:00
new_group = creator_sd - > group_sid ;
2009-09-25 03:53:06 +04:00
}
2009-09-14 20:44:41 +04:00
new_sd - > owner_sid = talloc_memdup ( new_sd , new_owner , sizeof ( struct dom_sid ) ) ;
new_sd - > group_sid = talloc_memdup ( new_sd , new_group , sizeof ( struct dom_sid ) ) ;
if ( ! new_sd - > owner_sid | | ! new_sd - > group_sid ) {
talloc_free ( new_sd ) ;
return NULL ;
}
2009-09-21 00:50:34 +04:00
2010-04-15 14:54:23 +04:00
if ( ! compute_acl ( parent_sd , creator_sd ,
2009-09-21 00:50:34 +04:00
is_container , inherit_flags , object_list ,
generic_map , token , new_sd ) ) {
talloc_free ( new_sd ) ;
return NULL ;
2009-09-14 20:44:41 +04:00
}
2009-09-21 00:50:34 +04:00
2009-09-14 20:44:41 +04:00
return new_sd ;
}