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 kernel
00004  * FILE:            ntoskrnl/se/sd.c
00005  * PURPOSE:         Security manager
00006  *
00007  * PROGRAMMERS:     David Welch <welch@cwcom.net>
00008  */
00009 
00010 /* INCLUDES *******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 #if defined (ALLOC_PRAGMA)
00017 #pragma alloc_text(INIT, SepInitSDs)
00018 #endif
00019 
00020 /* GLOBALS ********************************************************************/
00021 
00022 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
00023 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
00024 PSECURITY_DESCRIPTOR SePublicOpenSd = NULL;
00025 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
00026 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
00027 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
00028 
00029 /* PRIVATE FUNCTIONS **********************************************************/
00030 
00031 PSID
00032 FORCEINLINE
00033 SepGetGroupFromDescriptor(PVOID _Descriptor)
00034 {
00035     PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor;
00036     PISECURITY_DESCRIPTOR_RELATIVE SdRel;
00037 
00038     if (Descriptor->Control & SE_SELF_RELATIVE)
00039     {
00040         SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor;
00041         if (!SdRel->Group) return NULL;
00042         return (PSID)((ULONG_PTR)Descriptor + SdRel->Group);
00043     }
00044     else
00045     {
00046         return Descriptor->Group;
00047     }
00048 }
00049 
00050 PSID
00051 FORCEINLINE
00052 SepGetOwnerFromDescriptor(PVOID _Descriptor)
00053 {
00054     PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor;
00055     PISECURITY_DESCRIPTOR_RELATIVE SdRel;
00056 
00057     if (Descriptor->Control & SE_SELF_RELATIVE)
00058     {
00059         SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor;
00060         if (!SdRel->Owner) return NULL;
00061         return (PSID)((ULONG_PTR)Descriptor + SdRel->Owner);
00062     }
00063     else
00064     {
00065         return Descriptor->Owner;
00066     }
00067 }
00068 
00069 PACL
00070 FORCEINLINE
00071 SepGetDaclFromDescriptor(PVOID _Descriptor)
00072 {
00073     PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor;
00074     PISECURITY_DESCRIPTOR_RELATIVE SdRel;
00075 
00076     if (Descriptor->Control & SE_SELF_RELATIVE)
00077     {
00078         SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor;
00079         if (!SdRel->Dacl) return NULL;
00080         return (PACL)((ULONG_PTR)Descriptor + SdRel->Dacl);
00081     }
00082     else
00083     {
00084         return Descriptor->Dacl;
00085     }
00086 }
00087 
00088 PACL
00089 FORCEINLINE
00090 SepGetSaclFromDescriptor(PVOID _Descriptor)
00091 {
00092     PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor;
00093     PISECURITY_DESCRIPTOR_RELATIVE SdRel;
00094 
00095     if (Descriptor->Control & SE_SELF_RELATIVE)
00096     {
00097         SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor;
00098         if (!SdRel->Sacl) return NULL;
00099         return (PACL)((ULONG_PTR)Descriptor + SdRel->Sacl);
00100     }
00101     else
00102     {
00103         return Descriptor->Sacl;
00104     }
00105 }
00106 
00107 BOOLEAN
00108 INIT_FUNCTION
00109 NTAPI
00110 SepInitSDs(VOID)
00111 {
00112     /* Create PublicDefaultSd */
00113     SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
00114                                               sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00115     if (SePublicDefaultSd == NULL)
00116         return FALSE;
00117 
00118     RtlCreateSecurityDescriptor(SePublicDefaultSd,
00119                                 SECURITY_DESCRIPTOR_REVISION);
00120     RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
00121                                  TRUE,
00122                                  SePublicDefaultDacl,
00123                                  FALSE);
00124 
00125     /* Create PublicDefaultUnrestrictedSd */
00126     SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
00127                                                           sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00128     if (SePublicDefaultUnrestrictedSd == NULL)
00129         return FALSE;
00130 
00131     RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
00132                                 SECURITY_DESCRIPTOR_REVISION);
00133     RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
00134                                  TRUE,
00135                                  SePublicDefaultUnrestrictedDacl,
00136                                  FALSE);
00137 
00138     /* Create PublicOpenSd */
00139     SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
00140                                            sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00141     if (SePublicOpenSd == NULL)
00142         return FALSE;
00143 
00144     RtlCreateSecurityDescriptor(SePublicOpenSd,
00145                                 SECURITY_DESCRIPTOR_REVISION);
00146     RtlSetDaclSecurityDescriptor(SePublicOpenSd,
00147                                  TRUE,
00148                                  SePublicOpenDacl,
00149                                  FALSE);
00150 
00151     /* Create PublicOpenUnrestrictedSd */
00152     SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
00153                                                        sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00154     if (SePublicOpenUnrestrictedSd == NULL)
00155         return FALSE;
00156 
00157     RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
00158                                 SECURITY_DESCRIPTOR_REVISION);
00159     RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
00160                                  TRUE,
00161                                  SePublicOpenUnrestrictedDacl,
00162                                  FALSE);
00163 
00164     /* Create SystemDefaultSd */
00165     SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
00166                                               sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00167     if (SeSystemDefaultSd == NULL)
00168         return FALSE;
00169 
00170     RtlCreateSecurityDescriptor(SeSystemDefaultSd,
00171                                 SECURITY_DESCRIPTOR_REVISION);
00172     RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
00173                                  TRUE,
00174                                  SeSystemDefaultDacl,
00175                                  FALSE);
00176 
00177     /* Create UnrestrictedSd */
00178     SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
00179                                              sizeof(SECURITY_DESCRIPTOR), TAG_SD);
00180     if (SeUnrestrictedSd == NULL)
00181         return FALSE;
00182 
00183     RtlCreateSecurityDescriptor(SeUnrestrictedSd,
00184                                 SECURITY_DESCRIPTOR_REVISION);
00185     RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
00186                                  TRUE,
00187                                  SeUnrestrictedDacl,
00188                                  FALSE);
00189 
00190     return TRUE;
00191 }
00192 
00193 NTSTATUS
00194 NTAPI
00195 SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
00196                              PISECURITY_DESCRIPTOR SecurityDescriptor,
00197                              PULONG BufferLength)
00198 {
00199     ULONG Current;
00200     ULONG SidSize;
00201     ULONG SdSize;
00202     NTSTATUS Status;
00203     PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
00204 
00205     DPRINT("SeSetWorldSecurityDescriptor() called\n");
00206 
00207     if (SecurityInformation == 0)
00208     {
00209         return STATUS_ACCESS_DENIED;
00210     }
00211 
00212     /* calculate the minimum size of the buffer */
00213     SidSize = RtlLengthSid(SeWorldSid);
00214     SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00215     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
00216         SdSize += SidSize;
00217     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
00218         SdSize += SidSize;
00219     if (SecurityInformation & DACL_SECURITY_INFORMATION)
00220     {
00221         SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
00222     }
00223 
00224     if (*BufferLength < SdSize)
00225     {
00226         *BufferLength = SdSize;
00227         return STATUS_BUFFER_TOO_SMALL;
00228     }
00229 
00230     *BufferLength = SdSize;
00231 
00232     Status = RtlCreateSecurityDescriptorRelative(SdRel,
00233                                                  SECURITY_DESCRIPTOR_REVISION);
00234     if (!NT_SUCCESS(Status))
00235     {
00236         return Status;
00237     }
00238 
00239     Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00240 
00241     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
00242     {
00243         RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
00244         SdRel->Owner = Current;
00245         Current += SidSize;
00246     }
00247 
00248     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
00249     {
00250         RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
00251         SdRel->Group = Current;
00252         Current += SidSize;
00253     }
00254 
00255     if (SecurityInformation & DACL_SECURITY_INFORMATION)
00256     {
00257         PACL Dacl = (PACL)((PUCHAR)SdRel + Current);
00258         SdRel->Control |= SE_DACL_PRESENT;
00259 
00260         Status = RtlCreateAcl(Dacl,
00261                               sizeof(ACL) + sizeof(ACE) + SidSize,
00262                               ACL_REVISION);
00263         if (!NT_SUCCESS(Status))
00264             return Status;
00265 
00266         Status = RtlAddAccessAllowedAce(Dacl,
00267                                         ACL_REVISION,
00268                                         GENERIC_ALL,
00269                                         SeWorldSid);
00270         if (!NT_SUCCESS(Status))
00271             return Status;
00272 
00273         SdRel->Dacl = Current;
00274     }
00275 
00276     if (SecurityInformation & SACL_SECURITY_INFORMATION)
00277     {
00278         /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
00279     }
00280 
00281     return STATUS_SUCCESS;
00282 }
00283 
00284 
00285 NTSTATUS
00286 NTAPI
00287 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
00288                                    IN KPROCESSOR_MODE AccessMode,
00289                                    IN POOL_TYPE PoolType,
00290                                    IN BOOLEAN CaptureIfKernel,
00291                                    OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
00292                                    OUT PBOOLEAN Present)
00293 {
00294     PSECURITY_QUALITY_OF_SERVICE CapturedQos;
00295     NTSTATUS Status = STATUS_SUCCESS;
00296 
00297     PAGED_CODE();
00298 
00299     ASSERT(CapturedSecurityQualityOfService);
00300     ASSERT(Present);
00301 
00302     if (ObjectAttributes != NULL)
00303     {
00304         if (AccessMode != KernelMode)
00305         {
00306             SECURITY_QUALITY_OF_SERVICE SafeQos;
00307 
00308             _SEH2_TRY
00309             {
00310                 ProbeForRead(ObjectAttributes,
00311                              sizeof(OBJECT_ATTRIBUTES),
00312                              sizeof(ULONG));
00313                 if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
00314                 {
00315                     if (ObjectAttributes->SecurityQualityOfService != NULL)
00316                     {
00317                         ProbeForRead(ObjectAttributes->SecurityQualityOfService,
00318                                      sizeof(SECURITY_QUALITY_OF_SERVICE),
00319                                      sizeof(ULONG));
00320 
00321                         if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
00322                             sizeof(SECURITY_QUALITY_OF_SERVICE))
00323                         {
00324                             /*
00325                              * Don't allocate memory here because ExAllocate should bugcheck
00326                              * the system if it's buggy, SEH would catch that! So make a local
00327                              * copy of the qos structure.
00328                              */
00329                             RtlCopyMemory(&SafeQos,
00330                                           ObjectAttributes->SecurityQualityOfService,
00331                                           sizeof(SECURITY_QUALITY_OF_SERVICE));
00332                             *Present = TRUE;
00333                         }
00334                         else
00335                         {
00336                             Status = STATUS_INVALID_PARAMETER;
00337                         }
00338                     }
00339                     else
00340                     {
00341                         *CapturedSecurityQualityOfService = NULL;
00342                         *Present = FALSE;
00343                     }
00344                 }
00345                 else
00346                 {
00347                     Status = STATUS_INVALID_PARAMETER;
00348                 }
00349             }
00350             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00351             {
00352                 Status = _SEH2_GetExceptionCode();
00353             }
00354             _SEH2_END;
00355 
00356             if (NT_SUCCESS(Status))
00357             {
00358                 if (*Present)
00359                 {
00360                     CapturedQos = ExAllocatePool(PoolType,
00361                                                  sizeof(SECURITY_QUALITY_OF_SERVICE));
00362                     if (CapturedQos != NULL)
00363                     {
00364                         RtlCopyMemory(CapturedQos,
00365                                       &SafeQos,
00366                                       sizeof(SECURITY_QUALITY_OF_SERVICE));
00367                         *CapturedSecurityQualityOfService = CapturedQos;
00368                     }
00369                     else
00370                     {
00371                         Status = STATUS_INSUFFICIENT_RESOURCES;
00372                     }
00373                 }
00374                 else
00375                 {
00376                     *CapturedSecurityQualityOfService = NULL;
00377                 }
00378             }
00379         }
00380         else
00381         {
00382             if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
00383             {
00384                 if (CaptureIfKernel)
00385                 {
00386                     if (ObjectAttributes->SecurityQualityOfService != NULL)
00387                     {
00388                         if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
00389                             sizeof(SECURITY_QUALITY_OF_SERVICE))
00390                         {
00391                             CapturedQos = ExAllocatePool(PoolType,
00392                                                          sizeof(SECURITY_QUALITY_OF_SERVICE));
00393                             if (CapturedQos != NULL)
00394                             {
00395                                 RtlCopyMemory(CapturedQos,
00396                                               ObjectAttributes->SecurityQualityOfService,
00397                                               sizeof(SECURITY_QUALITY_OF_SERVICE));
00398                                 *CapturedSecurityQualityOfService = CapturedQos;
00399                                 *Present = TRUE;
00400                             }
00401                             else
00402                             {
00403                                 Status = STATUS_INSUFFICIENT_RESOURCES;
00404                             }
00405                         }
00406                         else
00407                         {
00408                             Status = STATUS_INVALID_PARAMETER;
00409                         }
00410                     }
00411                     else
00412                     {
00413                         *CapturedSecurityQualityOfService = NULL;
00414                         *Present = FALSE;
00415                     }
00416                 }
00417                 else
00418                 {
00419                     *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
00420                     *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
00421                 }
00422             }
00423             else
00424             {
00425                 Status = STATUS_INVALID_PARAMETER;
00426             }
00427         }
00428     }
00429     else
00430     {
00431         *CapturedSecurityQualityOfService = NULL;
00432         *Present = FALSE;
00433     }
00434 
00435     return Status;
00436 }
00437 
00438 
00439 VOID
00440 NTAPI
00441 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService  OPTIONAL,
00442                                    IN KPROCESSOR_MODE AccessMode,
00443                                    IN BOOLEAN CaptureIfKernel)
00444 {
00445     PAGED_CODE();
00446 
00447     if (CapturedSecurityQualityOfService != NULL &&
00448         (AccessMode != KernelMode || CaptureIfKernel))
00449     {
00450         ExFreePool(CapturedSecurityQualityOfService);
00451     }
00452 }
00453 
00454 /* PUBLIC FUNCTIONS ***********************************************************/
00455 
00456 static
00457 ULONG
00458 DetermineSIDSize(
00459     PISID Sid,
00460     PULONG OutSAC,
00461     KPROCESSOR_MODE ProcessorMode)
00462 {
00463     ULONG Size;
00464 
00465     if (!Sid)
00466     {
00467         *OutSAC = 0;
00468         return 0;
00469     }
00470 
00471     if (ProcessorMode != KernelMode)
00472     {
00473         /* Securely access the buffers! */
00474         *OutSAC = ProbeForReadUchar(&Sid->SubAuthorityCount);
00475         Size = RtlLengthRequiredSid(*OutSAC);
00476         ProbeForRead(Sid, Size, sizeof(ULONG));
00477     }
00478     else
00479     {
00480         *OutSAC = Sid->SubAuthorityCount;
00481         Size = RtlLengthRequiredSid(*OutSAC);
00482     }
00483 
00484     return Size;
00485 }
00486 
00487 static
00488 ULONG
00489 DetermineACLSize(
00490     PACL Acl,
00491     KPROCESSOR_MODE ProcessorMode)
00492 {
00493     ULONG Size;
00494 
00495     if (!Acl) return 0;
00496 
00497     if (ProcessorMode == KernelMode) return Acl->AclSize;
00498 
00499     /* Probe the buffers! */
00500     Size = ProbeForReadUshort(&Acl->AclSize);
00501     ProbeForRead(Acl, Size, sizeof(ULONG));
00502 
00503     return Size;
00504 }
00505 
00506 NTSTATUS
00507 NTAPI
00508 SeCaptureSecurityDescriptor(
00509     IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
00510     IN KPROCESSOR_MODE CurrentMode,
00511     IN POOL_TYPE PoolType,
00512     IN BOOLEAN CaptureIfKernel,
00513     OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
00514 {
00515     PISECURITY_DESCRIPTOR OriginalDescriptor = _OriginalSecurityDescriptor;
00516     SECURITY_DESCRIPTOR DescriptorCopy;
00517     PISECURITY_DESCRIPTOR_RELATIVE NewDescriptor;
00518     ULONG OwnerSAC = 0, GroupSAC = 0;
00519     ULONG OwnerSize = 0, GroupSize = 0;
00520     ULONG SaclSize = 0, DaclSize = 0;
00521     ULONG DescriptorSize = 0;
00522     ULONG Offset;
00523 
00524     if (!OriginalDescriptor)
00525     {
00526         /* Nothing to do... */
00527         *CapturedSecurityDescriptor = NULL;
00528         return STATUS_SUCCESS;
00529     }
00530 
00531     /* Quick path */
00532     if (CurrentMode == KernelMode && !CaptureIfKernel)
00533     {
00534         /* Check descriptor version */
00535         if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
00536         {
00537             return STATUS_UNKNOWN_REVISION;
00538         }
00539 
00540         *CapturedSecurityDescriptor = _OriginalSecurityDescriptor;
00541         return STATUS_SUCCESS;
00542     }
00543 
00544     _SEH2_TRY
00545     {
00546         if (CurrentMode != KernelMode)
00547         {
00548             ProbeForRead(OriginalDescriptor,
00549                          sizeof(SECURITY_DESCRIPTOR_RELATIVE),
00550                          sizeof(ULONG));
00551         }
00552 
00553         /* Check the descriptor version */
00554         if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
00555         {
00556             _SEH2_YIELD(return STATUS_UNKNOWN_REVISION);
00557         }
00558 
00559         if (CurrentMode != KernelMode)
00560         {
00561             /* Get the size of the descriptor */
00562             DescriptorSize = (OriginalDescriptor->Control & SE_SELF_RELATIVE) ?
00563                 sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR);
00564 
00565             /* Probe the entire security descriptor structure. The SIDs
00566              * and ACLs will be probed and copied later though */
00567             ProbeForRead(OriginalDescriptor, DescriptorSize, sizeof(ULONG));
00568         }
00569 
00570         /* Now capture all fields and convert to an absolute descriptor */
00571         DescriptorCopy.Revision = OriginalDescriptor->Revision;
00572         DescriptorCopy.Sbz1 = OriginalDescriptor->Sbz1;
00573         DescriptorCopy.Control = OriginalDescriptor->Control & ~SE_SELF_RELATIVE;
00574         DescriptorCopy.Owner = SepGetOwnerFromDescriptor(OriginalDescriptor);
00575         DescriptorCopy.Group = SepGetGroupFromDescriptor(OriginalDescriptor);
00576         DescriptorCopy.Sacl = SepGetSaclFromDescriptor(OriginalDescriptor);
00577         DescriptorCopy.Dacl = SepGetDaclFromDescriptor(OriginalDescriptor);
00578         DescriptorSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00579 
00580         /* Determine owner and group sizes */
00581         OwnerSize = DetermineSIDSize(DescriptorCopy.Owner, &OwnerSAC, CurrentMode);
00582         DescriptorSize += ROUND_UP(OwnerSize, sizeof(ULONG));
00583         GroupSize = DetermineSIDSize(DescriptorCopy.Group, &GroupSAC, CurrentMode);
00584         DescriptorSize += ROUND_UP(GroupSize, sizeof(ULONG));
00585 
00586         /* Determine the size of the ACLs */
00587         if (DescriptorCopy.Control & SE_SACL_PRESENT)
00588         {
00589             /* Get the size and probe if user mode */
00590             SaclSize = DetermineACLSize(DescriptorCopy.Sacl, CurrentMode);
00591             DescriptorSize += ROUND_UP(SaclSize, sizeof(ULONG));
00592         }
00593 
00594         if (DescriptorCopy.Control & SE_DACL_PRESENT)
00595         {
00596             /* Get the size and probe if user mode */
00597             DaclSize = DetermineACLSize(DescriptorCopy.Dacl, CurrentMode);
00598             DescriptorSize += ROUND_UP(DaclSize, sizeof(ULONG));
00599         }
00600     }
00601     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00602     {
00603         _SEH2_YIELD(return _SEH2_GetExceptionCode());
00604     }
00605     _SEH2_END
00606 
00607     /*
00608      * Allocate enough memory to store a complete copy of a self-relative
00609      * security descriptor
00610      */
00611     NewDescriptor = ExAllocatePoolWithTag(PoolType,
00612                                           DescriptorSize,
00613                                           TAG_SD);
00614     if (!NewDescriptor) return STATUS_INSUFFICIENT_RESOURCES;
00615 
00616     RtlZeroMemory(NewDescriptor, DescriptorSize);
00617     NewDescriptor->Revision = DescriptorCopy.Revision;
00618     NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
00619     NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
00620 
00621     _SEH2_TRY
00622     {
00623         /*
00624          * Setup the offsets and copy the SIDs and ACLs to the new
00625          * self-relative security descriptor. Probing the pointers is not
00626          * neccessary anymore as we did that when collecting the sizes!
00627          * Make sure to validate the SIDs and ACLs *again* as they could have
00628          * been modified in the meanwhile!
00629          */
00630         Offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00631 
00632         if (DescriptorCopy.Owner)
00633         {
00634             if (!RtlValidSid(DescriptorCopy.Owner)) RtlRaiseStatus(STATUS_INVALID_SID);
00635             NewDescriptor->Owner = Offset;
00636             RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
00637                           DescriptorCopy.Owner,
00638                           OwnerSize);
00639             Offset += ROUND_UP(OwnerSize, sizeof(ULONG));
00640         }
00641 
00642         if (DescriptorCopy.Group)
00643         {
00644             if (!RtlValidSid(DescriptorCopy.Group)) RtlRaiseStatus(STATUS_INVALID_SID);
00645             NewDescriptor->Group = Offset;
00646             RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
00647                           DescriptorCopy.Group,
00648                           GroupSize);
00649             Offset += ROUND_UP(GroupSize, sizeof(ULONG));
00650         }
00651 
00652         if (DescriptorCopy.Sacl)
00653         {
00654             if (!RtlValidAcl(DescriptorCopy.Sacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
00655             NewDescriptor->Sacl = Offset;
00656             RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
00657                           DescriptorCopy.Sacl,
00658                           SaclSize);
00659             Offset += ROUND_UP(SaclSize, sizeof(ULONG));
00660         }
00661 
00662         if (DescriptorCopy.Dacl)
00663         {
00664             if (!RtlValidAcl(DescriptorCopy.Dacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
00665             NewDescriptor->Dacl = Offset;
00666             RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
00667                           DescriptorCopy.Dacl,
00668                           DaclSize);
00669             Offset += ROUND_UP(DaclSize, sizeof(ULONG));
00670         }
00671 
00672         /* Make sure the size was correct */
00673         ASSERT(Offset == DescriptorSize);
00674     }
00675     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00676     {
00677         /* We failed to copy the data to the new descriptor */
00678         ExFreePoolWithTag(NewDescriptor, TAG_SD);
00679         _SEH2_YIELD(return _SEH2_GetExceptionCode());
00680     }
00681     _SEH2_END;
00682 
00683     /*
00684      * We're finally done!
00685      * Copy the pointer to the captured descriptor to to the caller.
00686      */
00687     *CapturedSecurityDescriptor = NewDescriptor;
00688     return STATUS_SUCCESS;
00689 }
00690 
00691 /*
00692  * @implemented
00693  */
00694 NTSTATUS NTAPI
00695 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
00696                               IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
00697                               IN OUT PULONG Length,
00698                               IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
00699 {
00700     PISECURITY_DESCRIPTOR ObjectSd;
00701     PISECURITY_DESCRIPTOR_RELATIVE RelSD;
00702     PSID Owner = NULL;
00703     PSID Group = NULL;
00704     PACL Dacl = NULL;
00705     PACL Sacl = NULL;
00706     ULONG OwnerLength = 0;
00707     ULONG GroupLength = 0;
00708     ULONG DaclLength = 0;
00709     ULONG SaclLength = 0;
00710     ULONG Control = 0;
00711     ULONG_PTR Current;
00712     ULONG SdLength;
00713 
00714     RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
00715 
00716     if (*ObjectsSecurityDescriptor == NULL)
00717     {
00718         if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
00719         {
00720             *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00721             return STATUS_BUFFER_TOO_SMALL;
00722         }
00723 
00724         *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00725         RtlCreateSecurityDescriptorRelative(RelSD,
00726                                             SECURITY_DESCRIPTOR_REVISION);
00727         return STATUS_SUCCESS;
00728     }
00729 
00730     ObjectSd = *ObjectsSecurityDescriptor;
00731 
00732     /* Calculate the required security descriptor length */
00733     Control = SE_SELF_RELATIVE;
00734     if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
00735         (ObjectSd->Owner != NULL))
00736     {
00737         Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
00738         OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
00739         Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
00740     }
00741 
00742     if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
00743         (ObjectSd->Group != NULL))
00744     {
00745         Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
00746         GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
00747         Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
00748     }
00749 
00750     if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
00751         (ObjectSd->Control & SE_DACL_PRESENT))
00752     {
00753         if (ObjectSd->Dacl != NULL)
00754         {
00755             Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
00756             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
00757         }
00758 
00759         Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
00760     }
00761 
00762     if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
00763         (ObjectSd->Control & SE_SACL_PRESENT))
00764     {
00765         if (ObjectSd->Sacl != NULL)
00766         {
00767             Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
00768             SaclLength = ROUND_UP(Sacl->AclSize, 4);
00769         }
00770 
00771         Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
00772     }
00773 
00774     SdLength = OwnerLength + GroupLength + DaclLength +
00775     SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00776     if (*Length < SdLength)
00777     {
00778         *Length = SdLength;
00779         return STATUS_BUFFER_TOO_SMALL;
00780     }
00781 
00782     /* Build the new security descrtiptor */
00783     RtlCreateSecurityDescriptorRelative(RelSD,
00784                                         SECURITY_DESCRIPTOR_REVISION);
00785     RelSD->Control = (USHORT)Control;
00786 
00787     Current = (ULONG_PTR)(RelSD + 1);
00788 
00789     if (OwnerLength != 0)
00790     {
00791         RtlCopyMemory((PVOID)Current,
00792                       Owner,
00793                       OwnerLength);
00794         RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
00795         Current += OwnerLength;
00796     }
00797 
00798     if (GroupLength != 0)
00799     {
00800         RtlCopyMemory((PVOID)Current,
00801                       Group,
00802                       GroupLength);
00803         RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
00804         Current += GroupLength;
00805     }
00806 
00807     if (DaclLength != 0)
00808     {
00809         RtlCopyMemory((PVOID)Current,
00810                       Dacl,
00811                       DaclLength);
00812         RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
00813         Current += DaclLength;
00814     }
00815 
00816     if (SaclLength != 0)
00817     {
00818         RtlCopyMemory((PVOID)Current,
00819                       Sacl,
00820                       SaclLength);
00821         RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
00822         Current += SaclLength;
00823     }
00824 
00825     *Length = SdLength;
00826 
00827     return STATUS_SUCCESS;
00828 }
00829 
00830 /*
00831  * @implemented
00832  */
00833 NTSTATUS
00834 NTAPI
00835 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
00836                             IN KPROCESSOR_MODE CurrentMode,
00837                             IN BOOLEAN CaptureIfKernelMode)
00838 {
00839     PAGED_CODE();
00840 
00841     /*
00842      * WARNING! You need to call this function with the same value for CurrentMode
00843      * and CaptureIfKernelMode that you previously passed to
00844      * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
00845      */
00846     if (CapturedSecurityDescriptor != NULL &&
00847         (CurrentMode != KernelMode ||
00848          (CurrentMode == KernelMode && CaptureIfKernelMode)))
00849     {
00850         /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
00851         ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD);
00852     }
00853 
00854     return STATUS_SUCCESS;
00855 }
00856 
00857 /*
00858  * @implemented
00859  */
00860 NTSTATUS NTAPI
00861 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
00862                             IN PSECURITY_INFORMATION _SecurityInformation,
00863                             IN PSECURITY_DESCRIPTOR _SecurityDescriptor,
00864                             IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
00865                             IN POOL_TYPE PoolType,
00866                             IN PGENERIC_MAPPING GenericMapping)
00867 {
00868     PISECURITY_DESCRIPTOR_RELATIVE ObjectSd;
00869     PISECURITY_DESCRIPTOR_RELATIVE NewSd;
00870     PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
00871     PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
00872     PSID Owner = 0;
00873     PSID Group = 0;
00874     PACL Dacl = 0;
00875     PACL Sacl = 0;
00876     ULONG OwnerLength = 0;
00877     ULONG GroupLength = 0;
00878     ULONG DaclLength = 0;
00879     ULONG SaclLength = 0;
00880     ULONG Control = 0;
00881     ULONG Current;
00882     SECURITY_INFORMATION SecurityInformation;
00883 
00884     ObjectSd = *ObjectsSecurityDescriptor;
00885     ASSERT(ObjectSd->Control & SE_SELF_RELATIVE);
00886 
00887     /* The object does not have a security descriptor. */
00888     if (!ObjectSd)
00889         return STATUS_NO_SECURITY_ON_OBJECT;
00890 
00891     SecurityInformation = *_SecurityInformation;
00892 
00893     /* Get owner and owner size */
00894     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
00895     {
00896         if (SecurityDescriptor->Owner != NULL)
00897         {
00898             if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
00899                 Owner = (PSID)((ULONG_PTR)RelSD->Owner +
00900                                (ULONG_PTR)SecurityDescriptor);
00901             else
00902                 Owner = (PSID)SecurityDescriptor->Owner;
00903             OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
00904         }
00905 
00906         Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
00907     }
00908     else
00909     {
00910         if (ObjectSd->Owner)
00911         {
00912             Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
00913             OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
00914         }
00915 
00916         Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
00917     }
00918 
00919     /* Get group and group size */
00920     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
00921     {
00922         if (SecurityDescriptor->Group != NULL)
00923         {
00924             if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
00925                 Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
00926                                (ULONG_PTR)SecurityDescriptor);
00927             else
00928                 Group = (PSID)SecurityDescriptor->Group;
00929             GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
00930         }
00931 
00932         Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
00933     }
00934     else
00935     {
00936         if (ObjectSd->Group)
00937         {
00938             Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
00939             GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
00940         }
00941 
00942         Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
00943     }
00944 
00945     /* Get DACL and DACL size */
00946     if (SecurityInformation & DACL_SECURITY_INFORMATION)
00947     {
00948         if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
00949             (SecurityDescriptor->Dacl != NULL))
00950         {
00951             if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
00952                 Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
00953                               (ULONG_PTR)SecurityDescriptor);
00954             else
00955                 Dacl = (PACL)SecurityDescriptor->Dacl;
00956 
00957             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
00958         }
00959 
00960         Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
00961     }
00962     else
00963     {
00964         if ((ObjectSd->Control & SE_DACL_PRESENT) && (ObjectSd->Dacl))
00965         {
00966             Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
00967             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
00968         }
00969 
00970         Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
00971     }
00972 
00973     /* Get SACL and SACL size */
00974     if (SecurityInformation & SACL_SECURITY_INFORMATION)
00975     {
00976         if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
00977             (SecurityDescriptor->Sacl != NULL))
00978         {
00979             if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
00980                 Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
00981                               (ULONG_PTR)SecurityDescriptor);
00982             else
00983                 Sacl = (PACL)SecurityDescriptor->Sacl;
00984             SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
00985         }
00986 
00987         Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
00988     }
00989     else
00990     {
00991         if ((ObjectSd->Control & SE_SACL_PRESENT) && (ObjectSd->Sacl))
00992         {
00993             Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
00994             SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
00995         }
00996 
00997         Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
00998     }
00999 
01000     NewSd = ExAllocatePool(NonPagedPool,
01001                            sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength +
01002                            DaclLength + SaclLength);
01003     if (NewSd == NULL)
01004     {
01005         ObDereferenceObject(Object);
01006         return STATUS_INSUFFICIENT_RESOURCES;
01007     }
01008 
01009     RtlCreateSecurityDescriptor(NewSd,
01010                                 SECURITY_DESCRIPTOR_REVISION1);
01011 
01012     /* We always build a self-relative descriptor */
01013     NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE;
01014 
01015     Current = sizeof(SECURITY_DESCRIPTOR);
01016 
01017     if (OwnerLength != 0)
01018     {
01019         RtlCopyMemory((PUCHAR)NewSd + Current, Owner, OwnerLength);
01020         NewSd->Owner = Current;
01021         Current += OwnerLength;
01022     }
01023 
01024     if (GroupLength != 0)
01025     {
01026         RtlCopyMemory((PUCHAR)NewSd + Current, Group, GroupLength);
01027         NewSd->Group = Current;
01028         Current += GroupLength;
01029     }
01030 
01031     if (DaclLength != 0)
01032     {
01033         RtlCopyMemory((PUCHAR)NewSd + Current, Dacl, DaclLength);
01034         NewSd->Dacl = Current;
01035         Current += DaclLength;
01036     }
01037 
01038     if (SaclLength != 0)
01039     {
01040         RtlCopyMemory((PUCHAR)NewSd + Current, Sacl, SaclLength);
01041         NewSd->Sacl = Current;
01042         Current += SaclLength;
01043     }
01044 
01045     *ObjectsSecurityDescriptor = NewSd;
01046     return STATUS_SUCCESS;
01047 }
01048 
01049 /*
01050  * @unimplemented
01051  */
01052 NTSTATUS
01053 NTAPI
01054 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL,
01055                               IN PSECURITY_INFORMATION SecurityInformation,
01056                               IN PSECURITY_DESCRIPTOR ModificationDescriptor,
01057                               IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
01058                               IN ULONG AutoInheritFlags,
01059                               IN POOL_TYPE PoolType,
01060                               IN PGENERIC_MAPPING GenericMapping)
01061 {
01062     PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor;
01063 
01064     /* The object does not have a security descriptor. */
01065     if (!ObjectSd)
01066         return STATUS_NO_SECURITY_ON_OBJECT;
01067 
01068     UNIMPLEMENTED;
01069     return STATUS_NOT_IMPLEMENTED;
01070 }
01071 
01072 
01073 /*
01074  * @implemented
01075  */
01076 BOOLEAN NTAPI
01077 SeValidSecurityDescriptor(IN ULONG Length,
01078                           IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
01079 {
01080     ULONG SdLength;
01081     PISID Sid;
01082     PACL Acl;
01083     PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor = _SecurityDescriptor;
01084 
01085     if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
01086     {
01087         DPRINT1("Invalid Security Descriptor revision\n");
01088         return FALSE;
01089     }
01090 
01091     if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
01092     {
01093         DPRINT1("Invalid Security Descriptor revision\n");
01094         return FALSE;
01095     }
01096 
01097     if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
01098     {
01099         DPRINT1("No self-relative Security Descriptor\n");
01100         return FALSE;
01101     }
01102 
01103     SdLength = sizeof(SECURITY_DESCRIPTOR);
01104 
01105     /* Check Owner SID */
01106     if (SecurityDescriptor->Owner)
01107     {
01108         DPRINT1("No Owner SID\n");
01109         return FALSE;
01110     }
01111 
01112     if (SecurityDescriptor->Owner % sizeof(ULONG))
01113     {
01114         DPRINT1("Invalid Owner SID alignment\n");
01115         return FALSE;
01116     }
01117 
01118     Sid = (PISID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Owner);
01119     if (Sid->Revision != SID_REVISION)
01120     {
01121         DPRINT1("Invalid Owner SID revision\n");
01122         return FALSE;
01123     }
01124 
01125     SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
01126     if (Length < SdLength)
01127     {
01128         DPRINT1("Invalid Owner SID size\n");
01129         return FALSE;
01130     }
01131 
01132     /* Check Group SID */
01133     if (SecurityDescriptor->Group)
01134     {
01135         if (SecurityDescriptor->Group % sizeof(ULONG))
01136         {
01137             DPRINT1("Invalid Group SID alignment\n");
01138             return FALSE;
01139         }
01140 
01141         Sid = (PSID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Group);
01142         if (Sid->Revision != SID_REVISION)
01143         {
01144             DPRINT1("Invalid Group SID revision\n");
01145             return FALSE;
01146         }
01147 
01148         SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
01149         if (Length < SdLength)
01150         {
01151             DPRINT1("Invalid Group SID size\n");
01152             return FALSE;
01153         }
01154     }
01155 
01156     /* Check DACL */
01157     if (SecurityDescriptor->Dacl)
01158     {
01159         if (SecurityDescriptor->Dacl % sizeof(ULONG))
01160         {
01161             DPRINT1("Invalid DACL alignment\n");
01162             return FALSE;
01163         }
01164 
01165         Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Dacl);
01166         if ((Acl->AclRevision < MIN_ACL_REVISION) &&
01167             (Acl->AclRevision > MAX_ACL_REVISION))
01168         {
01169             DPRINT1("Invalid DACL revision\n");
01170             return FALSE;
01171         }
01172 
01173         SdLength += Acl->AclSize;
01174         if (Length < SdLength)
01175         {
01176             DPRINT1("Invalid DACL size\n");
01177             return FALSE;
01178         }
01179     }
01180 
01181     /* Check SACL */
01182     if (SecurityDescriptor->Sacl)
01183     {
01184         if (SecurityDescriptor->Sacl % sizeof(ULONG))
01185         {
01186             DPRINT1("Invalid SACL alignment\n");
01187             return FALSE;
01188         }
01189 
01190         Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Sacl);
01191         if ((Acl->AclRevision < MIN_ACL_REVISION) ||
01192             (Acl->AclRevision > MAX_ACL_REVISION))
01193         {
01194             DPRINT1("Invalid SACL revision\n");
01195             return FALSE;
01196         }
01197 
01198         SdLength += Acl->AclSize;
01199         if (Length < SdLength)
01200         {
01201             DPRINT1("Invalid SACL size\n");
01202             return FALSE;
01203         }
01204     }
01205 
01206     return TRUE;
01207 }
01208 
01209 /*
01210  * @implemented
01211  */
01212 NTSTATUS NTAPI
01213 SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
01214 {
01215     PAGED_CODE();
01216 
01217     if (*SecurityDescriptor != NULL)
01218     {
01219         ExFreePoolWithTag(*SecurityDescriptor, TAG_SD);
01220         *SecurityDescriptor = NULL;
01221     }
01222 
01223     return STATUS_SUCCESS;
01224 }
01225 
01226 
01227 
01228 /*
01229  * @unimplemented
01230  */
01231 NTSTATUS NTAPI
01232 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
01233                    IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
01234                    OUT PSECURITY_DESCRIPTOR *NewDescriptor,
01235                    IN GUID *ObjectType OPTIONAL,
01236                    IN BOOLEAN IsDirectoryObject,
01237                    IN ULONG AutoInheritFlags,
01238                    IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
01239                    IN PGENERIC_MAPPING GenericMapping,
01240                    IN POOL_TYPE PoolType)
01241 {
01242     UNIMPLEMENTED;
01243     return STATUS_NOT_IMPLEMENTED;
01244 }
01245 
01246 /*
01247  * @implemented
01248  */
01249 NTSTATUS NTAPI
01250 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
01251                  PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL,
01252                  PSECURITY_DESCRIPTOR *NewDescriptor,
01253                  BOOLEAN IsDirectoryObject,
01254                  PSECURITY_SUBJECT_CONTEXT SubjectContext,
01255                  PGENERIC_MAPPING GenericMapping,
01256                  POOL_TYPE PoolType)
01257 {
01258     PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
01259     PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
01260     PISECURITY_DESCRIPTOR_RELATIVE Descriptor;
01261     PTOKEN Token;
01262     ULONG OwnerLength = 0;
01263     ULONG GroupLength = 0;
01264     ULONG DaclLength = 0;
01265     ULONG SaclLength = 0;
01266     ULONG Length = 0;
01267     ULONG Control = 0;
01268     ULONG Current;
01269     PSID Owner = NULL;
01270     PSID Group = NULL;
01271     PACL Dacl = NULL;
01272     PACL Sacl = NULL;
01273 
01274     PAGED_CODE();
01275 
01276     /* Lock subject context */
01277     SeLockSubjectContext(SubjectContext);
01278 
01279     if (SubjectContext->ClientToken != NULL)
01280     {
01281         Token = SubjectContext->ClientToken;
01282     }
01283     else
01284     {
01285         Token = SubjectContext->PrimaryToken;
01286     }
01287 
01288     /* Inherit the Owner SID */
01289     if (ExplicitDescriptor != NULL)
01290     {
01291         DPRINT("Use explicit owner sid!\n");
01292         Owner = SepGetOwnerFromDescriptor(ExplicitDescriptor);
01293     }
01294 
01295     if (!Owner)
01296     {
01297         if (Token != NULL)
01298         {
01299             DPRINT("Use token owner sid!\n");
01300             Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
01301         }
01302         else
01303         {
01304             DPRINT("Use default owner sid!\n");
01305             Owner = SeLocalSystemSid;
01306         }
01307 
01308         Control |= SE_OWNER_DEFAULTED;
01309     }
01310 
01311     OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
01312 
01313     /* Inherit the Group SID */
01314     if (ExplicitDescriptor != NULL)
01315     {
01316         Group = SepGetGroupFromDescriptor(ExplicitDescriptor);
01317     }
01318 
01319     if (!Group)
01320     {
01321         if (Token != NULL)
01322         {
01323             DPRINT("Use token group sid!\n");
01324             Group = Token->PrimaryGroup;
01325         }
01326         else
01327         {
01328             DPRINT("Use default group sid!\n");
01329             Group = SeLocalSystemSid;
01330         }
01331 
01332         Control |= SE_GROUP_DEFAULTED;
01333     }
01334 
01335     GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
01336 
01337     /* Inherit the DACL */
01338     if (ExplicitDescriptor != NULL &&
01339         (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
01340         !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
01341     {
01342         DPRINT("Use explicit DACL!\n");
01343         Dacl = SepGetDaclFromDescriptor(ExplicitDescriptor);
01344         Control |= SE_DACL_PRESENT;
01345     }
01346     else if (ParentDescriptor != NULL &&
01347              (ParentDescriptor->Control & SE_DACL_PRESENT))
01348     {
01349         DPRINT("Use parent DACL!\n");
01350         /* FIXME: Inherit */
01351         Dacl = SepGetDaclFromDescriptor(ParentDescriptor);
01352         Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
01353     }
01354     else if (Token != NULL && Token->DefaultDacl != NULL)
01355     {
01356         DPRINT("Use token default DACL!\n");
01357         /* FIXME: Inherit */
01358         Dacl = Token->DefaultDacl;
01359         Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
01360     }
01361     else
01362     {
01363         DPRINT("Use NULL DACL!\n");
01364         Dacl = NULL;
01365         Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
01366     }
01367 
01368     DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
01369 
01370     /* Inherit the SACL */
01371     if (ExplicitDescriptor != NULL &&
01372         (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
01373         !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
01374     {
01375         DPRINT("Use explicit SACL!\n");
01376         Sacl = SepGetSaclFromDescriptor(ExplicitDescriptor);
01377         Control |= SE_SACL_PRESENT;
01378     }
01379     else if (ParentDescriptor != NULL &&
01380              (ParentDescriptor->Control & SE_SACL_PRESENT))
01381     {
01382         DPRINT("Use parent SACL!\n");
01383         /* FIXME: Inherit */
01384         Sacl = SepGetSaclFromDescriptor(ParentDescriptor);
01385         Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
01386     }
01387 
01388     SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
01389 
01390     /* Allocate and initialize the new security descriptor */
01391     Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
01392         OwnerLength + GroupLength + DaclLength + SaclLength;
01393 
01394     DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
01395            sizeof(SECURITY_DESCRIPTOR),
01396            OwnerLength,
01397            GroupLength,
01398            DaclLength,
01399            SaclLength);
01400 
01401     Descriptor = ExAllocatePoolWithTag(PagedPool, Length, TAG_SD);
01402     if (Descriptor == NULL)
01403     {
01404         DPRINT1("ExAlloctePool() failed\n");
01405         /* FIXME: Unlock subject context */
01406         return STATUS_INSUFFICIENT_RESOURCES;
01407     }
01408 
01409     RtlZeroMemory(Descriptor, Length);
01410     RtlCreateSecurityDescriptor(Descriptor, SECURITY_DESCRIPTOR_REVISION);
01411 
01412     Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE;
01413 
01414     Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
01415 
01416     if (SaclLength != 0)
01417     {
01418         RtlCopyMemory((PUCHAR)Descriptor + Current, Sacl, SaclLength);
01419         Descriptor->Sacl = Current;
01420         Current += SaclLength;
01421     }
01422 
01423     if (DaclLength != 0)
01424     {
01425         RtlCopyMemory((PUCHAR)Descriptor + Current, Dacl, DaclLength);
01426         Descriptor->Dacl = Current;
01427         Current += DaclLength;
01428     }
01429 
01430     if (OwnerLength != 0)
01431     {
01432         RtlCopyMemory((PUCHAR)Descriptor + Current, Owner, OwnerLength);
01433         Descriptor->Owner = Current;
01434         Current += OwnerLength;
01435         DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
01436     }
01437     else
01438     {
01439         DPRINT("Owner of %x is zero length\n", Descriptor);
01440     }
01441 
01442     if (GroupLength != 0)
01443     {
01444         RtlCopyMemory((PUCHAR)Descriptor + Current, Group, GroupLength);
01445         Descriptor->Group = Current;
01446     }
01447 
01448     /* Unlock subject context */
01449     SeUnlockSubjectContext(SubjectContext);
01450 
01451     *NewDescriptor = Descriptor;
01452 
01453     DPRINT("Descrptor %x\n", Descriptor);
01454     ASSERT(RtlLengthSecurityDescriptor(Descriptor));
01455 
01456     return STATUS_SUCCESS;
01457 }
01458 
01459 /* EOF */

Generated on Sat May 26 2012 04:35:23 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.