1998-11-09 19:40:38 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
1998-11-09 19:40:38 +03:00
* RPC Pipe client / server routines
2000-06-01 21:01:34 +04:00
* Copyright ( C ) Andrew Tridgell 1992 - 1998 ,
* Copyright ( C ) Jeremy R . Allison 1995 - 1998
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998 ,
* Copyright ( C ) Paul Ashton 1997 - 1998.
1998-11-09 19:40:38 +03: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
* the Free Software Foundation ; either version 2 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 , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
1998-11-13 02:35:05 +03:00
/*******************************************************************
1999-12-13 16:27:58 +03:00
Sets up a SEC_ACCESS structure .
1998-11-13 02:35:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
void init_sec_access ( SEC_ACCESS * t , uint32 mask )
1998-11-13 02:35:05 +03:00
{
t - > mask = mask ;
}
1998-11-09 19:40:38 +03:00
/*******************************************************************
1999-12-13 16:27:58 +03:00
Reads or writes a SEC_ACCESS structure .
1998-11-09 19:40:38 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
1999-10-15 22:46:22 +04:00
BOOL sec_io_access ( char * desc , SEC_ACCESS * t , prs_struct * ps , int depth )
{
1999-12-13 16:27:58 +03:00
if ( t = = NULL )
return False ;
1998-11-09 19:40:38 +03:00
1998-11-13 02:35:05 +03:00
prs_debug ( ps , depth , desc , " sec_io_access " ) ;
1998-11-09 19:40:38 +03:00
depth + + ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
if ( ! prs_uint32 ( " mask " , ps , depth , & ( t - > mask ) ) )
return False ;
1999-10-15 22:46:22 +04:00
return True ;
1998-11-13 02:35:05 +03:00
}
2002-03-10 04:54:44 +03:00
/*******************************************************************
Check if ACE has OBJECT type .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL sec_ace_object ( uint8 type )
{
if ( type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT | |
type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT | |
type = = SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT | |
type = = SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT ) {
return True ;
}
return False ;
}
/*******************************************************************
copy a SEC_ACE structure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void sec_ace_copy ( SEC_ACE * ace_dest , SEC_ACE * ace_src )
{
ace_dest - > type = ace_src - > type ;
ace_dest - > flags = ace_src - > flags ;
ace_dest - > size = ace_src - > size ;
ace_dest - > info . mask = ace_src - > info . mask ;
ace_dest - > obj_flags = ace_src - > obj_flags ;
memcpy ( & ace_dest - > obj_guid , & ace_src - > obj_guid , GUID_SIZE ) ;
memcpy ( & ace_dest - > inh_guid , & ace_src - > inh_guid , GUID_SIZE ) ;
sid_copy ( & ace_dest - > trustee , & ace_src - > trustee ) ;
}
1998-11-13 02:35:05 +03:00
/*******************************************************************
1999-12-13 16:27:58 +03:00
Sets up a SEC_ACE structure .
1998-11-13 02:35:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
void init_sec_ace ( SEC_ACE * t , DOM_SID * sid , uint8 type , SEC_ACCESS mask , uint8 flag )
1998-11-13 02:35:05 +03:00
{
t - > type = type ;
t - > flags = flag ;
2000-06-01 21:01:34 +04:00
t - > size = sid_size ( sid ) + 8 ;
1998-11-13 02:35:05 +03:00
t - > info = mask ;
2000-05-27 05:26:34 +04:00
2001-11-30 04:04:15 +03:00
ZERO_STRUCTP ( & t - > trustee ) ;
sid_copy ( & t - > trustee , sid ) ;
1998-11-09 19:40:38 +03:00
}
/*******************************************************************
1999-12-13 16:27:58 +03:00
Reads or writes a SEC_ACE structure .
1998-11-09 19:40:38 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
BOOL sec_io_ace ( char * desc , SEC_ACE * psa , prs_struct * ps , int depth )
1998-11-09 19:40:38 +03:00
{
uint32 old_offset ;
uint32 offset_ace_size ;
2000-06-01 21:01:34 +04:00
if ( psa = = NULL )
1999-12-13 16:27:58 +03:00
return False ;
1998-11-09 19:40:38 +03:00
prs_debug ( ps , depth , desc , " sec_io_ace " ) ;
depth + + ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
2000-05-27 05:26:34 +04:00
old_offset = prs_offset ( ps ) ;
1998-11-09 19:40:38 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint8 ( " type " , ps , depth , & psa - > type ) )
return False ;
if ( ! prs_uint8 ( " flags " , ps , depth , & psa - > flags ) )
return False ;
if ( ! prs_uint16_pre ( " size " , ps , depth , & psa - > size , & offset_ace_size ) )
return False ;
if ( ! sec_io_access ( " info " , & psa - > info , ps , depth ) )
return False ;
if ( ! prs_align ( ps ) )
return False ;
1999-02-24 01:39:54 +03:00
2002-03-10 04:54:44 +03:00
/* check whether object access is present */
if ( ! sec_ace_object ( psa - > type ) ) {
if ( ! smb_io_dom_sid ( " trustee " , & psa - > trustee , ps , depth ) )
return False ;
} else {
if ( ! prs_uint32 ( " obj_flags " , ps , depth , & psa - > obj_flags ) )
return False ;
if ( psa - > obj_flags & SEC_ACE_OBJECT_PRESENT )
if ( ! prs_uint8s ( False , " obj_guid " , ps , depth , psa - > obj_guid . info , GUID_SIZE ) )
return False ;
if ( psa - > obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT )
if ( ! prs_uint8s ( False , " inh_guid " , ps , depth , psa - > inh_guid . info , GUID_SIZE ) )
return False ;
if ( ! smb_io_dom_sid ( " trustee " , & psa - > trustee , ps , depth ) )
return False ;
}
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint16_post ( " size " , ps , depth , & psa - > size , offset_ace_size , old_offset ) )
return False ;
1999-10-15 22:46:22 +04:00
return True ;
1998-11-09 19:40:38 +03:00
}
2002-03-10 04:54:44 +03:00
/*******************************************************************
adds new SID with its permissions to ACE list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_ace_add_sid ( TALLOC_CTX * ctx , SEC_ACE * * new , SEC_ACE * old , size_t * num , DOM_SID * sid , uint32 mask )
{
int i = 0 ;
if ( ! ctx | | ! new | | ! old | | ! sid | | ! num ) return NT_STATUS_INVALID_PARAMETER ;
* num + = 1 ;
if ( ( new [ 0 ] = ( SEC_ACE * ) talloc_zero ( ctx , * num * sizeof ( SEC_ACE ) ) ) = = 0 )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < * num - 1 ; i + + )
sec_ace_copy ( & ( * new ) [ i ] , & old [ i ] ) ;
( * new ) [ i ] . type = 0 ;
( * new ) [ i ] . flags = 0 ;
( * new ) [ i ] . size = SEC_ACE_HEADER_SIZE + sid_size ( sid ) ;
( * new ) [ i ] . info . mask = mask ;
sid_copy ( & ( * new ) [ i ] . trustee , sid ) ;
return NT_STATUS_OK ;
}
/*******************************************************************
modify SID ' s permissions at ACL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_ace_mod_sid ( SEC_ACE * ace , size_t num , DOM_SID * sid , uint32 mask )
{
int i = 0 ;
if ( ! ace | | ! sid ) return NT_STATUS_INVALID_PARAMETER ;
for ( i = 0 ; i < num ; i + + ) {
if ( sid_compare ( & ace [ i ] . trustee , sid ) = = 0 ) {
ace [ i ] . info . mask = mask ;
return NT_STATUS_OK ;
}
}
return NT_STATUS_NOT_FOUND ;
}
/*******************************************************************
delete SID from ACL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_ace_del_sid ( TALLOC_CTX * ctx , SEC_ACE * * new , SEC_ACE * old , size_t * num , DOM_SID * sid )
{
int i = 0 ;
int n_del = 0 ;
if ( ! ctx | | ! new | | ! old | | ! sid | | ! num ) return NT_STATUS_INVALID_PARAMETER ;
if ( ( new [ 0 ] = ( SEC_ACE * ) talloc_zero ( ctx , * num * sizeof ( SEC_ACE ) ) ) = = 0 )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < * num ; i + + ) {
if ( sid_compare ( & old [ i ] . trustee , sid ) ! = 0 )
sec_ace_copy ( & ( * new ) [ i ] , & old [ i ] ) ;
else
n_del + + ;
}
if ( n_del = = 0 )
return NT_STATUS_NOT_FOUND ;
else {
* num - = n_del ;
return NT_STATUS_OK ;
}
}
1998-11-09 19:40:38 +03:00
/*******************************************************************
2000-06-01 21:01:34 +04:00
Create a SEC_ACL structure .
1998-11-13 02:35:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
2001-02-28 03:51:02 +03:00
SEC_ACL * make_sec_acl ( TALLOC_CTX * ctx , uint16 revision , int num_aces , SEC_ACE * ace_list )
1998-11-13 02:35:05 +03:00
{
2000-06-01 21:01:34 +04:00
SEC_ACL * dst ;
1998-11-13 02:35:05 +03:00
int i ;
1999-12-13 16:27:58 +03:00
2001-02-28 03:51:02 +03:00
if ( ( dst = ( SEC_ACL * ) talloc_zero ( ctx , sizeof ( SEC_ACL ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return NULL ;
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
dst - > revision = revision ;
dst - > num_aces = num_aces ;
2002-03-10 04:54:44 +03:00
dst - > size = SEC_ACL_HEADER_SIZE ;
2000-06-01 21:01:34 +04:00
2001-06-26 10:11:40 +04:00
/* Now we need to return a non-NULL address for the ace list even
if the number of aces required is zero . This is because there
is a distinct difference between a NULL ace and an ace with zero
2001-08-07 04:01:41 +04:00
entries in it . This is achieved by checking that num_aces is a
positive number . */
2001-06-26 10:11:40 +04:00
2001-08-07 04:01:41 +04:00
if ( ( num_aces ) & &
( ( dst - > ace = ( SEC_ACE * ) talloc ( ctx , sizeof ( SEC_ACE ) * num_aces ) )
= = NULL ) ) {
2000-06-01 21:01:34 +04:00
return NULL ;
1998-11-13 02:35:05 +03:00
}
2001-08-07 04:01:41 +04:00
2000-06-01 21:01:34 +04:00
for ( i = 0 ; i < num_aces ; i + + ) {
dst - > ace [ i ] = ace_list [ i ] ; /* Structure copy. */
dst - > size + = ace_list [ i ] . size ;
}
return dst ;
1998-11-13 02:35:05 +03:00
}
/*******************************************************************
2000-06-01 21:01:34 +04:00
Duplicate a SEC_ACL structure .
1999-02-24 01:39:54 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
2001-02-28 03:51:02 +03:00
SEC_ACL * dup_sec_acl ( TALLOC_CTX * ctx , SEC_ACL * src )
1999-02-24 01:39:54 +03:00
{
1999-12-13 16:27:58 +03:00
if ( src = = NULL )
return NULL ;
2001-02-28 03:51:02 +03:00
return make_sec_acl ( ctx , src - > revision , src - > num_aces , src - > ace ) ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2000-06-01 21:01:34 +04:00
Reads or writes a SEC_ACL structure .
1999-12-13 16:27:58 +03:00
First of the xx_io_xx functions that allocates its data structures
1999-02-24 01:39:54 +03:00
for you as it reads them .
1998-11-09 19:40:38 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
BOOL sec_io_acl ( char * desc , SEC_ACL * * ppsa , prs_struct * ps , int depth )
1998-11-09 19:40:38 +03:00
{
2000-06-01 21:01:34 +04:00
int i ;
1998-11-09 19:40:38 +03:00
uint32 old_offset ;
uint32 offset_acl_size ;
2000-06-01 21:01:34 +04:00
SEC_ACL * psa ;
1999-02-24 01:39:54 +03:00
2000-06-01 21:01:34 +04:00
if ( ppsa = = NULL )
1999-12-13 16:27:58 +03:00
return False ;
2000-06-01 21:01:34 +04:00
psa = * ppsa ;
if ( UNMARSHALLING ( ps ) & & psa = = NULL ) {
/*
* This is a read and we must allocate the stuct to read into .
*/
2001-02-28 03:51:02 +03:00
if ( ( psa = ( SEC_ACL * ) prs_alloc_mem ( ps , sizeof ( SEC_ACL ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return False ;
* ppsa = psa ;
}
1998-11-09 19:40:38 +03:00
prs_debug ( ps , depth , desc , " sec_io_acl " ) ;
depth + + ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
1999-12-13 16:27:58 +03:00
old_offset = prs_offset ( ps ) ;
1998-11-09 19:40:38 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint16 ( " revision " , ps , depth , & psa - > revision ) )
return False ;
1998-11-09 19:40:38 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint16_pre ( " size " , ps , depth , & psa - > size , & offset_acl_size ) )
return False ;
1999-08-04 00:30:25 +04:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint32 ( " num_aces " , ps , depth , & psa - > num_aces ) )
1999-10-15 22:46:22 +04:00
return False ;
2000-06-01 21:01:34 +04:00
2001-06-26 10:31:55 +04:00
if ( UNMARSHALLING ( ps ) ) {
/*
* Even if the num_aces is zero , allocate memory as there ' s a difference
* between a non - present DACL ( allow all access ) and a DACL with no ACE ' s
* ( allow no access ) .
*/
if ( ( psa - > ace = ( SEC_ACE * ) prs_alloc_mem ( ps , sizeof ( psa - > ace [ 0 ] ) * ( psa - > num_aces + 1 ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return False ;
1998-11-13 02:35:05 +03:00
}
2000-06-01 21:01:34 +04:00
for ( i = 0 ; i < psa - > num_aces ; i + + ) {
1998-11-09 19:40:38 +03:00
fstring tmp ;
2000-06-01 21:01:34 +04:00
slprintf ( tmp , sizeof ( tmp ) - 1 , " ace_list[%02d]: " , i ) ;
if ( ! sec_io_ace ( tmp , & psa - > ace [ i ] , ps , depth ) )
1999-12-13 16:27:58 +03:00
return False ;
1998-11-09 19:40:38 +03:00
}
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
1998-11-09 19:40:38 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint16_post ( " size " , ps , depth , & psa - > size , offset_acl_size , old_offset ) )
return False ;
1999-10-15 22:46:22 +04:00
return True ;
1998-11-09 19:40:38 +03:00
}
2000-06-01 22:17:22 +04:00
/*******************************************************************
Works out the linearization size of a SEC_DESC .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
size_t sec_desc_size ( SEC_DESC * psd )
{
2000-06-05 03:34:11 +04:00
size_t offset ;
if ( ! psd ) return 0 ;
2002-03-10 04:54:44 +03:00
offset = SEC_DESC_HEADER_SIZE ;
2000-06-01 22:17:22 +04:00
if ( psd - > owner_sid ! = NULL )
offset + = ( ( sid_size ( psd - > owner_sid ) + 3 ) & ~ 3 ) ;
if ( psd - > grp_sid ! = NULL )
offset + = ( ( sid_size ( psd - > grp_sid ) + 3 ) & ~ 3 ) ;
if ( psd - > sacl ! = NULL )
offset + = ( ( psd - > sacl - > size + 3 ) & ~ 3 ) ;
if ( psd - > dacl ! = NULL )
offset + = ( ( psd - > dacl - > size + 3 ) & ~ 3 ) ;
return offset ;
}
2000-11-07 05:54:50 +03:00
/*******************************************************************
Compares two SEC_ACE structures
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL sec_ace_equal ( SEC_ACE * s1 , SEC_ACE * s2 )
{
/* Trivial case */
if ( ! s1 & & ! s2 ) return True ;
/* Check top level stuff */
if ( s1 - > type ! = s2 - > type | | s1 - > flags ! = s2 - > flags | |
s1 - > info . mask ! = s2 - > info . mask ) {
return False ;
}
/* Check SID */
2001-11-30 04:04:15 +03:00
if ( ! sid_equal ( & s1 - > trustee , & s2 - > trustee ) ) {
2000-11-07 05:54:50 +03:00
return False ;
}
return True ;
}
/*******************************************************************
Compares two SEC_ACL structures
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL sec_acl_equal ( SEC_ACL * s1 , SEC_ACL * s2 )
{
int i , j ;
2001-08-07 04:01:41 +04:00
/* Trivial cases */
2000-11-07 05:54:50 +03:00
if ( ! s1 & & ! s2 ) return True ;
2001-08-07 04:01:41 +04:00
if ( ! s1 | | ! s2 ) return False ;
2000-11-07 05:54:50 +03:00
/* Check top level stuff */
2000-12-18 09:02:31 +03:00
if ( s1 - > revision ! = s2 - > revision ) {
DEBUG ( 10 , ( " sec_acl_equal(): revision differs (%d != %d) \n " ,
s1 - > revision , s2 - > revision ) ) ;
return False ;
}
if ( s1 - > num_aces ! = s2 - > num_aces ) {
DEBUG ( 10 , ( " sec_acl_equal(): num_aces differs (%d != %d) \n " ,
s1 - > revision , s2 - > revision ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
/* The ACEs could be in any order so check each ACE in s1 against
each ACE in s2 . */
for ( i = 0 ; i < s1 - > num_aces ; i + + ) {
BOOL found = False ;
for ( j = 0 ; j < s2 - > num_aces ; j + + ) {
if ( sec_ace_equal ( & s1 - > ace [ i ] , & s2 - > ace [ j ] ) ) {
found = True ;
break ;
}
}
if ( ! found ) return False ;
}
return True ;
}
/*******************************************************************
Compares two SEC_DESC structures
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL sec_desc_equal ( SEC_DESC * s1 , SEC_DESC * s2 )
{
/* Trivial case */
2000-12-14 22:31:24 +03:00
if ( ! s1 & & ! s2 ) {
goto done ;
}
2000-11-07 05:54:50 +03:00
/* Check top level stuff */
2000-12-18 09:02:31 +03:00
if ( s1 - > revision ! = s2 - > revision ) {
DEBUG ( 10 , ( " sec_desc_equal(): revision differs (%d != %d) \n " ,
s1 - > revision , s2 - > revision ) ) ;
return False ;
}
if ( s1 - > type ! = s2 - > type ) {
DEBUG ( 10 , ( " sec_desc_equal(): type differs (%d != %d) \n " ,
s1 - > type , s2 - > type ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
/* Check owner and group */
2000-12-18 09:02:31 +03:00
if ( ! sid_equal ( s1 - > owner_sid , s2 - > owner_sid ) ) {
fstring str1 , str2 ;
sid_to_string ( str1 , s1 - > owner_sid ) ;
sid_to_string ( str2 , s2 - > owner_sid ) ;
DEBUG ( 10 , ( " sec_desc_equal(): owner differs (%s != %s) \n " ,
str1 , str2 ) ) ;
return False ;
}
if ( ! sid_equal ( s1 - > grp_sid , s2 - > grp_sid ) ) {
fstring str1 , str2 ;
sid_to_string ( str1 , s1 - > grp_sid ) ;
sid_to_string ( str2 , s2 - > grp_sid ) ;
DEBUG ( 10 , ( " sec_desc_equal(): group differs (%s != %s) \n " ,
str1 , str2 ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
/* Check ACLs present in one but not the other */
if ( ( s1 - > dacl & & ! s2 - > dacl ) | | ( ! s1 - > dacl & & s2 - > dacl ) | |
( s1 - > sacl & & ! s2 - > sacl ) | | ( ! s1 - > sacl & & s2 - > sacl ) ) {
2000-12-18 09:02:31 +03:00
DEBUG ( 10 , ( " sec_desc_equal(): dacl or sacl not present \n " ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
/* Sigh - we have to do it the hard way by iterating over all
the ACEs in the ACLs */
if ( ! sec_acl_equal ( s1 - > dacl , s2 - > dacl ) | |
! sec_acl_equal ( s1 - > sacl , s2 - > sacl ) ) {
2000-12-18 09:02:31 +03:00
DEBUG ( 10 , ( " sec_desc_equal(): dacl/sacl list not equal \n " ) ) ;
2000-11-07 05:54:50 +03:00
return False ;
}
2000-12-14 22:31:24 +03:00
done :
2001-01-11 23:41:19 +03:00
DEBUG ( 10 , ( " sec_desc_equal(): secdescs are identical \n " ) ) ;
2000-11-07 05:54:50 +03:00
return True ;
}
/*******************************************************************
Merge part of security descriptor old_sec in to the empty sections of
security descriptor new_sec .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 03:51:02 +03:00
SEC_DESC_BUF * sec_desc_merge ( TALLOC_CTX * ctx , SEC_DESC_BUF * new_sdb , SEC_DESC_BUF * old_sdb )
2000-11-07 05:54:50 +03:00
{
DOM_SID * owner_sid , * group_sid ;
SEC_DESC_BUF * return_sdb ;
SEC_ACL * dacl , * sacl ;
SEC_DESC * psd = NULL ;
uint16 secdesc_type ;
size_t secdesc_size ;
/* Copy over owner and group sids. There seems to be no flag for
this so just check the pointer values . */
owner_sid = new_sdb - > sec - > owner_sid ? new_sdb - > sec - > owner_sid :
old_sdb - > sec - > owner_sid ;
group_sid = new_sdb - > sec - > grp_sid ? new_sdb - > sec - > grp_sid :
old_sdb - > sec - > grp_sid ;
secdesc_type = new_sdb - > sec - > type ;
/* Ignore changes to the system ACL. This has the effect of making
changes through the security tab audit button not sticking .
Perhaps in future Samba could implement these settings somehow . */
sacl = NULL ;
secdesc_type & = ~ SEC_DESC_SACL_PRESENT ;
/* Copy across discretionary ACL */
if ( secdesc_type & SEC_DESC_DACL_PRESENT ) {
dacl = new_sdb - > sec - > dacl ;
} else {
dacl = old_sdb - > sec - > dacl ;
}
/* Create new security descriptor from bits */
2001-02-28 03:51:02 +03:00
psd = make_sec_desc ( ctx , new_sdb - > sec - > revision ,
2000-11-07 05:54:50 +03:00
owner_sid , group_sid , sacl , dacl , & secdesc_size ) ;
2001-02-28 03:51:02 +03:00
return_sdb = make_sec_desc_buf ( ctx , secdesc_size , psd ) ;
2000-11-07 05:54:50 +03:00
return ( return_sdb ) ;
}
2001-02-28 03:51:02 +03:00
/*******************************************************************
Tallocs a duplicate SID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static DOM_SID * sid_dup_talloc ( TALLOC_CTX * ctx , DOM_SID * src )
{
DOM_SID * dst ;
if ( ! src )
return NULL ;
if ( ( dst = talloc_zero ( ctx , sizeof ( DOM_SID ) ) ) ! = NULL ) {
sid_copy ( dst , src ) ;
}
return dst ;
}
1998-11-13 02:35:05 +03:00
/*******************************************************************
1999-12-13 16:27:58 +03:00
Creates a SEC_DESC structure
1998-11-13 02:35:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
2001-02-28 03:51:02 +03:00
SEC_DESC * make_sec_desc ( TALLOC_CTX * ctx , uint16 revision ,
2000-06-01 21:01:34 +04:00
DOM_SID * owner_sid , DOM_SID * grp_sid ,
2000-06-01 22:17:22 +04:00
SEC_ACL * sacl , SEC_ACL * dacl , size_t * sd_size )
1998-11-13 02:35:05 +03:00
{
2000-06-01 21:01:34 +04:00
SEC_DESC * dst ;
2002-03-10 04:54:44 +03:00
uint32 offset = 0 ;
uint32 offset_sid = SEC_DESC_HEADER_SIZE ;
uint32 offset_acl = 0 ;
1998-11-13 02:35:05 +03:00
2000-06-01 22:17:22 +04:00
* sd_size = 0 ;
1999-12-13 16:27:58 +03:00
2001-02-28 03:51:02 +03:00
if ( ( dst = ( SEC_DESC * ) talloc_zero ( ctx , sizeof ( SEC_DESC ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return NULL ;
1999-02-24 01:39:54 +03:00
2000-06-01 21:01:34 +04:00
dst - > revision = revision ;
2000-12-04 04:58:22 +03:00
dst - > type = SEC_DESC_SELF_RELATIVE ;
if ( sacl ) dst - > type | = SEC_DESC_SACL_PRESENT ;
if ( dacl ) dst - > type | = SEC_DESC_DACL_PRESENT ;
1998-11-13 02:35:05 +03:00
2000-06-01 21:01:34 +04:00
dst - > off_owner_sid = 0 ;
dst - > off_grp_sid = 0 ;
dst - > off_sacl = 0 ;
dst - > off_dacl = 0 ;
2001-02-28 03:51:02 +03:00
if ( owner_sid & & ( ( dst - > owner_sid = sid_dup_talloc ( ctx , owner_sid ) ) = = NULL ) )
2000-06-01 21:01:34 +04:00
goto error_exit ;
2001-02-28 03:51:02 +03:00
if ( grp_sid & & ( ( dst - > grp_sid = sid_dup_talloc ( ctx , grp_sid ) ) = = NULL ) )
2000-06-01 21:01:34 +04:00
goto error_exit ;
2001-02-28 03:51:02 +03:00
if ( sacl & & ( ( dst - > sacl = dup_sec_acl ( ctx , sacl ) ) = = NULL ) )
2000-06-01 21:01:34 +04:00
goto error_exit ;
2001-02-28 03:51:02 +03:00
if ( dacl & & ( ( dst - > dacl = dup_sec_acl ( ctx , dacl ) ) = = NULL ) )
2000-06-01 21:01:34 +04:00
goto error_exit ;
2002-03-10 04:54:44 +03:00
2000-06-01 22:17:22 +04:00
offset = 0 ;
1998-11-13 02:35:05 +03:00
2000-06-01 21:01:34 +04:00
/*
* Work out the linearization sizes .
*/
if ( dst - > owner_sid ! = NULL ) {
1998-11-13 04:38:41 +03:00
if ( offset = = 0 )
2002-03-10 04:54:44 +03:00
offset = SEC_DESC_HEADER_SIZE ;
2000-06-01 21:01:34 +04:00
offset + = ( ( sid_size ( dst - > owner_sid ) + 3 ) & ~ 3 ) ;
1998-11-13 02:35:05 +03:00
}
2000-06-01 21:01:34 +04:00
if ( dst - > grp_sid ! = NULL ) {
1998-11-13 04:38:41 +03:00
if ( offset = = 0 )
2002-03-10 04:54:44 +03:00
offset = SEC_DESC_HEADER_SIZE ;
2000-06-01 21:01:34 +04:00
offset + = ( ( sid_size ( dst - > grp_sid ) + 3 ) & ~ 3 ) ;
1998-11-13 02:35:05 +03:00
}
2000-06-01 21:01:34 +04:00
if ( dst - > sacl ! = NULL ) {
2002-03-10 04:54:44 +03:00
offset_acl = SEC_DESC_HEADER_SIZE ;
2000-06-01 21:01:34 +04:00
2002-03-10 04:54:44 +03:00
dst - > off_sacl = offset_acl ;
offset_acl + = ( ( dst - > sacl - > size + 3 ) & ~ 3 ) ;
offset + = dst - > sacl - > size ;
offset_sid + = dst - > sacl - > size ;
1998-11-13 02:35:05 +03:00
}
2000-06-01 21:01:34 +04:00
if ( dst - > dacl ! = NULL ) {
2002-03-10 04:54:44 +03:00
if ( offset_acl = = 0 )
offset_acl = SEC_DESC_HEADER_SIZE ;
2000-06-01 21:01:34 +04:00
2002-03-10 04:54:44 +03:00
dst - > off_dacl = offset_acl ;
offset_acl + = ( ( dst - > dacl - > size + 3 ) & ~ 3 ) ;
offset + = dst - > dacl - > size ;
offset_sid + = dst - > dacl - > size ;
1998-11-13 02:35:05 +03:00
}
2002-03-10 04:54:44 +03:00
* sd_size = ( size_t ) ( ( offset = = 0 ) ? SEC_DESC_HEADER_SIZE : offset ) ;
dst - > off_owner_sid = offset_sid ;
if ( dst - > owner_sid ! = NULL )
dst - > off_grp_sid = offset_sid + sid_size ( dst - > owner_sid ) ;
else
dst - > off_grp_sid = offset_sid ;
2000-06-01 21:01:34 +04:00
return dst ;
error_exit :
2000-06-01 22:17:22 +04:00
* sd_size = 0 ;
2000-06-01 21:01:34 +04:00
return NULL ;
1998-11-13 02:35:05 +03:00
}
2000-06-01 21:01:34 +04:00
/*******************************************************************
Duplicate a SEC_DESC structure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 03:51:02 +03:00
SEC_DESC * dup_sec_desc ( TALLOC_CTX * ctx , SEC_DESC * src )
2000-06-01 21:01:34 +04:00
{
size_t dummy ;
if ( src = = NULL )
return NULL ;
2001-02-28 03:51:02 +03:00
return make_sec_desc ( ctx , src - > revision ,
2000-06-01 21:01:34 +04:00
src - > owner_sid , src - > grp_sid , src - > sacl ,
src - > dacl , & dummy ) ;
}
1998-11-13 02:35:05 +03:00
2000-06-01 21:01:34 +04:00
/*******************************************************************
Creates a SEC_DESC structure with typical defaults .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-28 03:51:02 +03:00
SEC_DESC * make_standard_sec_desc ( TALLOC_CTX * ctx , DOM_SID * owner_sid , DOM_SID * grp_sid ,
2000-06-01 22:17:22 +04:00
SEC_ACL * dacl , size_t * sd_size )
2000-06-01 21:01:34 +04:00
{
2001-02-28 03:51:02 +03:00
return make_sec_desc ( ctx , SEC_DESC_REVISION ,
2000-06-01 22:17:22 +04:00
owner_sid , grp_sid , NULL , dacl , sd_size ) ;
1998-11-13 02:35:05 +03:00
}
1998-11-09 19:40:38 +03:00
/*******************************************************************
2000-06-01 21:01:34 +04:00
Reads or writes a SEC_DESC structure .
If reading and the * ppsd = NULL , allocates the structure .
1998-11-09 19:40:38 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
BOOL sec_io_desc ( char * desc , SEC_DESC * * ppsd , prs_struct * ps , int depth )
1998-11-09 19:40:38 +03:00
{
1998-11-11 22:22:08 +03:00
uint32 old_offset ;
2000-06-01 21:01:34 +04:00
uint32 max_offset = 0 ; /* after we're done, move offset to end */
2002-03-10 04:54:44 +03:00
uint32 tmp_offset = 0 ;
2000-06-01 21:01:34 +04:00
SEC_DESC * psd ;
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
if ( ppsd = = NULL )
1999-12-13 16:27:58 +03:00
return False ;
1999-02-24 01:39:54 +03:00
2000-06-01 21:01:34 +04:00
psd = * ppsd ;
2000-06-07 05:49:23 +04:00
if ( psd = = NULL ) {
if ( UNMARSHALLING ( ps ) ) {
2001-02-28 03:51:02 +03:00
if ( ( psd = ( SEC_DESC * ) prs_alloc_mem ( ps , sizeof ( SEC_DESC ) ) ) = = NULL )
2000-06-07 05:49:23 +04:00
return False ;
* ppsd = psd ;
} else {
/* Marshalling - just ignore. */
return True ;
}
2000-06-01 21:01:34 +04:00
}
1998-11-09 19:40:38 +03:00
prs_debug ( ps , depth , desc , " sec_io_desc " ) ;
depth + + ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
1998-11-11 22:22:08 +03:00
/* start of security descriptor stored for back-calc offset purposes */
1999-12-13 16:27:58 +03:00
old_offset = prs_offset ( ps ) ;
2000-06-01 21:01:34 +04:00
if ( ! prs_uint16 ( " revision " , ps , depth , & psd - > revision ) )
return False ;
if ( ! prs_uint16 ( " type " , ps , depth , & psd - > type ) )
return False ;
if ( ! prs_uint32 ( " off_owner_sid " , ps , depth , & psd - > off_owner_sid ) )
return False ;
if ( ! prs_uint32 ( " off_grp_sid " , ps , depth , & psd - > off_grp_sid ) )
return False ;
if ( ! prs_uint32 ( " off_sacl " , ps , depth , & psd - > off_sacl ) )
return False ;
if ( ! prs_uint32 ( " off_dacl " , ps , depth , & psd - > off_dacl ) )
return False ;
1999-12-13 16:27:58 +03:00
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
2000-06-01 21:01:34 +04:00
if ( psd - > off_owner_sid ! = 0 ) {
if ( UNMARSHALLING ( ps ) ) {
if ( ! prs_set_offset ( ps , old_offset + psd - > off_owner_sid ) )
return False ;
1999-08-04 00:30:25 +04:00
/* reading */
2001-02-28 03:51:02 +03:00
if ( ( psd - > owner_sid = ( DOM_SID * ) prs_alloc_mem ( ps , sizeof ( * psd - > owner_sid ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return False ;
1998-11-13 02:35:05 +03:00
}
2002-03-10 04:54:44 +03:00
tmp_offset = ps - > data_offset ;
ps - > data_offset = psd - > off_owner_sid ;
2000-06-01 21:01:34 +04:00
if ( ! smb_io_dom_sid ( " owner_sid " , psd - > owner_sid , ps , depth ) )
1999-12-13 16:27:58 +03:00
return False ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
1999-10-15 22:46:22 +04:00
return False ;
2002-03-10 04:54:44 +03:00
ps - > data_offset = tmp_offset ;
2000-05-27 05:26:34 +04:00
}
1998-11-13 02:35:05 +03:00
1999-12-13 16:27:58 +03:00
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
1998-11-13 02:35:05 +03:00
2000-06-01 21:01:34 +04:00
if ( psd - > off_grp_sid ! = 0 ) {
if ( UNMARSHALLING ( ps ) ) {
1999-08-04 00:30:25 +04:00
/* reading */
2000-06-01 21:01:34 +04:00
if ( ! prs_set_offset ( ps , old_offset + psd - > off_grp_sid ) )
return False ;
2001-02-28 03:51:02 +03:00
if ( ( psd - > grp_sid = ( DOM_SID * ) prs_alloc_mem ( ps , sizeof ( * psd - > grp_sid ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return False ;
1999-08-04 00:30:25 +04:00
}
1999-02-24 01:39:54 +03:00
2002-03-10 04:54:44 +03:00
tmp_offset = ps - > data_offset ;
ps - > data_offset = psd - > off_grp_sid ;
2000-06-01 21:01:34 +04:00
if ( ! smb_io_dom_sid ( " grp_sid " , psd - > grp_sid , ps , depth ) )
1999-10-15 22:46:22 +04:00
return False ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
1999-12-13 16:27:58 +03:00
return False ;
2002-03-10 04:54:44 +03:00
ps - > data_offset = tmp_offset ;
2000-05-27 05:26:34 +04:00
}
1999-12-13 16:27:58 +03:00
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
1999-02-24 01:39:54 +03:00
2000-08-01 22:32:34 +04:00
if ( ( psd - > type & SEC_DESC_SACL_PRESENT ) & & psd - > off_sacl ) {
2000-06-01 21:01:34 +04:00
if ( ! prs_set_offset ( ps , old_offset + psd - > off_sacl ) )
return False ;
if ( ! sec_io_acl ( " sacl " , & psd - > sacl , ps , depth ) )
return False ;
if ( ! prs_align ( ps ) )
1999-12-13 16:27:58 +03:00
return False ;
1999-02-24 01:39:54 +03:00
}
1999-12-13 16:27:58 +03:00
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
2000-08-01 22:32:34 +04:00
if ( ( psd - > type & SEC_DESC_DACL_PRESENT ) & & psd - > off_dacl ! = 0 ) {
2000-06-01 21:01:34 +04:00
if ( ! prs_set_offset ( ps , old_offset + psd - > off_dacl ) )
return False ;
if ( ! sec_io_acl ( " dacl " , & psd - > dacl , ps , depth ) )
return False ;
if ( ! prs_align ( ps ) )
1999-12-13 16:27:58 +03:00
return False ;
}
1999-08-04 00:30:25 +04:00
1999-12-13 16:27:58 +03:00
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
1999-10-15 22:46:22 +04:00
1999-12-13 16:27:58 +03:00
if ( ! prs_set_offset ( ps , max_offset ) )
return False ;
1999-10-15 22:46:22 +04:00
return True ;
1998-11-12 00:44:02 +03:00
}
1998-11-13 02:35:05 +03:00
/*******************************************************************
2000-06-01 21:01:34 +04:00
Creates a SEC_DESC_BUF structure .
1998-11-13 02:35:05 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
2001-02-28 03:51:02 +03:00
SEC_DESC_BUF * make_sec_desc_buf ( TALLOC_CTX * ctx , size_t len , SEC_DESC * sec_desc )
1999-10-15 22:46:22 +04:00
{
2000-06-01 21:01:34 +04:00
SEC_DESC_BUF * dst ;
2001-02-28 03:51:02 +03:00
if ( ( dst = ( SEC_DESC_BUF * ) talloc_zero ( ctx , sizeof ( SEC_DESC_BUF ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return NULL ;
1999-08-04 00:30:25 +04:00
/* max buffer size (allocated size) */
2000-06-01 21:01:34 +04:00
dst - > max_len = ( uint32 ) len ;
dst - > len = ( uint32 ) len ;
2001-02-28 03:51:02 +03:00
if ( sec_desc & & ( ( dst - > sec = dup_sec_desc ( ctx , sec_desc ) ) = = NULL ) ) {
2000-06-01 21:01:34 +04:00
return NULL ;
}
2001-02-28 03:51:02 +03:00
dst - > ptr = 0x1 ;
2000-06-01 21:01:34 +04:00
return dst ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2000-06-01 21:01:34 +04:00
Duplicates a SEC_DESC_BUF structure .
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
2001-02-28 03:51:02 +03:00
SEC_DESC_BUF * dup_sec_desc_buf ( TALLOC_CTX * ctx , SEC_DESC_BUF * src )
1999-12-13 16:27:58 +03:00
{
2000-06-01 21:01:34 +04:00
if ( src = = NULL )
return NULL ;
2001-02-28 03:51:02 +03:00
return make_sec_desc_buf ( ctx , src - > len , src - > sec ) ;
1998-11-13 02:35:05 +03:00
}
1998-11-09 19:40:38 +03:00
/*******************************************************************
2000-06-01 21:01:34 +04:00
Reads or writes a SEC_DESC_BUF structure .
1998-11-09 19:40:38 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-06-01 21:01:34 +04:00
BOOL sec_io_desc_buf ( char * desc , SEC_DESC_BUF * * ppsdb , prs_struct * ps , int depth )
1998-11-09 19:40:38 +03:00
{
1998-11-11 22:22:08 +03:00
uint32 off_len ;
1998-11-12 22:21:20 +03:00
uint32 off_max_len ;
1998-11-11 22:22:08 +03:00
uint32 old_offset ;
1998-11-12 22:21:20 +03:00
uint32 size ;
2000-06-01 21:01:34 +04:00
SEC_DESC_BUF * psdb ;
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
if ( ppsdb = = NULL )
1999-12-13 16:27:58 +03:00
return False ;
1998-11-11 22:22:08 +03:00
2000-06-01 21:01:34 +04:00
psdb = * ppsdb ;
if ( UNMARSHALLING ( ps ) & & psdb = = NULL ) {
2001-02-28 03:51:02 +03:00
if ( ( psdb = ( SEC_DESC_BUF * ) prs_alloc_mem ( ps , sizeof ( SEC_DESC_BUF ) ) ) = = NULL )
2000-06-01 21:01:34 +04:00
return False ;
* ppsdb = psdb ;
}
1998-11-09 19:40:38 +03:00
prs_debug ( ps , depth , desc , " sec_io_desc_buf " ) ;
depth + + ;
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
if ( ! prs_uint32_pre ( " max_len " , ps , depth , & psdb - > max_len , & off_max_len ) )
return False ;
1999-08-04 00:30:25 +04:00
2001-02-28 03:51:02 +03:00
if ( ! prs_uint32 ( " ptr " , ps , depth , & psdb - > ptr ) )
2000-06-01 21:01:34 +04:00
return False ;
1998-11-13 02:35:05 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint32_pre ( " len " , ps , depth , & psdb - > len , & off_len ) )
return False ;
2000-05-27 05:26:34 +04:00
2000-06-01 21:01:34 +04:00
old_offset = prs_offset ( ps ) ;
1999-02-24 01:39:54 +03:00
2000-05-27 05:26:34 +04:00
/* reading, length is non-zero; writing, descriptor is non-NULL */
2000-06-07 05:49:23 +04:00
if ( ( UNMARSHALLING ( ps ) & & psdb - > len ! = 0 ) | | ( MARSHALLING ( ps ) & & psdb - > sec ! = NULL ) ) {
2000-06-01 21:01:34 +04:00
if ( ! sec_io_desc ( " sec " , & psdb - > sec , ps , depth ) )
return False ;
2000-05-27 05:26:34 +04:00
}
2000-06-01 21:01:34 +04:00
if ( ! prs_align ( ps ) )
return False ;
size = prs_offset ( ps ) - old_offset ;
if ( ! prs_uint32_post ( " max_len " , ps , depth , & psdb - > max_len , off_max_len , size = = 0 ? psdb - > max_len : size ) )
return False ;
1999-12-13 16:27:58 +03:00
2000-06-01 21:01:34 +04:00
if ( ! prs_uint32_post ( " len " , ps , depth , & psdb - > len , off_len , size ) )
1999-12-13 16:27:58 +03:00
return False ;
1999-10-15 22:46:22 +04:00
return True ;
1998-11-09 19:40:38 +03:00
}
2002-03-10 04:54:44 +03:00
/*******************************************************************
adds new SID with its permissions to SEC_DESC
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_desc_add_sid ( TALLOC_CTX * ctx , SEC_DESC * * psd , DOM_SID * sid , uint32 mask , size_t * sd_size )
{
SEC_DESC * sd = 0 ;
SEC_ACL * dacl = 0 ;
SEC_ACE * ace = 0 ;
NTSTATUS status ;
* sd_size = 0 ;
if ( ! ctx | | ! psd | | ! sid | | ! sd_size ) return NT_STATUS_INVALID_PARAMETER ;
status = sec_ace_add_sid ( ctx , & ace , psd [ 0 ] - > dacl - > ace , & psd [ 0 ] - > dacl - > num_aces , sid , mask ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
return status ;
if ( ! ( dacl = make_sec_acl ( ctx , psd [ 0 ] - > dacl - > revision , psd [ 0 ] - > dacl - > num_aces , ace ) ) )
return NT_STATUS_UNSUCCESSFUL ;
if ( ! ( sd = make_sec_desc ( ctx , psd [ 0 ] - > revision , psd [ 0 ] - > owner_sid ,
psd [ 0 ] - > grp_sid , psd [ 0 ] - > sacl , dacl , sd_size ) ) )
return NT_STATUS_UNSUCCESSFUL ;
* psd = sd ;
sd = 0 ;
return NT_STATUS_OK ;
}
/*******************************************************************
modify SID ' s permissions at SEC_DESC
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_desc_mod_sid ( SEC_DESC * sd , DOM_SID * sid , uint32 mask )
{
NTSTATUS status ;
if ( ! sd | | ! sid ) return NT_STATUS_INVALID_PARAMETER ;
status = sec_ace_mod_sid ( sd - > dacl - > ace , sd - > dacl - > num_aces , sid , mask ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
return status ;
return NT_STATUS_OK ;
}
/*******************************************************************
delete SID from SEC_DESC
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS sec_desc_del_sid ( TALLOC_CTX * ctx , SEC_DESC * * psd , DOM_SID * sid , size_t * sd_size )
{
SEC_DESC * sd = 0 ;
SEC_ACL * dacl = 0 ;
SEC_ACE * ace = 0 ;
NTSTATUS status ;
* sd_size = 0 ;
if ( ! ctx | | ! psd [ 0 ] | | ! sid | | ! sd_size ) return NT_STATUS_INVALID_PARAMETER ;
status = sec_ace_del_sid ( ctx , & ace , psd [ 0 ] - > dacl - > ace , & psd [ 0 ] - > dacl - > num_aces , sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
return status ;
if ( ! ( dacl = make_sec_acl ( ctx , psd [ 0 ] - > dacl - > revision , psd [ 0 ] - > dacl - > num_aces , ace ) ) )
return NT_STATUS_UNSUCCESSFUL ;
if ( ! ( sd = make_sec_desc ( ctx , psd [ 0 ] - > revision , psd [ 0 ] - > owner_sid ,
psd [ 0 ] - > grp_sid , psd [ 0 ] - > sacl , dacl , sd_size ) ) )
return NT_STATUS_UNSUCCESSFUL ;
* psd = sd ;
sd = 0 ;
return NT_STATUS_OK ;
}