00517                    :
00518 
00519     Converts a security descriptor from 
self-relative 
format to absolute
00520     
format using the memory allocated 
for the SelfRelativeSecurityDescriptor
00521 
00522 Arguments:
00523 
00524     pSecurityDescriptor - Supplies a pointer to a security descriptor in
00525         Self-Relative 
format. If success, we 
return a absolute security
00526         descriptor where 
this pointer pointings.
00527 
00528     pBufferSize - Supplies a pointer to 
the size of 
the
00529         buffer.
00530 
00531 Return Value:
00532 
00533     STATUS_SUCCESS - Success
00534 
00535     STATUS_BAD_DESCRIPTOR_FORMAT - The passed descriptor 
is not a 
self-relative
00536        security descriptor.
00537 
00538     STATUS_BUFFER_TOO_SMALL - The passed buffer 
is too small.
00539 
00540     STATUS_INVALID_OWNER - There was not a valid owner in 
the passed
00541         security descriptor.
00542 
00543 Notes: Despite some attempts to make 
this code as portable as possible and 
the 
00544        utilization of 
C_ASSERT or 
ASSERT to detect 
the respect of these assumptions, 
00545        
this code 
is still making several assumptions about 
the format of 
the absolute 
00546        and 
self-relative descriptors and their relationships: in terms of packing, 
00547        fields definitions and locations in their respective structures. 
00548        In particular, 
this code assumes that 
the only differences are due to differences 
00549        in 
the types of 
the structure members and in 
the behaviour of 
the security descriptor
00550        query API.
00551        At 
this time, 
the only structure members that get read/updated are 
Owner, 
Group,
00552        
Dacl and Sacl. If more members are added or displaced in 
the definitions of these
00553        structures, 
this code may have to be modified.
00554 
00555 --*/
00556 
00557 {
00558     ULONG_PTR   ptr;
00559     PSID        owner;
00560     PSID        group;
00561     PACL        dacl;
00562     PACL        sacl;
00563     ULONG       daclSize;
00564     ULONG       saclSize;
00565     ULONG       newBodySize;
00566     ULONG       ownerSize;
00567     ULONG       groupSize;
00568     ULONG       newBufferSize;
00569     LONG        deltaSize;
00570 
00571 
00572 
00573 
00574 
00575     PISECURITY_DESCRIPTOR          psd  = (PISECURITY_DESCRIPTOR)         pSelfRelativeSecurityDescriptor;
00576     PISECURITY_DESCRIPTOR_RELATIVE psdr = (PISECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor;
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584     
C_ASSERT( 
sizeof( SECURITY_DESCRIPTOR ) >= 
sizeof( SECURITY_DESCRIPTOR_RELATIVE ) ); 
00585     
C_ASSERT( 
sizeof( psd->Control ) == 
sizeof( psdr->Control ) );
00586     
C_ASSERT( FIELD_OFFSET( SECURITY_DESCRIPTOR, Control ) == FIELD_OFFSET( SECURITY_DESCRIPTOR_RELATIVE, Control ) );
00587     
00588     
RTL_PAGED_CODE();
00589 
00590 
00591 
00592 
00593 
00594     
if ( psd == (PISECURITY_DESCRIPTOR)0 ) {
00595         
return( STATUS_INVALID_PARAMETER_1 );        
00596     }
00597     
if ( pBufferSize == (PULONG)0 )   {
00598         
return( STATUS_INVALID_PARAMETER_2 );       
00599     }
00600 
00601     
00602     
00603     
00604     
00605 
00606     
if ( !RtlpAreControlBitsSet( psd, SE_SELF_RELATIVE) ) {
00607         
return( STATUS_BAD_DESCRIPTOR_FORMAT );
00608     }
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616     
RtlpQuerySecurityDescriptor(
00617         psd,
00618         &owner,
00619         &ownerSize,
00620         &group,
00621         &groupSize,
00622         &dacl,
00623         &daclSize,
00624         &sacl,
00625         &saclSize
00626         );
00627 
00628 
00629 
00630 
00631 
00632     
00633     
00634     
00635 
00636     deltaSize = 
sizeof( SECURITY_DESCRIPTOR ) - 
sizeof( SECURITY_DESCRIPTOR_RELATIVE ); 
00637 
00638     
00639     
00640     
00641     
00642     
00643     
00644 
00645     
if ( deltaSize == 0 )   {
00646        
00647         RtlpClearControlBits( psd, SE_SELF_RELATIVE );
00648 
00649         
00650         
00651         
00652 
00653         
ASSERT( 
sizeof( psd->Owner ) == 
sizeof( psdr->Owner ) );
00654         
ASSERT( 
sizeof( psd->Group ) == 
sizeof( psdr->Group ) );
00655         
ASSERT( 
sizeof( psd->Sacl  ) == 
sizeof( psdr->Sacl  ) );
00656         
ASSERT( 
sizeof( psd->Dacl  ) == 
sizeof( psdr->Dacl  ) );
00657 
00658         psd->Owner = owner;
00659         psd->Group = group;
00660         psd->Sacl  = sacl;
00661         psd->Dacl  = dacl;
00662     
00663         
return( STATUS_SUCCESS );
00664 
00665     }
00666 
00667 
00668 
00669 
00670 
00671 
#define ULONG_PTR_SDEND( _Adr ) ( (ULONG_PTR)(_Adr) + (ULONG_PTR)(_Adr##Size) )
00672 
00673     ptr = owner > group ? 
ULONG_PTR_SDEND( owner ) : 
ULONG_PTR_SDEND( group );
00674     ptr = ptr > (ULONG_PTR)dacl ? ptr : 
ULONG_PTR_SDEND( dacl );
00675     ptr = ptr > (ULONG_PTR)sacl ? ptr : 
ULONG_PTR_SDEND( sacl );
00676    
00677     newBufferSize = 
sizeof( SECURITY_DESCRIPTOR );
00678     
if ( ptr )   {
00679 
00680 
#define ULONG_ROUND_UP( x, y )   ((ULONG)(x) + ((y)-1) & ~((y)-1))
00681 
00682         newBufferSize += 
ULONG_ROUND_UP( (ULONG_PTR)ptr - (ULONG_PTR)(psdr + 1), 
sizeof(PVOID) );
00683     }
00684 
00685     
00686     
00687     
00688     
00689 
00690     
if ( newBufferSize > *pBufferSize )  {
00691         *pBufferSize = newBufferSize;
00692         
return( STATUS_BUFFER_TOO_SMALL );
00693     }
00694 
00695 
00696 
00697 
00698 
00699     
00700     
00701     
00702     
00703 
00704     
if ( ptr )   {
00705        RtlMoveMemory( (PVOID)(psd + 1), (PVOID)(psdr + 1), newBufferSize - 
sizeof( SECURITY_DESCRIPTOR) );      
00706     }
00707 
00708     
00709     
00710     
00711 
00712     RtlpClearControlBits( psd, SE_SELF_RELATIVE );
00713 
00714     
00715     
00716     
00717 
00718     psd->Owner = (PSID)( owner ? (ULONG_PTR)owner + deltaSize : 0 );
00719     psd->Group = (PSID)( group ? (ULONG_PTR)group + deltaSize : 0 );
00720     psd->Sacl  = (PACL)( sacl  ? (ULONG_PTR)sacl  + deltaSize : 0 );
00721     psd->Dacl  = (PACL)( dacl  ? (ULONG_PTR)dacl  + deltaSize : 0 );
00722     
00723     
return( STATUS_SUCCESS );
00724 
00725 }