test: rtlassig.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# rtlassig.c File Reference

`#include "ntrtlp.h"`
`#include "seopaque.h"`
`#include "sertlp.h"`

Go to the source code of this file.

## Defines

#define | ULONG_PTR_SDEND(_Adr) ( (ULONG_PTR)(_Adr) + (ULONG_PTR)(_Adr##Size) )
#define | ULONG_ROUND_UP(x, y) ((ULONG)(x) + ((y)-1) & ~((y)-1))

## Functions

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)
NTSTATUS | RtlMakeSelfRelativeSD (IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN OUT PULONG BufferLength)
NTSTATUS | RtlAbsoluteToSelfRelativeSD (IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN OUT PULONG BufferLength)
VOID | RtlpQuerySecurityDescriptor (IN PISECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PULONG OwnerSize, OUT PSID *PrimaryGroup, OUT PULONG PrimaryGroupSize, OUT PACL *Dacl, OUT PULONG DaclSize, OUT PACL *Sacl, OUT PULONG SaclSize)
NTSTATUS | RtlSelfRelativeToAbsoluteSD2 (IN OUT PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, IN OUT PULONG pBufferSize)

## Define Documentation

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

| Referenced by RtlSelfRelativeToAbsoluteSD2().

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

| Referenced by RtlSelfRelativeToAbsoluteSD2().

## Function Documentation

NTSTATUS RtlAbsoluteToSelfRelativeSD | ( | IN PSECURITY_DESCRIPTOR | AbsoluteSecurityDescriptor,
|  | IN OUT PSECURITY_DESCRIPTOR | SelfRelativeSecurityDescriptor,
|  | IN OUT PULONG | BufferLength
| ) |

Definition at line 360 of file rtlassig.c.

References NTSTATUS(), RTL_PAGED_CODE, and RtlMakeSelfRelativeSD().

