Exemplo n.º 1
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor,
                          OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
{
    PSID Owner, Group;
    PACL Dacl, Sacl;
    DWORD OwnerLength, GroupLength, DaclLength, SaclLength, TotalLength;
    PISECURITY_DESCRIPTOR Sd = pSourceSecurityDescriptor;

    /* Get all the components */
    RtlpQuerySecurityDescriptor(Sd,
                                &Owner,
                                &OwnerLength,
                                &Group,
                                &GroupLength,
                                &Dacl,
                                &DaclLength,
                                &Sacl,
                                &SaclLength);

    /* Add up their lengths */
    TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
                  OwnerLength +
                  GroupLength +
                  DaclLength +
                  SaclLength;

    /* Allocate a copy */
    *pDestinationSecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
                                                      0,
                                                          TotalLength);
    if (*pDestinationSecurityDescriptor == NULL) return STATUS_NO_MEMORY;

    /* Copy the old in the new */
    RtlCopyMemory(*pDestinationSecurityDescriptor, Sd, TotalLength);

    /* All good */
    return STATUS_SUCCESS;
}
Exemplo n.º 2
0
NTSTATUS
RtlSelfRelativeToAbsoluteSD2(
    IN OUT PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
    IN OUT PULONG               pBufferSize
    )

/*++

Routine Description:

    Converts a security descriptor from self-relative format to absolute
    format using the memory allocated for the SelfRelativeSecurityDescriptor

Arguments:

    pSecurityDescriptor - Supplies a pointer to a security descriptor in
        Self-Relative format. If success, we return a absolute security
        descriptor where this pointer pointings.

    pBufferSize - Supplies a pointer to the size of the
        buffer.

Return Value:

    STATUS_SUCCESS - Success

    STATUS_BAD_DESCRIPTOR_FORMAT - The passed descriptor is not a self-relative
       security descriptor.

    STATUS_BUFFER_TOO_SMALL - The passed buffer is too small.

    STATUS_INVALID_OWNER - There was not a valid owner in the passed
        security descriptor.

Notes: Despite some attempts to make this code as portable as possible and the 
       utilization of C_ASSERT or ASSERT to detect the respect of these assumptions, 
       this code is still making several assumptions about the format of the absolute 
       and self-relative descriptors and their relationships: in terms of packing, 
       fields definitions and locations in their respective structures. 
       In particular, this code assumes that the only differences are due to differences 
       in the types of the structure members and in the behaviour of the security descriptor
       query API.
       At this time, the only structure members that get read/updated are Owner, Group,
       Dacl and Sacl. If more members are added or displaced in the definitions of these
       structures, this code may have to be modified.

--*/

