0001-01-01 02:30:17 +02:30
/*
0001-01-01 02:30:17 +02:30
* Unix SMB / Netbios implementation .
* Version 1.9 .
0001-01-01 02:30:17 +02:30
* RPC Pipe client / server routines
0001-01-01 02:30:17 +02:30
* Copyright ( C ) Andrew Tridgell 1992 - 1998 ,
0001-01-01 02:30:17 +02:30
* Copyright ( C ) Jeremy R . Allison 1995 - 2003.
0001-01-01 02:30:17 +02:30
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998 ,
* Copyright ( C ) Paul Ashton 1997 - 1998.
0001-01-01 02:30:17 +02:30
*
* 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"
0001-01-01 02:30:17 +02:30
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_PARSE
0001-01-01 02:30:17 +02:30
/*******************************************************************
0001-01-01 02:30:17 +02:30
Reads or writes a SEC_ACCESS structure .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
BOOL sec_io_access ( const char * desc , SEC_ACCESS * t , prs_struct * ps , int depth )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( t = = NULL )
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
prs_debug ( ps , depth , desc , " sec_io_access " ) ;
0001-01-01 02:30:17 +02:30
depth + + ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint32 ( " mask " , ps , depth , & t - > mask ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
return True ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/*******************************************************************
0001-01-01 02:30:17 +02:30
Reads or writes a SEC_ACE structure .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
BOOL sec_io_ace ( const char * desc , SEC_ACE * psa , prs_struct * ps , int depth )
0001-01-01 02:30:17 +02:30
{
uint32 old_offset ;
uint32 offset_ace_size ;
0001-01-01 02:30:17 +02:30
if ( psa = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
prs_debug ( ps , depth , desc , " sec_io_ace " ) ;
depth + + ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
old_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
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 ;
0001-01-01 02:30:17 +02:30
/* 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 )
2004-04-13 18:39:48 +04:00
if ( ! smb_io_uuid ( " obj_guid " , & psa - > obj_guid , ps , depth ) )
0001-01-01 02:30:17 +02:30
return False ;
if ( psa - > obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT )
2004-04-13 18:39:48 +04:00
if ( ! smb_io_uuid ( " inh_guid " , & psa - > inh_guid , ps , depth ) )
0001-01-01 02:30:17 +02:30
return False ;
if ( ! smb_io_dom_sid ( " trustee " , & psa - > trustee , ps , depth ) )
return False ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint16_post ( " size " , ps , depth , & psa - > size , offset_ace_size , old_offset ) )
return False ;
0001-01-01 02:30:17 +02:30
return True ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/*******************************************************************
0001-01-01 02:30:17 +02:30
Reads or writes a SEC_ACL structure .
0001-01-01 02:30:17 +02:30
First of the xx_io_xx functions that allocates its data structures
0001-01-01 02:30:17 +02:30
for you as it reads them .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
BOOL sec_io_acl ( const char * desc , SEC_ACL * * ppsa , prs_struct * ps , int depth )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
unsigned int i ;
0001-01-01 02:30:17 +02:30
uint32 old_offset ;
uint32 offset_acl_size ;
0001-01-01 02:30:17 +02:30
SEC_ACL * psa ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/*
* Note that the size is always a multiple of 4 bytes due to the
* nature of the data structure . Therefore the prs_align ( ) calls
* have been removed as they through us off when doing two - layer
* marshalling such as in the printing code ( NEW_BUFFER ) . - - jerry
*/
0001-01-01 02:30:17 +02:30
if ( ppsa = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
psa = * ppsa ;
if ( UNMARSHALLING ( ps ) & & psa = = NULL ) {
/*
* This is a read and we must allocate the stuct to read into .
*/
0001-01-01 02:30:17 +02:30
if ( ( psa = ( SEC_ACL * ) prs_alloc_mem ( ps , sizeof ( SEC_ACL ) ) ) = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
* ppsa = psa ;
}
0001-01-01 02:30:17 +02:30
prs_debug ( ps , depth , desc , " sec_io_acl " ) ;
depth + + ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
old_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint16 ( " revision " , ps , depth , & psa - > revision ) )
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint16_pre ( " size " , ps , depth , & psa - > size , & offset_acl_size ) )
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint32 ( " num_aces " , ps , depth , & psa - > num_aces ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
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 )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
for ( i = 0 ; i < psa - > num_aces ; i + + ) {
0001-01-01 02:30:17 +02:30
fstring tmp ;
0001-01-01 02:30:17 +02:30
slprintf ( tmp , sizeof ( tmp ) - 1 , " ace_list[%02d]: " , i ) ;
if ( ! sec_io_ace ( tmp , & psa - > ace [ i ] , ps , depth ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
if ( ! prs_uint16_post ( " size " , ps , depth , & psa - > size , offset_acl_size , old_offset ) )
return False ;
0001-01-01 02:30:17 +02:30
return True ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
0001-01-01 02:30:17 +02:30
Reads or writes a SEC_DESC structure .
If reading and the * ppsd = NULL , allocates the structure .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
BOOL sec_io_desc ( const char * desc , SEC_DESC * * ppsd , prs_struct * ps , int depth )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
uint32 old_offset ;
0001-01-01 02:30:17 +02:30
uint32 max_offset = 0 ; /* after we're done, move offset to end */
0001-01-01 02:30:17 +02:30
uint32 tmp_offset = 0 ;
0001-01-01 02:30:17 +02:30
SEC_DESC * psd ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ppsd = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
psd = * ppsd ;
0001-01-01 02:30:17 +02:30
if ( psd = = NULL ) {
if ( UNMARSHALLING ( ps ) ) {
0001-01-01 02:30:17 +02:30
if ( ( psd = ( SEC_DESC * ) prs_alloc_mem ( ps , sizeof ( SEC_DESC ) ) ) = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
* ppsd = psd ;
} else {
/* Marshalling - just ignore. */
return True ;
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
prs_debug ( ps , depth , desc , " sec_io_desc " ) ;
depth + + ;
0001-01-01 02:30:17 +02:30
#if 0
/*
* if alignment is needed , should be done by the the
* caller . Not here . This caused me problems when marshalling
* printer info into a buffer . - - jerry
*/
0001-01-01 02:30:17 +02:30
if ( ! prs_align ( ps ) )
return False ;
0001-01-01 02:30:17 +02:30
# endif
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* start of security descriptor stored for back-calc offset purposes */
0001-01-01 02:30:17 +02:30
old_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
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 ;
0001-01-01 02:30:17 +02:30
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
0001-01-01 02:30:17 +02:30
if ( psd - > off_owner_sid ! = 0 ) {
0001-01-01 02:30:17 +02:30
tmp_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , old_offset + psd - > off_owner_sid ) )
return False ;
0001-01-01 02:30:17 +02:30
if ( UNMARSHALLING ( ps ) ) {
0001-01-01 02:30:17 +02:30
/* reading */
0001-01-01 02:30:17 +02:30
if ( ( psd - > owner_sid = ( DOM_SID * ) prs_alloc_mem ( ps , sizeof ( * psd - > owner_sid ) ) ) = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
if ( ! smb_io_dom_sid ( " owner_sid " , psd - > owner_sid , ps , depth ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , tmp_offset ) )
return False ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( psd - > off_grp_sid ! = 0 ) {
0001-01-01 02:30:17 +02:30
tmp_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , old_offset + psd - > off_grp_sid ) )
return False ;
0001-01-01 02:30:17 +02:30
if ( UNMARSHALLING ( ps ) ) {
0001-01-01 02:30:17 +02:30
/* reading */
0001-01-01 02:30:17 +02:30
if ( ( psd - > grp_sid = ( DOM_SID * ) prs_alloc_mem ( ps , sizeof ( * psd - > grp_sid ) ) ) = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! smb_io_dom_sid ( " grp_sid " , psd - > grp_sid , ps , depth ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , tmp_offset ) )
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ( psd - > type & SEC_DESC_SACL_PRESENT ) & & psd - > off_sacl ) {
0001-01-01 02:30:17 +02:30
tmp_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , old_offset + psd - > off_sacl ) )
return False ;
if ( ! sec_io_acl ( " sacl " , & psd - > sacl , ps , depth ) )
return False ;
0001-01-01 02:30:17 +02:30
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
if ( ! prs_set_offset ( ps , tmp_offset ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ( psd - > type & SEC_DESC_DACL_PRESENT ) & & psd - > off_dacl ! = 0 ) {
0001-01-01 02:30:17 +02:30
tmp_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , old_offset + psd - > off_dacl ) )
return False ;
if ( ! sec_io_acl ( " dacl " , & psd - > dacl , ps , depth ) )
return False ;
0001-01-01 02:30:17 +02:30
max_offset = MAX ( max_offset , prs_offset ( ps ) ) ;
if ( ! prs_set_offset ( ps , tmp_offset ) )
0001-01-01 02:30:17 +02:30
return False ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_set_offset ( ps , max_offset ) )
return False ;
0001-01-01 02:30:17 +02:30
return True ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/*******************************************************************
0001-01-01 02:30:17 +02:30
Reads or writes a SEC_DESC_BUF structure .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
BOOL sec_io_desc_buf ( const char * desc , SEC_DESC_BUF * * ppsdb , prs_struct * ps , int depth )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
uint32 off_len ;
0001-01-01 02:30:17 +02:30
uint32 off_max_len ;
0001-01-01 02:30:17 +02:30
uint32 old_offset ;
0001-01-01 02:30:17 +02:30
uint32 size ;
0001-01-01 02:30:17 +02:30
SEC_DESC_BUF * psdb ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ppsdb = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
psdb = * ppsdb ;
if ( UNMARSHALLING ( ps ) & & psdb = = NULL ) {
0001-01-01 02:30:17 +02:30
if ( ( psdb = ( SEC_DESC_BUF * ) prs_alloc_mem ( ps , sizeof ( SEC_DESC_BUF ) ) ) = = NULL )
0001-01-01 02:30:17 +02:30
return False ;
* ppsdb = psdb ;
}
0001-01-01 02:30:17 +02:30
prs_debug ( ps , depth , desc , " sec_io_desc_buf " ) ;
depth + + ;
0001-01-01 02:30:17 +02:30
if ( ! prs_align ( ps ) )
return False ;
if ( ! prs_uint32_pre ( " max_len " , ps , depth , & psdb - > max_len , & off_max_len ) )
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint32 ( " ptr " , ps , depth , & psdb - > ptr ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint32_pre ( " len " , ps , depth , & psdb - > len , & off_len ) )
return False ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
old_offset = prs_offset ( ps ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* reading, length is non-zero; writing, descriptor is non-NULL */
0001-01-01 02:30:17 +02:30
if ( ( UNMARSHALLING ( ps ) & & psdb - > len ! = 0 ) | | ( MARSHALLING ( ps ) & & psdb - > sec ! = NULL ) ) {
0001-01-01 02:30:17 +02:30
if ( ! sec_io_desc ( " sec " , & psdb - > sec , ps , depth ) )
return False ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
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 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! prs_uint32_post ( " len " , ps , depth , & psdb - > len , off_len , size ) )
0001-01-01 02:30:17 +02:30
return False ;
0001-01-01 02:30:17 +02:30
return True ;
0001-01-01 02:30:17 +02:30
}