Referenced by SeMakeAnonymousLogonToken(), and SeMakeSystemToken().

    00368                    :
    00369
    00370     Converts a security descriptor in absolute form to one in self-relative
    00371     form.
    00372
    00373 Arguments:
    00374
    00375     AbsoluteSecurityDescriptor - Pointer to an absolute format security
    00376         descriptor.  This descriptor will not be modified.
    00377
    00378     SelfRelativeSecurityDescriptor - Pointer to a buffer that will contain
    00379         the returned self-relative security descriptor.
    00380
    00381     BufferLength - Supplies the length of the buffer.  If the supplied
    00382         buffer is not large enough to hold the self-relative security
    00383         descriptor, an error will be returned, and this field will return
    00384         the minimum size required.
    00385
    00386
    00387 Return Value:
    00388
    00389     STATUS_BUFFER_TOO_SMALL - The supplied buffer was too small to contain
    00390         the resultant security descriptor.
    00391
    00392     STATUS_BAD_DESCRIPTOR_FORMAT - The supplied security descriptor was not
    00393         in absolute form.
    00394
    00395 --*/
    00396
    00397 {
    00398     NTSTATUS NtStatus;
    00399
    00400     PISECURITY_DESCRIPTOR IAbsoluteSecurityDescriptor =
    00401             (PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor;
    00402
    00403
    00404     RTL_PAGED_CODE();
    00405
    00406     //
    00407     // Make sure the passed SD is absolute format, and then call
    00408     // RtlMakeSelfRelativeSD() to do all the work.
    00409     //
    00410
    00411     if ( RtlpAreControlBitsSet( IAbsoluteSecurityDescriptor, SE_SELF_RELATIVE) ) {
    00412         return( STATUS_BAD_DESCRIPTOR_FORMAT );
    00413     }
    00414
    00415     NtStatus = RtlMakeSelfRelativeSD(
    00416                    AbsoluteSecurityDescriptor,
    00417                    SelfRelativeSecurityDescriptor,
    00418                    BufferLength
    00419                    );
    00420
    00421     return( NtStatus );
    00422
    00423 }
    VOID

NTSTATUS RtlMakeSelfRelativeSD | ( | IN PSECURITY_DESCRIPTOR | SecurityDescriptor,
|  | IN OUT PSECURITY_DESCRIPTOR | SelfRelativeSecurityDescriptor,
|  | IN OUT PULONG | BufferLength
| ) |

Definition at line 219 of file rtlassig.c.

References Owner, RTL_PAGED_CODE, and RtlpQuerySecurityDescriptor().

Referenced by RtlAbsoluteToSelfRelativeSD().

    00227                    :
    00228
    00229     Makes a copy of a security descriptor.  The produced copy will be in self-relative
    00230     form.
    00231
    00232     The security descriptor to be copied may be in either absolute or self-relative
    00233     form.
    00234
    00235 Arguments:
    00236
    00237     SecurityDescriptor - Pointer to a security descriptor.  This descriptor will not
    00238         be modified.
    00239
    00240     SelfRelativeSecurityDescriptor - Pointer to a buffer that will contain
    00241         the returned self-relative security descriptor.
    00242
    00243     BufferLength - Supplies the length of the buffer.  If the supplied
    00244         buffer is not large enough to hold the self-relative security
    00245         descriptor, an error will be returned, and this field will return
    00246         the minimum size required.
    00247
    00248
    00249 Return Value:
    00250
    00251     STATUS_BUFFER_TOO_SMALL - The supplied buffer was too small to contain
    00252         the resultant security descriptor.
    00253
    00254
    00255 --*/
    00256
    00257 {
    00258     ULONG NewDaclSize;
    00259     ULONG NewSaclSize;
    00260     ULONG NewOwnerSize;
    00261     ULONG NewGroupSize;
    00262
    00263     ULONG AllocationSize;
    00264
    00265     PSID NewOwner;
    00266     PSID NewGroup;
    00267     PACL NewDacl;
    00268     PACL NewSacl;
    00269
    00270     PCHAR Field;
    00271     PCHAR Base;
    00272
    00273
    00274     //
    00275     // Convert security descriptors to new data type so we don't
    00276     // have to cast all over the place.
    00277     //
    00278
    00279     PISECURITY_DESCRIPTOR_RELATIVE IResultantDescriptor =
    00280             (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSecurityDescriptor;
    00281
    00282     PISECURITY_DESCRIPTOR IPassedSecurityDescriptor =
    00283             (PISECURITY_DESCRIPTOR)SecurityDescriptor;
    00284
    00285
    00286     RtlpQuerySecurityDescriptor(
    00287         IPassedSecurityDescriptor,
    00288         &NewOwner,
    00289         &NewOwnerSize,
    00290         &NewGroup,
    00291         &NewGroupSize,
    00292         &NewDacl,
    00293         &NewDaclSize,
    00294         &NewSacl,
    00295         &NewSaclSize
    00296         );
    00297
    00298     RTL_PAGED_CODE();
    00299
    00300     AllocationSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
    00301                      NewOwnerSize +
    00302                      NewGroupSize +
    00303                      NewDaclSize  +
    00304                      NewSaclSize  ;
    00305
    00306     if (AllocationSize > *BufferLength) {
    00307         *BufferLength = AllocationSize;
    00308         return( STATUS_BUFFER_TOO_SMALL );
    00309     }
    00310
    00311     RtlZeroMemory( IResultantDescriptor, AllocationSize );
    00312
    00313     RtlCopyMemory( IResultantDescriptor,
    00314                    IPassedSecurityDescriptor,
    00315                    FIELD_OFFSET( SECURITY_DESCRIPTOR_RELATIVE, Owner ));
    00316
    00317
    00318     Base = (PCHAR)(IResultantDescriptor);
    00319     Field =  Base + (ULONG)sizeof(SECURITY_DESCRIPTOR_RELATIVE);
    00320
    00321     if (NewSaclSize > 0) {
    00322         RtlCopyMemory( Field, NewSacl, NewSaclSize );
    00323         IResultantDescriptor->Sacl = RtlPointerToOffset(Base,Field);
    00324         Field += NewSaclSize;
    00325     } else {
    00326         IResultantDescriptor->Sacl = 0;
    00327     }
    00328
    00329
    00330     if (NewDaclSize > 0) {
    00331         RtlCopyMemory( Field, NewDacl, NewDaclSize );
    00332         IResultantDescriptor->Dacl = RtlPointerToOffset(Base,Field);
    00333         Field += NewDaclSize;
    00334     } else {
    00335         IResultantDescriptor->Dacl = 0;
    00336     }
    00337
    00338
    00339
    00340     if (NewOwnerSize > 0) {
    00341         RtlCopyMemory( Field, NewOwner, NewOwnerSize );
    00342         IResultantDescriptor->Owner = RtlPointerToOffset(Base,Field);
    00343         Field += NewOwnerSize;
    00344     }
    00345
    00346
    00347     if (NewGroupSize > 0) {
    00348         RtlCopyMemory( Field, NewGroup, NewGroupSize );
    00349         IResultantDescriptor->Group = RtlPointerToOffset(Base,Field);
    00350     }
    00351
    00352     RtlpSetControlBits( IResultantDescriptor, SE_SELF_RELATIVE );
    00353
    00354     return( STATUS_SUCCESS );
    00355
    00356 }

VOID RtlpQuerySecurityDescriptor | ( | IN PISECURITY_DESCRIPTOR | SecurityDescriptor,
|  | OUT PSID * | Owner,
|  | OUT PULONG | OwnerSize,
|  | OUT PSID * | PrimaryGroup,
|  | OUT PULONG | PrimaryGroupSize,
|  | OUT PACL * | Dacl,
|  | OUT PULONG | DaclSize,
|  | OUT PACL * | Sacl,
|  | OUT PULONG | SaclSize
| ) |

Definition at line 425 of file rtlassig.c.

References Dacl, NULL, Owner, RTL_PAGED_CODE, and SeLengthSid.

Referenced by RtlCopySecurityDescriptor(), RtlMakeSelfRelativeSD(), RtlSelfRelativeToAbsoluteSD(), and RtlSelfRelativeToAbsoluteSD2().

    00438                    :
    00439
    00440     Returns the pieces of a security descriptor structure.
    00441
    00442 Arguments:
    00443
    00444
    00445     SecurityDescriptor - Provides the security descriptor of interest.
    00446
    00447     Owner - Returns a pointer to the owner information contained in the
    00448         security descriptor.
    00449
    00450     OwnerSize - Returns the size of the owner information.
    00451
    00452     PrimaryGroup -  Returns a pointer to the primary group information.
    00453
    00454     PrimaryGroupSize - Returns the size of the primary group information.
    00455
    00456     Dacl - Returns a pointer to the Dacl.
    00457
    00458     DaclSize - Returns the size of the Dacl.
    00459
    00460     Sacl - Returns a pointer to the Sacl.
    00461
    00462     SaclSize - Returns the size of the Sacl.
    00463
    00464 Return Value:
    00465
    00466     None.
    00467
    00468 --*/
    00469 {
    00470
    00471     RTL_PAGED_CODE();
    00472
    00473     *Owner = RtlpOwnerAddrSecurityDescriptor( SecurityDescriptor );
    00474
    00475     if (*Owner != NULL) {
    00476         *OwnerSize = LongAlignSize(SeLengthSid(*Owner));
    00477     } else {
    00478         *OwnerSize = 0;
    00479     }
    00480
    00481     *Dacl = RtlpDaclAddrSecurityDescriptor ( SecurityDescriptor );
    00482
    00483     if (*Dacl !=NULL) {
    00484         *DaclSize = LongAlignSize((*Dacl)->AclSize);
    00485     } else {
    00486         *DaclSize = 0;
    00487     }
    00488
    00489     *PrimaryGroup = RtlpGroupAddrSecurityDescriptor( SecurityDescriptor );
    00490
    00491     if (*PrimaryGroup != NULL) {
    00492         *PrimaryGroupSize = LongAlignSize(SeLengthSid(*PrimaryGroup));
    00493     } else {
    00494          *PrimaryGroupSize = 0;
    00495     }
    00496
    00497     *Sacl = RtlpSaclAddrSecurityDescriptor( SecurityDescriptor );
    00498
    00499     if (*Sacl != NULL) {
    00500         *SaclSize = LongAlignSize((*Sacl)->AclSize);
    00501     } else {
    00502         *SaclSize = 0;
    00503     }
    00504
    00505 }

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
| ) |

Definition at line 49 of file rtlassig.c.

References Dacl, NULL, Owner, RTL_PAGED_CODE, RtlpQuerySecurityDescriptor(), and SeLengthSid.

    00065                    :
    00066
    00067     Converts a security descriptor from self-relative format to absolute
    00068     format
    00069
    00070 Arguments:
    00071
    00072     SecurityDescriptor - Supplies a pointer to a security descriptor in
    00073         Self-Relative format
    00074
    00075     AbsoluteSecurityDescriptor - A pointer to a buffer in which will be
    00076         placed the main body of the Absolute format security descriptor.
    00077
    00078     Dacl - Supplies a pointer to a buffer that will contain the Dacl of the
    00079         output descriptor.  This pointer will be referenced by, not copied
    00080         into, the output descriptor.
    00081
    00082     DaclSize - Supplies the size of the buffer pointed to by Dacl.  In case
    00083         of error, it will return the minimum size necessary to contain the
    00084         Dacl.
    00085
    00086     Sacl - Supplies a pointer to a buffer that will contain the Sacl of the
    00087         output descriptor.  This pointer will be referenced by, not copied
    00088         into, the output descriptor.
    00089
    00090     SaclSize - Supplies the size of the buffer pointed to by Sacl.  In case
    00091         of error, it will return the minimum size necessary to contain the
    00092         Sacl.
    00093
    00094     Owner - Supplies a pointer to a buffer that will contain the Owner of
    00095         the output descriptor.  This pointer will be referenced by, not
    00096         copied into, the output descriptor.
    00097
    00098     OwnerSize - Supplies the size of the buffer pointed to by Owner.  In
    00099         case of error, it will return the minimum size necessary to contain
    00100         the Owner.
    00101
    00102     PrimaryGroup - Supplies a pointer to a buffer that will contain the
    00103         PrimaryGroup of the output descriptor.  This pointer will be
    00104         referenced by, not copied into, the output descriptor.
    00105
    00106     PrimaryGroupSize - Supplies the size of the buffer pointed to by
    00107         PrimaryGroup.  In case of error, it will return the minimum size
    00108         necessary to contain the PrimaryGroup.
    00109
    00110
    00111 Return Value:
    00112
    00113     STATUS_SUCCESS - Success
    00114
    00115     STATUS_BUFFER_TOO_SMALL - One of the buffers passed was too small.
    00116
    00117     STATUS_INVALID_OWNER - There was not a valid owner in the passed
    00118         security descriptor.
    00119
    00120 --*/
    00121
    00122 {
    00123     ULONG NewDaclSize;
    00124     ULONG NewSaclSize;
    00125     ULONG NewBodySize;
    00126     ULONG NewOwnerSize;
    00127     ULONG NewGroupSize;
    00128
    00129     PSID NewOwner;
    00130     PSID NewGroup;
    00131     PACL NewDacl;
    00132     PACL NewSacl;
    00133
    00134     //
    00135     // typecast security descriptors so we don't have to cast all over the place.
    00136     //
    00137
    00138     PISECURITY_DESCRIPTOR OutSD =
    00139         AbsoluteSecurityDescriptor;
    00140
    00141     PISECURITY_DESCRIPTOR InSD =
    00142             (PISECURITY_DESCRIPTOR)SelfRelativeSecurityDescriptor;
    00143
    00144
    00145     RTL_PAGED_CODE();
    00146
    00147     if ( !RtlpAreControlBitsSet( InSD, SE_SELF_RELATIVE) ) {
    00148         return( STATUS_BAD_DESCRIPTOR_FORMAT );
    00149     }
    00150
    00151     NewBodySize = sizeof(SECURITY_DESCRIPTOR);
    00152
    00153     RtlpQuerySecurityDescriptor(
    00154         InSD,
    00155         &NewOwner,
    00156         &NewOwnerSize,
    00157         &NewGroup,
    00158         &NewGroupSize,
    00159         &NewDacl,
    00160         &NewDaclSize,
    00161         &NewSacl,
    00162         &NewSaclSize
    00163         );
    00164
    00165     if ( (NewBodySize  > *AbsoluteSecurityDescriptorSize) ||
    00166          (NewOwnerSize > *OwnerSize )                     ||
    00167          (NewDaclSize  > *DaclSize )                      ||
    00168          (NewSaclSize  > *SaclSize )                      ||
    00169          (NewGroupSize > *PrimaryGroupSize ) ) {
    00170
    00171          *AbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
    00172          *PrimaryGroupSize               = NewGroupSize;
    00173          *OwnerSize                      = NewOwnerSize;
    00174          *SaclSize                       = NewSaclSize;
    00175          *DaclSize                       = NewDaclSize;
    00176
    00177          return( STATUS_BUFFER_TOO_SMALL );
    00178     }
    00179
    00180
    00181     RtlMoveMemory( OutSD,
    00182                    InSD,
    00183                    sizeof(SECURITY_DESCRIPTOR_RELATIVE) );
    00184
    00185     OutSD->Owner = NULL;
    00186     OutSD->Group = NULL;
    00187     OutSD->Sacl  = NULL;
    00188     OutSD->Dacl  = NULL;
    00189
    00190     RtlpClearControlBits( OutSD, SE_SELF_RELATIVE );
    00191
    00192     if (NewOwner != NULL) {
    00193         RtlMoveMemory( Owner, NewOwner, SeLengthSid( NewOwner ));
    00194         OutSD->Owner = Owner;
    00195     }
    00196
    00197     if (NewGroup != NULL) {
    00198         RtlMoveMemory( PrimaryGroup, NewGroup, SeLengthSid( NewGroup ));
    00199         OutSD->Group = PrimaryGroup;
    00200     }
    00201
    00202     if (NewSacl != NULL) {
    00203         RtlMoveMemory( Sacl, NewSacl, NewSacl->AclSize );
    00204         OutSD->Sacl  = Sacl;
    00205     }
    00206
    00207     if (NewDacl != NULL) {
    00208         RtlMoveMemory( Dacl, NewDacl, NewDacl->AclSize );
    00209         OutSD->Dacl  = Dacl;
    00210     }
    00211
    00212     return( STATUS_SUCCESS );
    00213 }

NTSTATUS RtlSelfRelativeToAbsoluteSD2 | ( | IN OUT PSECURITY_DESCRIPTOR | pSelfRelativeSecurityDescriptor,
|  | IN OUT PULONG | pBufferSize
| ) |

Definition at line 510 of file rtlassig.c.

References ASSERT, C_ASSERT(), RTL_PAGED_CODE, RtlpQuerySecurityDescriptor(), ULONG_PTR_SDEND, and ULONG_ROUND_UP.

    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 // Typecast security descriptors so we don't have to cast all over the place.
    00573 //
    00574
    00575     PISECURITY_DESCRIPTOR          psd  = (PISECURITY_DESCRIPTOR)         pSelfRelativeSecurityDescriptor;
    00576     PISECURITY_DESCRIPTOR_RELATIVE psdr = (PISECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor;
    00577
    00578 //
    00579 // This code uses several assumptions about the absolute and self-relative formats of
    00580 // security descriptors and the way they are packing in memory.
    00581 // See Routine Description Notes.
    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 // Parameters check point
    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     // If the passed security descriptor is not self-relative, we return
    00603     // an format error.
    00604     //
    00605
    00606     if ( !RtlpAreControlBitsSet( psd, SE_SELF_RELATIVE) ) {
    00607         return( STATUS_BAD_DESCRIPTOR_FORMAT );
    00608     }
    00609
    00610 //
    00611 // Update local variables by querying the self-relative descriptor.
    00612 //
    00613 // Note that the returned size values are long-aligned.
    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 // Identical formats check:
    00630 //
    00631
    00632     //
    00633     // Determine the delta in size between the two formats of security descriptors
    00634     //
    00635
    00636     deltaSize = sizeof( SECURITY_DESCRIPTOR ) - sizeof( SECURITY_DESCRIPTOR_RELATIVE );
    00637
    00638     //
    00639     // If identical format:
    00640     //      - clear the SELF_RELATIVE flag
    00641     //      - update absolute descriptor members
    00642     //      - return SUCCESS.
    00643     //
    00644
    00645     if ( deltaSize == 0 )   {
    00646
    00647         RtlpClearControlBits( psd, SE_SELF_RELATIVE );
    00648
    00649         //
    00650         // Only the following fields are updated.
    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 // Determine the required size for the absolute format:
    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     // If the specified buffer size is not big enough, let the caller know abour
    00687     // the minimum size and return STATUS_BUFFER_TOO_SMALL.
    00688     //
    00689
    00690     if ( newBufferSize > *pBufferSize )  {
    00691         *pBufferSize = newBufferSize;
    00692         return( STATUS_BUFFER_TOO_SMALL );
    00693     }
    00694
    00695 //
    00696 // Update absolute security descriptor:
    00697 //
    00698
    00699     //
    00700     // Move the members of self-relative security descriptor in their
    00701     // absolute format locations.
    00702     //
    00703
    00704     if ( ptr )   {
    00705        RtlMoveMemory( (PVOID)(psd + 1), (PVOID)(psdr + 1), newBufferSize - sizeof( SECURITY_DESCRIPTOR) );
    00706     }
    00707
    00708     //
    00709     // Clear the self-relative flag
    00710     //
    00711
    00712     RtlpClearControlBits( psd, SE_SELF_RELATIVE );
    00713
    00714     //
    00715     // Only the following fields are updated.
    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 } // RtlSelfRelativeToAbsoluteSD2()