{
    ULONG_PTR   ptr;
    PSID        owner;
    PSID        group;
    PACL        dacl;
    PACL        sacl;
    ULONG       daclSize;
    ULONG       saclSize;
    ULONG       newBodySize;
    ULONG       ownerSize;
    ULONG       groupSize;
    ULONG       newBufferSize;
    LONG        deltaSize;

//
// Typecast security descriptors so we don't have to cast all over the place.
//

    PISECURITY_DESCRIPTOR          psd  = (PISECURITY_DESCRIPTOR)         pSelfRelativeSecurityDescriptor;
    PISECURITY_DESCRIPTOR_RELATIVE psdr = (PISECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor;

//
// This code uses several assumptions about the absolute and self-relative formats of 
// security descriptors and the way they are packing in memory. 
// See Routine Description Notes.
//

    C_ASSERT( sizeof( SECURITY_DESCRIPTOR ) >= sizeof( SECURITY_DESCRIPTOR_RELATIVE ) ); 
    C_ASSERT( sizeof( psd->Control ) == sizeof( psdr->Control ) );
    C_ASSERT( FIELD_OFFSET( SECURITY_DESCRIPTOR, Control ) == FIELD_OFFSET( SECURITY_DESCRIPTOR_RELATIVE, Control ) );
    
    RTL_PAGED_CODE();

//
// Parameters check point
//

    if ( psd == (PISECURITY_DESCRIPTOR)0 ) {
        return( STATUS_INVALID_PARAMETER_1 );        
    }
    if ( pBufferSize == (PULONG)0 )   {
        return( STATUS_INVALID_PARAMETER_2 );       
    }

    //
    // If the passed security descriptor is not self-relative, we return
    // an format error.
    //

    if ( !RtlpAreControlBitsSet( psd, SE_SELF_RELATIVE) ) {
        return( STATUS_BAD_DESCRIPTOR_FORMAT );
    }

//
// Update local variables by querying the self-relative descriptor.
//
// Note that the returned size values are long-aligned.
//

    RtlpQuerySecurityDescriptor(
        psd,
        &owner,
        &ownerSize,
        &group,
        &groupSize,
        &dacl,
        &daclSize,
        &sacl,
        &saclSize
        );

//
// Identical formats check:
//

    //
    // Determine the delta in size between the two formats of security descriptors
    //

    deltaSize = sizeof( SECURITY_DESCRIPTOR ) - sizeof( SECURITY_DESCRIPTOR_RELATIVE ); 

    //
    // If identical format: 
    //      - clear the SELF_RELATIVE flag
    //      - update absolute descriptor members
    //      - return SUCCESS.
    //

    if ( deltaSize == 0 )   {
       
        RtlpClearControlBits( psd, SE_SELF_RELATIVE );

        //
        // Only the following fields are updated.
        //

        ASSERT( sizeof( psd->Owner ) == sizeof( psdr->Owner ) );
        ASSERT( sizeof( psd->Group ) == sizeof( psdr->Group ) );
        ASSERT( sizeof( psd->Sacl  ) == sizeof( psdr->Sacl  ) );
        ASSERT( sizeof( psd->Dacl  ) == sizeof( psdr->Dacl  ) );

        psd->Owner = owner;
        psd->Group = group;
        psd->Sacl  = sacl;
        psd->Dacl  = dacl;
    
        return( STATUS_SUCCESS );

    }

//
// Determine the required size for the absolute format:
//

#define ULONG_PTR_SDEND( _Adr ) ( (ULONG_PTR)(_Adr) + (ULONG_PTR)(_Adr##Size) )

    ptr = owner > group ? ULONG_PTR_SDEND( owner ) : ULONG_PTR_SDEND( group );
    ptr = ptr > (ULONG_PTR)dacl ? ptr : ULONG_PTR_SDEND( dacl );
    ptr = ptr > (ULONG_PTR)sacl ? ptr : ULONG_PTR_SDEND( sacl );
   
    newBufferSize = sizeof( SECURITY_DESCRIPTOR );
    if ( ptr )   {

#define ULONG_ROUND_UP( x, y )   ((ULONG)(x) + ((y)-1) & ~((y)-1))

        newBufferSize += ULONG_ROUND_UP( (ULONG_PTR)ptr - (ULONG_PTR)(psdr + 1), sizeof(PVOID) );
    }

    //
    // If the specified buffer size is not big enough, let the caller know abour 
    // the minimum size and return STATUS_BUFFER_TOO_SMALL.
    //

    if ( newBufferSize > *pBufferSize )  {
        *pBufferSize = newBufferSize;
        return( STATUS_BUFFER_TOO_SMALL );
    }

//
// Update absolute security descriptor:
//

    //
    // Move the members of self-relative security descriptor in their 
    // absolute format locations.
    //

    if ( ptr )   {
       RtlMoveMemory( (PVOID)(psd + 1), (PVOID)(psdr + 1), newBufferSize - sizeof( SECURITY_DESCRIPTOR) );      
    }

    //
    // Clear the self-relative flag
    //

    RtlpClearControlBits( psd, SE_SELF_RELATIVE );

    //
    // Only the following fields are updated.
    //

    psd->Owner = (PSID)( owner ? (ULONG_PTR)owner + deltaSize : 0 );
    psd->Group = (PSID)( group ? (ULONG_PTR)group + deltaSize : 0 );
    psd->Sacl  = (PACL)( sacl  ? (ULONG_PTR)sacl  + deltaSize : 0 );
    psd->Dacl  = (PACL)( dacl  ? (ULONG_PTR)dacl  + deltaSize : 0 );
    
    return( STATUS_SUCCESS );

} // RtlSelfRelativeToAbsoluteSD2()
Exemplo n.º 3
0
NTSTATUS
RtlSelfRelativeToAbsoluteSD(
    IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
    OUT PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
    IN OUT PULONG AbsoluteSecurityDescriptorSize,
    IN OUT PACL Dacl,
    IN OUT PULONG DaclSize,
    IN OUT PACL Sacl,
    IN OUT PULONG SaclSize,
    IN OUT PSID Owner,
    IN OUT PULONG OwnerSize,
    IN OUT PSID PrimaryGroup,
    IN OUT PULONG PrimaryGroupSize
    )

/*++

Routine Description:

    Converts a security descriptor from self-relative format to absolute
    format

Arguments:

    SecurityDescriptor - Supplies a pointer to a security descriptor in
        Self-Relative format

    AbsoluteSecurityDescriptor - A pointer to a buffer in which will be
        placed the main body of the Absolute format security descriptor.

    Dacl - Supplies a pointer to a buffer that will contain the Dacl of the
        output descriptor.  This pointer will be referenced by, not copied
        into, the output descriptor.

    DaclSize - Supplies the size of the buffer pointed to by Dacl.  In case
        of error, it will return the minimum size necessary to contain the
        Dacl.

    Sacl - Supplies a pointer to a buffer that will contain the Sacl of the
        output descriptor.  This pointer will be referenced by, not copied
        into, the output descriptor.

    SaclSize - Supplies the size of the buffer pointed to by Sacl.  In case
        of error, it will return the minimum size necessary to contain the
        Sacl.

    Owner - Supplies a pointer to a buffer that will contain the Owner of
        the output descriptor.  This pointer will be referenced by, not
        copied into, the output descriptor.

    OwnerSize - Supplies the size of the buffer pointed to by Owner.  In
        case of error, it will return the minimum size necessary to contain
        the Owner.

    PrimaryGroup - Supplies a pointer to a buffer that will contain the
        PrimaryGroup of the output descriptor.  This pointer will be
        referenced by, not copied into, the output descriptor.

    PrimaryGroupSize - Supplies the size of the buffer pointed to by
        PrimaryGroup.  In case of error, it will return the minimum size
        necessary to contain the PrimaryGroup.


Return Value:

    STATUS_SUCCESS - Success

    STATUS_BUFFER_TOO_SMALL - One of the buffers passed was too small.

    STATUS_INVALID_OWNER - There was not a valid owner in the passed
        security descriptor.

--*/

{
    ULONG NewDaclSize;
    ULONG NewSaclSize;
    ULONG NewBodySize;
    ULONG NewOwnerSize;
    ULONG NewGroupSize;

    PSID NewOwner;
    PSID NewGroup;
    PACL NewDacl;
    PACL NewSacl;

    //
    // typecast security descriptors so we don't have to cast all over the place.
    //

    PISECURITY_DESCRIPTOR OutSD =
        AbsoluteSecurityDescriptor;

    PISECURITY_DESCRIPTOR InSD =
            (PISECURITY_DESCRIPTOR)SelfRelativeSecurityDescriptor;


    RTL_PAGED_CODE();

    if ( !RtlpAreControlBitsSet( InSD, SE_SELF_RELATIVE) ) {
        return( STATUS_BAD_DESCRIPTOR_FORMAT );
    }

    NewBodySize = sizeof(SECURITY_DESCRIPTOR);

    RtlpQuerySecurityDescriptor(
        InSD,
        &NewOwner,
        &NewOwnerSize,
        &NewGroup,
        &NewGroupSize,
        &NewDacl,
        &NewDaclSize,
        &NewSacl,
        &NewSaclSize
        );

    if ( (NewBodySize  > *AbsoluteSecurityDescriptorSize) ||
         (NewOwnerSize > *OwnerSize )                     ||
         (NewDaclSize  > *DaclSize )                      ||
         (NewSaclSize  > *SaclSize )                      ||
         (NewGroupSize > *PrimaryGroupSize ) ) {

         *AbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
         *PrimaryGroupSize               = NewGroupSize;
         *OwnerSize                      = NewOwnerSize;
         *SaclSize                       = NewSaclSize;
         *DaclSize                       = NewDaclSize;

         return( STATUS_BUFFER_TOO_SMALL );
    }


    RtlMoveMemory( OutSD,
                   InSD,
                   sizeof(SECURITY_DESCRIPTOR_RELATIVE) );

    OutSD->Owner = NULL;
    OutSD->Group = NULL;
    OutSD->Sacl  = NULL;
    OutSD->Dacl  = NULL;

    RtlpClearControlBits( OutSD, SE_SELF_RELATIVE );

    if (NewOwner != NULL) {
        RtlMoveMemory( Owner, NewOwner, SeLengthSid( NewOwner ));
        OutSD->Owner = Owner;
    }

    if (NewGroup != NULL) {
        RtlMoveMemory( PrimaryGroup, NewGroup, SeLengthSid( NewGroup ));
        OutSD->Group = PrimaryGroup;
    }

    if (NewSacl != NULL) {
        RtlMoveMemory( Sacl, NewSacl, NewSacl->AclSize );
        OutSD->Sacl  = Sacl;
    }

    if (NewDacl != NULL) {
        RtlMoveMemory( Dacl, NewDacl, NewDacl->AclSize );
        OutSD->Dacl  = Dacl;
    }

    return( STATUS_SUCCESS );
}
Exemplo n.º 4
0
NTSTATUS
RtlMakeSelfRelativeSD(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
    IN OUT PULONG BufferLength
    )

/*++

Routine Description:

    Makes a copy of a security descriptor.  The produced copy will be in self-relative
    form.

    The security descriptor to be copied may be in either absolute or self-relative
    form.

Arguments:

    SecurityDescriptor - Pointer to a security descriptor.  This descriptor will not
        be modified.

    SelfRelativeSecurityDescriptor - Pointer to a buffer that will contain
        the returned self-relative security descriptor.

    BufferLength - Supplies the length of the buffer.  If the supplied
        buffer is not large enough to hold the self-relative security
        descriptor, an error will be returned, and this field will return
        the minimum size required.


Return Value:

    STATUS_BUFFER_TOO_SMALL - The supplied buffer was too small to contain
        the resultant security descriptor.


--*/

{
    ULONG NewDaclSize;
    ULONG NewSaclSize;
    ULONG NewOwnerSize;
    ULONG NewGroupSize;

    ULONG AllocationSize;

    PSID NewOwner;
    PSID NewGroup;
    PACL NewDacl;
    PACL NewSacl;

    PCHAR Field;
    PCHAR Base;


    //
    // Convert security descriptors to new data type so we don't
    // have to cast all over the place.
    //

    PISECURITY_DESCRIPTOR_RELATIVE IResultantDescriptor =
            (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSecurityDescriptor;

    PISECURITY_DESCRIPTOR IPassedSecurityDescriptor =
            (PISECURITY_DESCRIPTOR)SecurityDescriptor;


    RtlpQuerySecurityDescriptor(
        IPassedSecurityDescriptor,
        &NewOwner,
        &NewOwnerSize,
        &NewGroup,
        &NewGroupSize,
        &NewDacl,
        &NewDaclSize,
        &NewSacl,
        &NewSaclSize
        );

    RTL_PAGED_CODE();

    AllocationSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
                     NewOwnerSize +
                     NewGroupSize +
                     NewDaclSize  +
                     NewSaclSize  ;

    if (AllocationSize > *BufferLength) {
        *BufferLength = AllocationSize;
        return( STATUS_BUFFER_TOO_SMALL );
    }

    RtlZeroMemory( IResultantDescriptor, AllocationSize );

    RtlCopyMemory( IResultantDescriptor,
                   IPassedSecurityDescriptor,
                   FIELD_OFFSET( SECURITY_DESCRIPTOR_RELATIVE, Owner ));


    Base = (PCHAR)(IResultantDescriptor);
    Field =  Base + (ULONG)sizeof(SECURITY_DESCRIPTOR_RELATIVE);

    if (NewSaclSize > 0) {
        RtlCopyMemory( Field, NewSacl, NewSaclSize );
        IResultantDescriptor->Sacl = RtlPointerToOffset(Base,Field);
        Field += NewSaclSize;
    } else {
        IResultantDescriptor->Sacl = 0;
    }


    if (NewDaclSize > 0) {
        RtlCopyMemory( Field, NewDacl, NewDaclSize );
        IResultantDescriptor->Dacl = RtlPointerToOffset(Base,Field);
        Field += NewDaclSize;
    } else {
        IResultantDescriptor->Dacl = 0;
    }



    if (NewOwnerSize > 0) {
        RtlCopyMemory( Field, NewOwner, NewOwnerSize );
        IResultantDescriptor->Owner = RtlPointerToOffset(Base,Field);
        Field += NewOwnerSize;
    }


    if (NewGroupSize > 0) {
        RtlCopyMemory( Field, NewGroup, NewGroupSize );
        IResultantDescriptor->Group = RtlPointerToOffset(Base,Field);
    }

    RtlpSetControlBits( IResultantDescriptor, SE_SELF_RELATIVE );

    return( STATUS_SUCCESS );

}
Exemplo n.º 5
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
                             OUT PULONG BufferSize)
{
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
    PISECURITY_DESCRIPTOR_RELATIVE RelSd = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
    PVOID DataStart, DataEnd;
    LONG MoveDelta;
    ULONG DataSize, OwnerLength, GroupLength, DaclLength, SaclLength;
    PSID pOwner, pGroup;
    PACL pDacl, pSacl;
    PAGED_CODE_RTL();

    /* Need input */
    if (!RelSd) return STATUS_INVALID_PARAMETER_1;

    /* Need to know how much space we have */
    if (!BufferSize) return STATUS_INVALID_PARAMETER_2;

    /* Input must be relative */
    if (!(RelSd->Control & SE_SELF_RELATIVE)) return STATUS_BAD_DESCRIPTOR_FORMAT;

    /* Query all the component sizes */
    RtlpQuerySecurityDescriptor(Sd,
                                &pOwner,
                                &OwnerLength,
                                &pGroup,
                                &GroupLength,
                                &pDacl,
                                &DaclLength,
                                &pSacl,
                                &SaclLength);

    /*
     * Check if there's a difference in structure layout between relatiev and
     * absolute descriptors. On 32-bit, there won't be, since an offset is the
     * same size as a pointer (32-bit), but on 64-bit, the offsets remain 32-bit
     * as they are not SIZE_T, but ULONG, while the pointers now become 64-bit
     * and thus the structure is different */
    MoveDelta = sizeof(SECURITY_DESCRIPTOR) - sizeof(SECURITY_DESCRIPTOR_RELATIVE);
    if (!MoveDelta)
    {
        /* So on 32-bit, simply clear the flag... */
        Sd->Control &= ~SE_SELF_RELATIVE;

        /* Ensure we're *really* on 32-bit */
        ASSERT(sizeof(Sd->Owner) == sizeof(RelSd->Owner));
        ASSERT(sizeof(Sd->Group) == sizeof(RelSd->Group));
        ASSERT(sizeof(Sd->Sacl) == sizeof(RelSd->Sacl));
        ASSERT(sizeof(Sd->Dacl) == sizeof(RelSd->Dacl));

        /* And simply set pointers where there used to be offsets */
        Sd->Owner = pOwner;
        Sd->Group = pGroup;
        Sd->Sacl = pSacl;
        Sd->Dacl = pDacl;
        return STATUS_SUCCESS;
    }

    /*
     * Calculate the start and end of the data area, we simply just move the
     * data by the difference between the size of the relative and absolute
     * security descriptor structure
     */
    DataStart = pOwner;
    DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);

    /* Is there a group? */
    if (pGroup)
    {
        /* Is the group higher than where we started? */
        if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || !DataStart)
        {
            /* Update the start pointer */
            DataStart = pGroup;
        }

        /* Is the group beyond where we ended? */
        if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || !DataEnd)
        {
            /* Update the end pointer */
            DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
        }
    }

    /* Is there a DACL? */
    if (pDacl)
    {
        /* Is the DACL higher than where we started? */
        if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || !DataStart)
        {
            /* Update the start pointer */
            DataStart = pDacl;
        }

        /* Is the DACL beyond where we ended? */
        if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
        {
            /* Update the end pointer */
            DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
        }
    }

    /* Is there a SACL? */
    if (pSacl)
    {
        /* Is the SACL higher than where we started? */
        if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || !DataStart)
        {
            /* Update the start pointer */
            DataStart = pSacl;
        }

        /* Is the SACL beyond where we ended? */
        if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
        {
            /* Update the end pointer */
            DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
        }
    }

    /* Sanity check */
    ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);

    /* Now compute the difference between relative and absolute */
    DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);

    /* Is the new buffer large enough for this difference? */
    if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
    {
        /* Nope, bail out */
        *BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
        return STATUS_BUFFER_TOO_SMALL;
    }

    /* Is there anything actually to copy? */
    if (DataSize)
    {
        /*
         * There must be at least one SID or ACL in the security descriptor!
         * Also the data area must be located somewhere after the end of the
         * SECURITY_DESCRIPTOR_RELATIVE structure
         */
        ASSERT(DataStart != NULL);
        ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSd + 1));

        /* It's time to move the data */
        RtlMoveMemory((PVOID)(Sd + 1),
                      DataStart,
                      DataSize);
    }

    /* Is there an owner? */
    if (pOwner)
    {
        /* Set the pointer to the relative position */
        Sd->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
    }
    else
    {
        /* No owner, clear the pointer */
        Sd->Owner = NULL;
    }

    /* Is there a group */
    if (pGroup)
    {
        /* Set the pointer to the relative position */
        Sd->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
    }
    else
    {
        /* No group, clear the pointer */
        Sd->Group = NULL;
    }

    /* Is there a SACL? */
    if (pSacl)
    {
        /* Set the pointer to the relative position */
        Sd->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
    }
    else
    {
        /* No SACL, clear the pointer */
        Sd->Sacl = NULL;
    }

    /* Is there a DACL? */
    if (pDacl)
    {
        /* Set the pointer to the relative position */
        Sd->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
    }
    else
    {
        /* No DACL, clear the pointer */
        Sd->Dacl = NULL;
    }

    /* Clear the self-relative flag */
    Sd->Control &= ~SE_SELF_RELATIVE;

    /* All good */
    return STATUS_SUCCESS;
}
Exemplo n.º 6
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD,
                            OUT PSECURITY_DESCRIPTOR AbsoluteSD,
                            IN PULONG AbsoluteSDSize,
                            IN PACL Dacl,
                            IN PULONG DaclSize,
                            IN PACL Sacl,
                            IN PULONG SaclSize,
                            IN PSID Owner,
                            IN PULONG OwnerSize,
                            IN PSID PrimaryGroup,
                            IN PULONG PrimaryGroupSize)
{
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)AbsoluteSD;
    PISECURITY_DESCRIPTOR RelSd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
    ULONG OwnerLength, GroupLength, DaclLength, SaclLength;
    PSID pOwner, pGroup;
    PACL pDacl, pSacl;
    PAGED_CODE_RTL();

    /* Must be relative, otherwiise fail */
    if (!(RelSd->Control & SE_SELF_RELATIVE)) return STATUS_BAD_DESCRIPTOR_FORMAT;

    /* Get all the components */
    RtlpQuerySecurityDescriptor(RelSd,
                                &pOwner,
                                &OwnerLength,
                                &pGroup,
                                &GroupLength,
                                &pDacl,
                                &DaclLength,
                                &pSacl,
                                &SaclLength);

    /* Fail if there's not enough space */
    if (!(Sd) ||
        (sizeof(SECURITY_DESCRIPTOR) > *AbsoluteSDSize) ||
        (OwnerLength > *OwnerSize) ||
        (GroupLength > *PrimaryGroupSize) ||
        (DaclLength > *DaclSize) ||
        (SaclLength > *SaclSize))
    {
        /* Return how much space is needed for each components */
        *AbsoluteSDSize = sizeof(SECURITY_DESCRIPTOR);
        *OwnerSize = OwnerLength;
        *PrimaryGroupSize = GroupLength;
        *DaclSize = DaclLength;
        *SaclSize = SaclLength;
        return STATUS_BUFFER_TOO_SMALL;
    }

    /* Copy the header fields */
    RtlMoveMemory(Sd, RelSd, sizeof(SECURITY_DESCRIPTOR_RELATIVE));

    /* Wipe out the pointers and the relative flag */
    Sd->Owner = NULL;
    Sd->Group = NULL;
    Sd->Sacl = NULL;
    Sd->Dacl = NULL;
    Sd->Control &= ~SE_SELF_RELATIVE;

    /* Is there an owner? */
    if (pOwner)
    {
        /* Copy it */
        RtlMoveMemory(Owner, pOwner, RtlLengthSid(pOwner));
        Sd->Owner = Owner;
    }

    /* Is there a group? */
    if (pGroup)
    {
        /* Copy it */
        RtlMoveMemory(PrimaryGroup, pGroup, RtlLengthSid(pGroup));
        Sd->Group = PrimaryGroup;
    }

    /* Is there a DACL? */
    if (pDacl)
    {
        /* Copy it */
        RtlMoveMemory(Dacl, pDacl, pDacl->AclSize);
        Sd->Dacl = Dacl;
    }

    /* Is there a SACL? */
    if (pSacl)
    {
        /* Copy it */
        RtlMoveMemory(Sacl, pSacl, pSacl->AclSize);
        Sd->Sacl = Sacl;
    }

    /* All good */
    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD,
                      OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
                      IN OUT PULONG BufferLength)
{
    PSID Owner, Group;
    PACL Sacl, Dacl;
    ULONG OwnerLength, GroupLength, SaclLength, DaclLength, TotalLength;
    ULONG_PTR Current;
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)AbsoluteSD;
    PISECURITY_DESCRIPTOR_RELATIVE RelSd = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
    PAGED_CODE_RTL();

    /* Query all components */
    RtlpQuerySecurityDescriptor(Sd,
                                &Owner,
                                &OwnerLength,
                                &Group,
                                &GroupLength,
                                &Dacl,
                                &DaclLength,
                                &Sacl,
                                &SaclLength);

    /* Calculate final length */
    TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
                  OwnerLength +
                  GroupLength +
                  SaclLength +
                  DaclLength;

    /* Is there enough space? */
    if (*BufferLength < TotalLength)
    {
        /* Nope, return how much is needed */
        *BufferLength = TotalLength;
        return STATUS_BUFFER_TOO_SMALL;
    }

    /* Start fresh */
    RtlZeroMemory(RelSd, TotalLength);

    /* Copy the header fields */
    RtlCopyMemory(RelSd,
                  Sd,
                  FIELD_OFFSET(SECURITY_DESCRIPTOR_RELATIVE, Owner));

    /* Set the current copy pointer */
    Current = (ULONG_PTR)(RelSd + 1);

    /* Is there a SACL? */
    if (SaclLength)
    {
        /* Copy it */
        RtlCopyMemory((PVOID)Current, Sacl, SaclLength);
        RelSd->Sacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
        Current += SaclLength;
    }

    /* Is there a DACL? */
    if (DaclLength)
    {
        /* Copy it */
        RtlCopyMemory((PVOID)Current, Dacl, DaclLength);
        RelSd->Dacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
        Current += DaclLength;
    }

    /* Is there an owner? */
    if (OwnerLength)
    {
        /* Copy it */
        RtlCopyMemory((PVOID)Current, Owner, OwnerLength);
        RelSd->Owner = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
        Current += OwnerLength;
    }

    /* Is there a group? */
    if (GroupLength)
    {
        /* Copy it */
        RtlCopyMemory((PVOID)Current, Group, GroupLength);
        RelSd->Group = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
    }

    /* Mark it as relative */
    RelSd->Control |= SE_SELF_RELATIVE;

    /* All good */
    return STATUS_SUCCESS;
}