ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sd.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:         See COPYING in the top level directory
00003  * PROJECT:           ReactOS system libraries
00004  * PURPOSE:           Security descriptor functions
00005  * FILE:              lib/rtl/sd.c
00006  * PROGRAMER:         David Welch <welch@cwcom.net>
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include <rtl.h>
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS ***************************************************************/
00017 
00018 
00019 static VOID
00020 RtlpQuerySecurityDescriptorPointers(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
00021                                     OUT PSID *Owner  OPTIONAL,
00022                                     OUT PSID *Group  OPTIONAL,
00023                                     OUT PACL *Sacl  OPTIONAL,
00024                                     OUT PACL *Dacl  OPTIONAL)
00025 {
00026   if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
00027   {
00028     PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
00029     if(Owner != NULL)
00030     {
00031       *Owner = ((RelSD->Owner != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Owner) : NULL);
00032     }
00033     if(Group != NULL)
00034     {
00035       *Group = ((RelSD->Group != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Group) : NULL);
00036     }
00037     if(Sacl != NULL)
00038     {
00039       *Sacl = (((RelSD->Control & SE_SACL_PRESENT) && (RelSD->Sacl != 0)) ?
00040               (PSID)((ULONG_PTR)RelSD + RelSD->Sacl) : NULL);
00041     }
00042     if(Dacl != NULL)
00043     {
00044       *Dacl = (((RelSD->Control & SE_DACL_PRESENT) && (RelSD->Dacl != 0)) ?
00045               (PSID)((ULONG_PTR)RelSD + RelSD->Dacl) : NULL);
00046     }
00047   }
00048   else
00049   {
00050     if(Owner != NULL)
00051     {
00052       *Owner = SecurityDescriptor->Owner;
00053     }
00054     if(Group != NULL)
00055     {
00056       *Group = SecurityDescriptor->Group;
00057     }
00058     if(Sacl != NULL)
00059     {
00060       *Sacl = ((SecurityDescriptor->Control & SE_SACL_PRESENT) ? SecurityDescriptor->Sacl : NULL);
00061     }
00062     if(Dacl != NULL)
00063     {
00064       *Dacl = ((SecurityDescriptor->Control & SE_DACL_PRESENT) ? SecurityDescriptor->Dacl : NULL);
00065     }
00066   }
00067 }
00068 
00069 static VOID
00070 RtlpQuerySecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
00071                             PSID* Owner,
00072                             PULONG OwnerLength,
00073                             PSID* Group,
00074                             PULONG GroupLength,
00075                             PACL* Dacl,
00076                             PULONG DaclLength,
00077                             PACL* Sacl,
00078                             PULONG SaclLength)
00079 {
00080    RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
00081                                        Owner,
00082                                        Group,
00083                                        Sacl,
00084                                        Dacl);
00085 
00086    if (Owner != NULL)
00087    {
00088       *OwnerLength = ((*Owner != NULL) ? ROUND_UP(RtlLengthSid(*Owner), 4) : 0);
00089    }
00090 
00091    if (Group != NULL)
00092    {
00093       *GroupLength = ((*Group != NULL) ? ROUND_UP(RtlLengthSid(*Group), 4) : 0);
00094    }
00095 
00096    if (Dacl != NULL)
00097    {
00098       *DaclLength = ((*Dacl != NULL) ? ROUND_UP((*Dacl)->AclSize, 4) : 0);
00099    }
00100 
00101    if (Sacl != NULL)
00102    {
00103       *SaclLength = ((*Sacl != NULL) ? ROUND_UP((*Sacl)->AclSize, 4) : 0);
00104    }
00105 }
00106 
00107 /*
00108  * @implemented
00109  */
00110 NTSTATUS NTAPI
00111 RtlCreateSecurityDescriptor(OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00112                             IN ULONG Revision)
00113 {
00114    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00115 
00116    PAGED_CODE_RTL();
00117 
00118    if (Revision != SECURITY_DESCRIPTOR_REVISION1)
00119    {
00120       return STATUS_UNKNOWN_REVISION;
00121    }
00122 
00123    pSD->Revision = SECURITY_DESCRIPTOR_REVISION1;
00124    pSD->Sbz1 = 0;
00125    pSD->Control = 0;
00126    pSD->Owner = NULL;
00127    pSD->Group = NULL;
00128    pSD->Sacl = NULL;
00129    pSD->Dacl = NULL;
00130 
00131    return STATUS_SUCCESS;
00132 }
00133 
00134 /*
00135  * @implemented
00136  */
00137 NTSTATUS NTAPI
00138 RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor,
00139                           OUT PSECURITY_DESCRIPTOR pDestinationSecurityDescriptor)
00140 {
00141   PSID Owner = NULL, Group = NULL;
00142   PACL Dacl = NULL, Sacl = NULL;
00143   BOOLEAN Defaulted, Present;
00144   DWORD OwnerLength, GroupLength;
00145   PISECURITY_DESCRIPTOR srcSD = pSourceSecurityDescriptor;
00146   PISECURITY_DESCRIPTOR destSD = pDestinationSecurityDescriptor;
00147 
00148   if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION)
00149     return STATUS_UNKNOWN_REVISION;
00150 
00151   /* Copy non relative dependent data */
00152   destSD->Revision = srcSD->Revision;
00153   destSD->Sbz1 = srcSD->Sbz1;
00154   destSD->Control = srcSD->Control;
00155 
00156   /* Read relative data */
00157   RtlGetOwnerSecurityDescriptor(srcSD, &Owner, &Defaulted);
00158   OwnerLength = RtlLengthSid(Owner);
00159   RtlGetGroupSecurityDescriptor(srcSD, &Group, &Defaulted);
00160   GroupLength = RtlLengthSid(Group);
00161   RtlGetDaclSecurityDescriptor(srcSD, &Present, &Dacl, &Defaulted);
00162   RtlGetSaclSecurityDescriptor(srcSD, &Present, &Sacl, &Defaulted);
00163 
00164   if (srcSD->Control & SE_SELF_RELATIVE)
00165   {
00166     destSD->Owner = srcSD->Owner;
00167     RtlCopySid(OwnerLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Owner, Owner);
00168 
00169     destSD->Group = srcSD->Group;
00170     RtlCopySid(GroupLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Group, Group);
00171 
00172     if (srcSD->Control & SE_DACL_PRESENT)
00173     {
00174       destSD->Dacl = srcSD->Dacl;
00175 
00176       if(srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl))
00177       {
00178         RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Dacl), Dacl, Dacl->AclSize);
00179       }
00180     }
00181 
00182     if (srcSD->Control & SE_SACL_PRESENT)
00183     {
00184       destSD->Sacl = srcSD->Sacl;
00185 
00186       if(srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl))
00187       {
00188         RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Sacl), Sacl, Sacl->AclSize);
00189       }
00190     }
00191   }
00192   else
00193   {
00194     RtlCopySid(OwnerLength, destSD->Owner, Owner);
00195     RtlCopySid(GroupLength, destSD->Group, Group);
00196 
00197     if (srcSD->Control & SE_DACL_PRESENT)
00198     {
00199       destSD->Dacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Dacl->AclSize);
00200 
00201       if(srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl))
00202       {
00203         RtlCopyMemory(destSD->Dacl, Dacl, Dacl->AclSize);
00204       }
00205     }
00206 
00207     if (srcSD->Control & SE_SACL_PRESENT)
00208     {
00209       destSD->Sacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Sacl->AclSize);
00210 
00211       if(srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl))
00212       {
00213         RtlCopyMemory(destSD->Sacl, Sacl, Sacl->AclSize);
00214       }
00215     }
00216   }
00217 
00218   return STATUS_SUCCESS;
00219 }
00220 
00221 
00222 NTSTATUS NTAPI
00223 RtlCreateSecurityDescriptorRelative (OUT PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
00224                          IN ULONG Revision)
00225 {
00226    PAGED_CODE_RTL();
00227 
00228    if (Revision != SECURITY_DESCRIPTOR_REVISION1)
00229    {
00230       return STATUS_UNKNOWN_REVISION;
00231    }
00232 
00233    SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION1;
00234    SecurityDescriptor->Sbz1 = 0;
00235    SecurityDescriptor->Control = SE_SELF_RELATIVE;
00236    SecurityDescriptor->Owner = 0;
00237    SecurityDescriptor->Group = 0;
00238    SecurityDescriptor->Sacl = 0;
00239    SecurityDescriptor->Dacl = 0;
00240 
00241    return STATUS_SUCCESS;
00242 }
00243 
00244 
00245 /*
00246  * @implemented
00247  */
00248 ULONG NTAPI
00249 RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
00250 {
00251    PSID Owner, Group;
00252    PACL Sacl, Dacl;
00253    ULONG Length;
00254 
00255    PAGED_CODE_RTL();
00256 
00257    if (((PISECURITY_DESCRIPTOR)SecurityDescriptor)->Control & SE_SELF_RELATIVE)
00258       Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00259    else
00260       Length = sizeof(SECURITY_DESCRIPTOR);
00261 
00262    RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)SecurityDescriptor,
00263                                        &Owner,
00264                                        &Group,
00265                                        &Sacl,
00266                                        &Dacl);
00267 
00268    if (Owner != NULL)
00269    {
00270       Length += ROUND_UP(RtlLengthSid(Owner), 4);
00271    }
00272 
00273    if (Group != NULL)
00274    {
00275       Length += ROUND_UP(RtlLengthSid(Group), 4);
00276    }
00277 
00278    if (Dacl != NULL)
00279    {
00280       Length += ROUND_UP(Dacl->AclSize, 4);
00281    }
00282 
00283    if (Sacl != NULL)
00284    {
00285       Length += ROUND_UP(Sacl->AclSize, 4);
00286    }
00287 
00288    return Length;
00289 }
00290 
00291 
00292 /*
00293  * @implemented
00294  */
00295 NTSTATUS NTAPI
00296 RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00297                              OUT PBOOLEAN DaclPresent,
00298                              OUT PACL* Dacl,
00299                              OUT PBOOLEAN DaclDefaulted)
00300 {
00301    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00302 
00303    PAGED_CODE_RTL();
00304 
00305    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00306    {
00307       return STATUS_UNKNOWN_REVISION;
00308    }
00309 
00310    if (!(pSD->Control & SE_DACL_PRESENT))
00311    {
00312       *DaclPresent = FALSE;
00313       return STATUS_SUCCESS;
00314    }
00315    *DaclPresent = TRUE;
00316 
00317    RtlpQuerySecurityDescriptorPointers(pSD,
00318                                        NULL,
00319                                        NULL,
00320                                        NULL,
00321                                        Dacl);
00322 
00323    *DaclDefaulted = ((pSD->Control & SE_DACL_DEFAULTED) ? TRUE : FALSE);
00324 
00325    return STATUS_SUCCESS;
00326 }
00327 
00328 
00329 /*
00330  * @implemented
00331  */
00332 NTSTATUS NTAPI
00333 RtlSetDaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00334                              IN BOOLEAN DaclPresent,
00335                              IN PACL Dacl,
00336                              IN BOOLEAN DaclDefaulted)
00337 {
00338    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00339 
00340    PAGED_CODE_RTL();
00341 
00342    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00343    {
00344       return STATUS_UNKNOWN_REVISION;
00345    }
00346 
00347    if (pSD->Control & SE_SELF_RELATIVE)
00348    {
00349       return STATUS_BAD_DESCRIPTOR_FORMAT;
00350    }
00351 
00352    if (!DaclPresent)
00353    {
00354       pSD->Control = pSD->Control & ~(SE_DACL_PRESENT);
00355       return STATUS_SUCCESS;
00356    }
00357 
00358    pSD->Dacl = Dacl;
00359    pSD->Control |= SE_DACL_PRESENT;
00360    pSD->Control &= ~(SE_DACL_DEFAULTED);
00361 
00362    if (DaclDefaulted)
00363    {
00364       pSD->Control |= SE_DACL_DEFAULTED;
00365    }
00366 
00367    return STATUS_SUCCESS;
00368 }
00369 
00370 
00371 /*
00372  * @implemented
00373  */
00374 BOOLEAN NTAPI
00375 RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
00376 {
00377    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00378    PSID Owner, Group;
00379    PACL Sacl, Dacl;
00380 
00381    PAGED_CODE_RTL();
00382 
00383    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00384    {
00385       return FALSE;
00386    }
00387 
00388    RtlpQuerySecurityDescriptorPointers(pSD,
00389                                        &Owner,
00390                                        &Group,
00391                                        &Sacl,
00392                                        &Dacl);
00393 
00394    if ((Owner != NULL && !RtlValidSid(Owner)) ||
00395        (Group != NULL && !RtlValidSid(Group)) ||
00396        (Sacl != NULL && !RtlValidAcl(Sacl)) ||
00397        (Dacl != NULL && !RtlValidAcl(Dacl)))
00398    {
00399       return FALSE;
00400    }
00401 
00402    return TRUE;
00403 }
00404 
00405 
00406 /*
00407  * @implemented
00408  */
00409 NTSTATUS NTAPI
00410 RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00411                               IN PSID Owner,
00412                               IN BOOLEAN OwnerDefaulted)
00413 {
00414    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00415 
00416    PAGED_CODE_RTL();
00417 
00418    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00419    {
00420       return STATUS_UNKNOWN_REVISION;
00421    }
00422 
00423    if (pSD->Control & SE_SELF_RELATIVE)
00424    {
00425       return STATUS_BAD_DESCRIPTOR_FORMAT;
00426    }
00427 
00428    pSD->Owner = Owner;
00429    pSD->Control &= ~(SE_OWNER_DEFAULTED);
00430 
00431    if (OwnerDefaulted)
00432    {
00433       pSD->Control |= SE_OWNER_DEFAULTED;
00434    }
00435 
00436    return STATUS_SUCCESS;
00437 }
00438 
00439 
00440 /*
00441  * @implemented
00442  */
00443 NTSTATUS NTAPI
00444 RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00445                               OUT PSID* Owner,
00446                               OUT PBOOLEAN OwnerDefaulted)
00447 {
00448    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00449 
00450    PAGED_CODE_RTL();
00451 
00452    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00453    {
00454       return STATUS_UNKNOWN_REVISION;
00455    }
00456 
00457    RtlpQuerySecurityDescriptorPointers(pSD,
00458                                        Owner,
00459                                        NULL,
00460                                        NULL,
00461                                        NULL);
00462 
00463    *OwnerDefaulted = ((pSD->Control & SE_OWNER_DEFAULTED) ? TRUE : FALSE);
00464 
00465    return STATUS_SUCCESS;
00466 }
00467 
00468 
00469 /*
00470  * @implemented
00471  */
00472 NTSTATUS NTAPI
00473 RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00474                               IN PSID Group,
00475                               IN BOOLEAN GroupDefaulted)
00476 {
00477    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00478 
00479    PAGED_CODE_RTL();
00480 
00481    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00482    {
00483       return STATUS_UNKNOWN_REVISION;
00484    }
00485 
00486    if (pSD->Control & SE_SELF_RELATIVE)
00487    {
00488       return STATUS_BAD_DESCRIPTOR_FORMAT;
00489    }
00490 
00491    pSD->Group = Group;
00492    pSD->Control &= ~(SE_GROUP_DEFAULTED);
00493    if (GroupDefaulted)
00494    {
00495       pSD->Control |= SE_GROUP_DEFAULTED;
00496    }
00497 
00498    return STATUS_SUCCESS;
00499 }
00500 
00501 
00502 /*
00503  * @implemented
00504  */
00505 NTSTATUS NTAPI
00506 RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00507                               OUT PSID* Group,
00508                               OUT PBOOLEAN GroupDefaulted)
00509 {
00510    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00511 
00512    PAGED_CODE_RTL();
00513 
00514    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00515    {
00516       return STATUS_UNKNOWN_REVISION;
00517    }
00518 
00519    RtlpQuerySecurityDescriptorPointers(pSD,
00520                                        NULL,
00521                                        Group,
00522                                        NULL,
00523                                        NULL);
00524 
00525    *GroupDefaulted = ((pSD->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE);
00526 
00527    return STATUS_SUCCESS;
00528 }
00529 
00530 
00531 /*
00532  * @implemented
00533  */
00534 NTSTATUS NTAPI
00535 RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD,
00536               OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
00537               IN OUT PULONG BufferLength)
00538 {
00539    PSID Owner;
00540    PSID Group;
00541    PACL Sacl;
00542    PACL Dacl;
00543    ULONG OwnerLength;
00544    ULONG GroupLength;
00545    ULONG SaclLength;
00546    ULONG DaclLength;
00547    ULONG TotalLength;
00548    ULONG_PTR Current;
00549    PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD;
00550    PISECURITY_DESCRIPTOR_RELATIVE pRelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
00551 
00552    PAGED_CODE_RTL();
00553 
00554    RtlpQuerySecurityDescriptor(pAbsSD,
00555                                &Owner,
00556                                &OwnerLength,
00557                                &Group,
00558                                &GroupLength,
00559                                &Dacl,
00560                                &DaclLength,
00561                                &Sacl,
00562                                &SaclLength);
00563 
00564    TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength;
00565    if (*BufferLength < TotalLength)
00566    {
00567       *BufferLength = TotalLength;
00568       return STATUS_BUFFER_TOO_SMALL;
00569    }
00570 
00571    RtlZeroMemory(pRelSD,
00572                  TotalLength);
00573 
00574    pRelSD->Revision = pAbsSD->Revision;
00575    pRelSD->Sbz1 = pAbsSD->Sbz1;
00576    pRelSD->Control = pAbsSD->Control | SE_SELF_RELATIVE;
00577 
00578    Current = (ULONG_PTR)(pRelSD + 1);
00579 
00580    if (SaclLength != 0)
00581    {
00582       RtlCopyMemory((PVOID)Current,
00583                     Sacl,
00584                     SaclLength);
00585       pRelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
00586       Current += SaclLength;
00587    }
00588 
00589    if (DaclLength != 0)
00590    {
00591       RtlCopyMemory((PVOID)Current,
00592                     Dacl,
00593                     DaclLength);
00594       pRelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
00595       Current += DaclLength;
00596    }
00597 
00598    if (OwnerLength != 0)
00599    {
00600       RtlCopyMemory((PVOID)Current,
00601                     Owner,
00602                     OwnerLength);
00603       pRelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
00604       Current += OwnerLength;
00605    }
00606 
00607    if (GroupLength != 0)
00608    {
00609       RtlCopyMemory((PVOID)Current,
00610                     Group,
00611                     GroupLength);
00612       pRelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
00613    }
00614 
00615    return STATUS_SUCCESS;
00616 }
00617 
00618 
00619 /*
00620  * @implemented
00621  */
00622 NTSTATUS NTAPI
00623 RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
00624                             IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
00625                             IN PULONG BufferLength)
00626 {
00627    PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor;
00628 
00629    PAGED_CODE_RTL();
00630 
00631    if (pAbsSD->Control & SE_SELF_RELATIVE)
00632    {
00633       return STATUS_BAD_DESCRIPTOR_FORMAT;
00634    }
00635 
00636    return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
00637                                 SelfRelativeSecurityDescriptor,
00638                                 BufferLength);
00639 }
00640 
00641 
00642 /*
00643  * @implemented
00644  */
00645 NTSTATUS NTAPI
00646 RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00647                                 OUT PSECURITY_DESCRIPTOR_CONTROL Control,
00648                                 OUT PULONG Revision)
00649 {
00650    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00651 
00652    PAGED_CODE_RTL();
00653 
00654    *Revision = pSD->Revision;
00655 
00656    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00657    {
00658       return STATUS_UNKNOWN_REVISION;
00659    }
00660 
00661    *Control = pSD->Control;
00662 
00663    return STATUS_SUCCESS;
00664 }
00665 
00666 
00667 /*
00668  * @implemented
00669  */
00670 NTSTATUS NTAPI
00671 RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00672                                 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
00673                                 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
00674 {
00675    SECURITY_DESCRIPTOR_CONTROL const immutable
00676        = SE_OWNER_DEFAULTED  | SE_GROUP_DEFAULTED
00677        | SE_DACL_PRESENT     | SE_DACL_DEFAULTED
00678        | SE_SACL_PRESENT     | SE_SACL_DEFAULTED
00679        | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
00680        ;
00681 
00682    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00683 
00684    PAGED_CODE_RTL();
00685 
00686    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00687    {
00688       return STATUS_UNKNOWN_REVISION;
00689    }
00690 
00691    if ((ControlBitsOfInterest | ControlBitsToSet) & immutable)
00692       return STATUS_INVALID_PARAMETER;
00693 
00694    /* Zero the 'bits of interest' */
00695    pSD->Control &= ~ControlBitsOfInterest;
00696 
00697    /* Set the 'bits to set' */
00698    pSD->Control |= (ControlBitsToSet & ControlBitsOfInterest);
00699 
00700    return STATUS_SUCCESS;
00701 }
00702 
00703 
00704 /*
00705  * @implemented
00706  */
00707 NTSTATUS NTAPI
00708 RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
00709                              OUT PBOOLEAN SaclPresent,
00710                              OUT PACL *Sacl,
00711                              OUT PBOOLEAN SaclDefaulted)
00712 {
00713    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00714 
00715    PAGED_CODE_RTL();
00716 
00717    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00718    {
00719       return STATUS_UNKNOWN_REVISION;
00720    }
00721 
00722    if (!(pSD->Control & SE_SACL_PRESENT))
00723    {
00724       *SaclPresent = FALSE;
00725       return STATUS_SUCCESS;
00726    }
00727    *SaclPresent = TRUE;
00728 
00729    RtlpQuerySecurityDescriptorPointers(pSD,
00730                                        NULL,
00731                                        NULL,
00732                                        Sacl,
00733                                        NULL);
00734 
00735    *SaclDefaulted = ((pSD->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE);
00736 
00737    return STATUS_SUCCESS;
00738 }
00739 
00740 
00741 /*
00742  * @implemented
00743  */
00744 NTSTATUS NTAPI
00745 RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00746                              IN BOOLEAN SaclPresent,
00747                              IN PACL Sacl,
00748                              IN BOOLEAN SaclDefaulted)
00749 {
00750    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
00751 
00752    PAGED_CODE_RTL();
00753 
00754    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00755    {
00756       return STATUS_UNKNOWN_REVISION;
00757    }
00758 
00759    if (pSD->Control & SE_SELF_RELATIVE)
00760    {
00761       return STATUS_BAD_DESCRIPTOR_FORMAT;
00762    }
00763 
00764    if (!SaclPresent)
00765    {
00766       pSD->Control &= ~(SE_SACL_PRESENT);
00767       return STATUS_SUCCESS;
00768    }
00769 
00770    pSD->Sacl = Sacl;
00771    pSD->Control |= SE_SACL_PRESENT;
00772    pSD->Control &= ~(SE_SACL_DEFAULTED);
00773 
00774    if (SaclDefaulted)
00775    {
00776       pSD->Control |= SE_SACL_DEFAULTED;
00777    }
00778 
00779    return STATUS_SUCCESS;
00780 }
00781 
00782 
00783 /*
00784  * @implemented
00785  */
00786 NTSTATUS NTAPI
00787 RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD,
00788                             OUT PSECURITY_DESCRIPTOR AbsoluteSD,
00789                             IN PULONG AbsoluteSDSize,
00790                             IN PACL Dacl,
00791                             IN PULONG DaclSize,
00792                             IN PACL Sacl,
00793                             IN PULONG SaclSize,
00794                             IN PSID Owner,
00795                             IN PULONG OwnerSize,
00796                             IN PSID PrimaryGroup,
00797                             IN PULONG PrimaryGroupSize)
00798 {
00799    PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD;
00800    PISECURITY_DESCRIPTOR pRelSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
00801    ULONG OwnerLength;
00802    ULONG GroupLength;
00803    ULONG DaclLength;
00804    ULONG SaclLength;
00805    PSID pOwner;
00806    PSID pGroup;
00807    PACL pDacl;
00808    PACL pSacl;
00809 
00810    PAGED_CODE_RTL();
00811 
00812    if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00813    {
00814       return STATUS_UNKNOWN_REVISION;
00815    }
00816 
00817    if (!(pRelSD->Control & SE_SELF_RELATIVE))
00818    {
00819       return STATUS_BAD_DESCRIPTOR_FORMAT;
00820    }
00821 
00822    RtlpQuerySecurityDescriptor (pRelSD,
00823                                 &pOwner,
00824                                 &OwnerLength,
00825                                 &pGroup,
00826                                 &GroupLength,
00827                                 &pDacl,
00828                                 &DaclLength,
00829                                 &pSacl,
00830                                 &SaclLength);
00831 
00832    if (OwnerLength > *OwnerSize ||
00833        GroupLength > *PrimaryGroupSize ||
00834        DaclLength > *DaclSize ||
00835        SaclLength > *SaclSize)
00836    {
00837       *OwnerSize = OwnerLength;
00838       *PrimaryGroupSize = GroupLength;
00839       *DaclSize = DaclLength;
00840       *SaclSize = SaclLength;
00841       return STATUS_BUFFER_TOO_SMALL;
00842    }
00843 
00844    RtlCopyMemory (Owner, pOwner, OwnerLength);
00845    RtlCopyMemory (PrimaryGroup, pGroup, GroupLength);
00846    RtlCopyMemory (Dacl, pDacl, DaclLength);
00847    RtlCopyMemory (Sacl, pSacl, SaclLength);
00848 
00849    pAbsSD->Revision = pRelSD->Revision;
00850    pAbsSD->Sbz1 = pRelSD->Sbz1;
00851    pAbsSD->Control = pRelSD->Control & ~SE_SELF_RELATIVE;
00852    pAbsSD->Owner = Owner;
00853    pAbsSD->Group = PrimaryGroup;
00854    pAbsSD->Dacl = Dacl;
00855    pAbsSD->Sacl = Sacl;
00856 
00857    *OwnerSize = OwnerLength;
00858    *PrimaryGroupSize = GroupLength;
00859    *DaclSize = DaclLength;
00860    *SaclSize = SaclLength;
00861 
00862    return STATUS_SUCCESS;
00863 }
00864 
00865 
00866 /*
00867  * @implemented
00868  */
00869 NTSTATUS NTAPI
00870 RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
00871                              OUT PULONG BufferSize)
00872 {
00873     PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
00874     PISECURITY_DESCRIPTOR_RELATIVE pRelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
00875 #ifdef _WIN64
00876     PVOID DataStart, DataEnd;
00877     ULONG DataSize;
00878     LONG MoveDelta;
00879     ULONG OwnerLength;
00880     ULONG GroupLength;
00881     ULONG DaclLength;
00882     ULONG SaclLength;
00883 #endif
00884     PSID pOwner;
00885     PSID pGroup;
00886     PACL pDacl;
00887     PACL pSacl;
00888 
00889     PAGED_CODE_RTL();
00890 
00891     if (SelfRelativeSD == NULL)
00892     {
00893         return STATUS_INVALID_PARAMETER_1;
00894     }
00895     if (BufferSize == NULL)
00896     {
00897         return STATUS_INVALID_PARAMETER_2;
00898     }
00899 
00900     if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
00901     {
00902         return STATUS_UNKNOWN_REVISION;
00903     }
00904     if (!(pRelSD->Control & SE_SELF_RELATIVE))
00905     {
00906         return STATUS_BAD_DESCRIPTOR_FORMAT;
00907     }
00908 
00909 #ifdef _WIN64
00910 
00911     RtlpQuerySecurityDescriptor((PISECURITY_DESCRIPTOR)pRelSD,
00912                                 &pOwner,
00913                                 &OwnerLength,
00914                                 &pGroup,
00915                                 &GroupLength,
00916                                 &pDacl,
00917                                 &DaclLength,
00918                                 &pSacl,
00919                                 &SaclLength);
00920 
00921     /* calculate the start and end of the data area, we simply just move the
00922        data by the difference between the size of the relative and absolute
00923        security descriptor structure */
00924     DataStart = pOwner;
00925     DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
00926     if (pGroup != NULL)
00927     {
00928         if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || DataStart == NULL)
00929             DataStart = pGroup;
00930         if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
00931             DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
00932     }
00933     if (pDacl != NULL)
00934     {
00935         if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || DataStart == NULL)
00936             DataStart = pDacl;
00937         if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
00938             DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
00939     }
00940     if (pSacl != NULL)
00941     {
00942         if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || DataStart == NULL)
00943             DataStart = pSacl;
00944         if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
00945             DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
00946     }
00947 
00948     ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
00949 
00950     DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
00951 
00952     if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
00953     {
00954         *BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
00955         return STATUS_BUFFER_TOO_SMALL;
00956     }
00957 
00958     if (DataSize != 0)
00959     {
00960         /* if DataSize != 0 ther must be at least one SID or ACL in the security
00961            descriptor! Also the data area must be located somewhere after the
00962            end of the SECURITY_DESCRIPTOR_RELATIVE structure */
00963         ASSERT(DataStart != NULL);
00964         ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(pRelSD + 1));
00965 
00966         /* it's time to move the data */
00967         RtlMoveMemory((PVOID)(pAbsSD + 1),
00968                       DataStart,
00969                       DataSize);
00970 
00971         MoveDelta = (LONG)((LONG_PTR)(pAbsSD + 1) - (LONG_PTR)DataStart);
00972 
00973         /* adjust the pointers if neccessary */
00974         if (pOwner != NULL)
00975             pAbsSD->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
00976         else
00977             pAbsSD->Owner = NULL;
00978 
00979         if (pGroup != NULL)
00980             pAbsSD->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
00981         else
00982             pAbsSD->Group = NULL;
00983 
00984         if (pSacl != NULL)
00985             pAbsSD->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
00986         else
00987             pAbsSD->Sacl = NULL;
00988 
00989         if (pDacl != NULL)
00990             pAbsSD->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
00991         else
00992             pAbsSD->Dacl = NULL;
00993     }
00994     else
00995     {
00996         /* all pointers must be NULL! */
00997         ASSERT(pOwner == NULL);
00998         ASSERT(pGroup == NULL);
00999         ASSERT(pSacl == NULL);
01000         ASSERT(pDacl == NULL);
01001 
01002         pAbsSD->Owner = NULL;
01003         pAbsSD->Group = NULL;
01004         pAbsSD->Sacl = NULL;
01005         pAbsSD->Dacl = NULL;
01006     }
01007 
01008     /* clear the self-relative flag */
01009     pAbsSD->Control &= ~SE_SELF_RELATIVE;
01010 
01011 #else
01012 
01013     RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)pRelSD,
01014                                         &pOwner,
01015                                         &pGroup,
01016                                         &pSacl,
01017                                         &pDacl);
01018 
01019     /* clear the self-relative flag and simply convert the offsets to pointers */
01020     pAbsSD->Control &= ~SE_SELF_RELATIVE;
01021     pAbsSD->Owner = pOwner;
01022     pAbsSD->Group = pGroup;
01023     pAbsSD->Sacl = pSacl;
01024     pAbsSD->Dacl = pDacl;
01025 
01026 #endif
01027 
01028     return STATUS_SUCCESS;
01029 }
01030 
01031 
01032 /*
01033  * @implemented
01034  */
01035 BOOLEAN NTAPI
01036 RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
01037                                    IN ULONG SecurityDescriptorLength,
01038                                    IN SECURITY_INFORMATION RequiredInformation)
01039 {
01040    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptorInput;
01041 
01042    PAGED_CODE_RTL();
01043 
01044    if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
01045        pSD->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
01046        !(pSD->Control & SE_SELF_RELATIVE))
01047    {
01048       return FALSE;
01049    }
01050 
01051    if (pSD->Owner != 0)
01052    {
01053       PSID Owner = (PSID)((ULONG_PTR)pSD->Owner + (ULONG_PTR)pSD);
01054       if (!RtlValidSid(Owner))
01055       {
01056          return FALSE;
01057       }
01058    }
01059    else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
01060    {
01061       return FALSE;
01062    }
01063 
01064    if (pSD->Group != 0)
01065    {
01066       PSID Group = (PSID)((ULONG_PTR)pSD->Group + (ULONG_PTR)pSD);
01067       if (!RtlValidSid(Group))
01068       {
01069          return FALSE;
01070       }
01071    }
01072    else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
01073    {
01074       return FALSE;
01075    }
01076 
01077    if (pSD->Control & SE_DACL_PRESENT)
01078    {
01079       if (pSD->Dacl != 0 &&
01080           !RtlValidAcl((PACL)((ULONG_PTR)pSD->Dacl + (ULONG_PTR)pSD)))
01081       {
01082          return FALSE;
01083       }
01084    }
01085    else if (RequiredInformation & DACL_SECURITY_INFORMATION)
01086    {
01087       return FALSE;
01088    }
01089 
01090    if (pSD->Control & SE_SACL_PRESENT)
01091    {
01092       if (pSD->Sacl != 0 &&
01093           !RtlValidAcl((PACL)((ULONG_PTR)pSD->Sacl + (ULONG_PTR)pSD)))
01094       {
01095          return FALSE;
01096       }
01097    }
01098    else if (RequiredInformation & SACL_SECURITY_INFORMATION)
01099    {
01100       return FALSE;
01101    }
01102 
01103    return TRUE;
01104 }
01105 
01106 
01107 /*
01108  * @implemented
01109  */
01110 BOOLEAN NTAPI
01111 RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
01112                                   OUT PUCHAR RMControl)
01113 {
01114    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
01115 
01116    PAGED_CODE_RTL();
01117 
01118    if (!(pSD->Control & SE_RM_CONTROL_VALID))
01119    {
01120       *RMControl = 0;
01121       return FALSE;
01122    }
01123 
01124    *RMControl = pSD->Sbz1;
01125 
01126    return TRUE;
01127 }
01128 
01129 
01130 /*
01131  * @implemented
01132  */
01133 VOID NTAPI
01134 RtlSetSecurityDescriptorRMControl(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
01135                                   IN PUCHAR RMControl)
01136 {
01137    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
01138 
01139    PAGED_CODE_RTL();
01140 
01141    if (RMControl == NULL)
01142    {
01143       pSD->Control &= ~SE_RM_CONTROL_VALID;
01144       pSD->Sbz1 = 0;
01145    }
01146    else
01147    {
01148       pSD->Control |= SE_RM_CONTROL_VALID;
01149       pSD->Sbz1 = *RMControl;
01150    }
01151 }
01152 
01153 
01154 /*
01155  * @implemented
01156  */
01157 NTSTATUS NTAPI
01158 RtlSetAttributesSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
01159                                    IN SECURITY_DESCRIPTOR_CONTROL Control,
01160                                    OUT PULONG Revision)
01161 {
01162    PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
01163 
01164    PAGED_CODE_RTL();
01165 
01166    *Revision = pSD->Revision;
01167 
01168    if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
01169       return STATUS_UNKNOWN_REVISION;
01170 
01171    Control &=
01172       ~(SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED | SE_DACL_PRESENT |
01173         SE_DACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_DEFAULTED |
01174         SE_RM_CONTROL_VALID | SE_SELF_RELATIVE);
01175 
01176    return RtlSetControlSecurityDescriptor(SecurityDescriptor,
01177                                           Control,
01178                                           Control);
01179 }
01180 
01181 /* EOF */

Generated on Thu May 24 2012 04:36:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.