-/* $Id: sd.c,v 1.11 2003/10/12 17:05:50 hbirr Exp $
+/* $Id$
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Security manager
- * FILE: kernel/se/sd.c
- * PROGRAMER: David Welch <welch@cwcom.net>
- * REVISION HISTORY:
- * 26/07/98: Added stubs for security functions
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/se/sd.c
+ * PURPOSE: Security manager
+ *
+ * PROGRAMMERS: David Welch <welch@cwcom.net>
*/
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/se.h>
-
+#include <ntoskrnl.h>
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SepInitSDs)
+#endif
+
+
/* GLOBALS ******************************************************************/
PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
/* FUNCTIONS ***************************************************************/
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
SepInitSDs(VOID)
{
/* Create PublicDefaultSd */
- SePublicDefaultSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SePublicDefaultSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SePublicDefaultSd,
SECURITY_DESCRIPTOR_REVISION);
FALSE);
/* Create PublicDefaultUnrestrictedSd */
- SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SePublicDefaultUnrestrictedSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
SECURITY_DESCRIPTOR_REVISION);
FALSE);
/* Create PublicOpenSd */
- SePublicOpenSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SePublicOpenSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SePublicOpenSd,
SECURITY_DESCRIPTOR_REVISION);
FALSE);
/* Create PublicOpenUnrestrictedSd */
- SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SePublicOpenUnrestrictedSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
SECURITY_DESCRIPTOR_REVISION);
FALSE);
/* Create SystemDefaultSd */
- SeSystemDefaultSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SeSystemDefaultSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SeSystemDefaultSd,
SECURITY_DESCRIPTOR_REVISION);
FALSE);
/* Create UnrestrictedSd */
- SeUnrestrictedSd = ExAllocatePool(NonPagedPool,
- sizeof(SECURITY_DESCRIPTOR));
+ SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+ sizeof(SECURITY_DESCRIPTOR), TAG_SD);
if (SeUnrestrictedSd == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateSecurityDescriptor(SeUnrestrictedSd,
SECURITY_DESCRIPTOR_REVISION);
SeUnrestrictedDacl,
FALSE);
- return(TRUE);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- ULONG Revision)
-{
- if (Revision != SECURITY_DESCRIPTOR_REVISION)
- return(STATUS_UNSUCCESSFUL);
-
- SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
- SecurityDescriptor->Sbz1 = 0;
- SecurityDescriptor->Control = 0;
- SecurityDescriptor->Owner = NULL;
- SecurityDescriptor->Group = NULL;
- SecurityDescriptor->Sacl = NULL;
- SecurityDescriptor->Dacl = NULL;
-
- return(STATUS_SUCCESS);
+ return TRUE;
}
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
+NTSTATUS
+STDCALL
+SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
+ PISECURITY_DESCRIPTOR SecurityDescriptor,
+ PULONG BufferLength)
{
- PSID Owner;
- PSID Group;
- ULONG Length;
- PACL Dacl;
- PACL Sacl;
+ ULONG_PTR Current;
+ ULONG SidSize;
+ ULONG SdSize;
+ NTSTATUS Status;
- Length = sizeof(SECURITY_DESCRIPTOR);
+ DPRINT("SeSetWorldSecurityDescriptor() called\n");
- if (SecurityDescriptor->Owner != NULL)
+ if (SecurityInformation == 0)
{
- Owner = SecurityDescriptor->Owner;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- Owner = (PSID)((ULONG)Owner +
- (ULONG)SecurityDescriptor);
- }
- Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) *
- sizeof(ULONG) + 3) & 0xfc);
+ return STATUS_ACCESS_DENIED;
}
- if (SecurityDescriptor->Group != NULL)
- {
- Group = SecurityDescriptor->Group;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
- }
- Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) *
- sizeof(ULONG) + 3) & 0xfc);
- }
+ SidSize = RtlLengthSid(SeWorldSid);
+ SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
- if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
- SecurityDescriptor->Dacl != NULL)
+ if (*BufferLength < SdSize)
{
- Dacl = SecurityDescriptor->Dacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor);
- }
- Length = Length + ((Dacl->AclSize + 3) & 0xfc);
+ *BufferLength = SdSize;
+ return STATUS_BUFFER_TOO_SMALL;
}
- if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
- SecurityDescriptor->Sacl != NULL)
+ *BufferLength = SdSize;
+
+ Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status))
{
- Sacl = SecurityDescriptor->Sacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor);
- }
- Length = Length + ((Sacl->AclSize + 3) & 0xfc);
+ return Status;
}
- return(Length);
-}
-
+ SecurityDescriptor->Control |= SE_SELF_RELATIVE;
+ Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PBOOLEAN DaclPresent,
- PACL* Dacl,
- PBOOLEAN DaclDefaulted)
-{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
{
- return(STATUS_UNSUCCESSFUL);
+ RtlCopyMemory((PVOID)Current,
+ SeWorldSid,
+ SidSize);
+ SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+ Current += SidSize;
}
- if (!(SecurityDescriptor->Control & SE_DACL_PRESENT))
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
{
- *DaclPresent = FALSE;
- return(STATUS_SUCCESS);
+ RtlCopyMemory((PVOID)Current,
+ SeWorldSid,
+ SidSize);
+ SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+ Current += SidSize;
}
- *DaclPresent = TRUE;
- if (SecurityDescriptor->Dacl == NULL)
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
- *Dacl = NULL;
+ SecurityDescriptor->Control |= SE_DACL_PRESENT;
}
- else
+
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl +
- (PVOID)SecurityDescriptor);
- }
- else
- {
- *Dacl = SecurityDescriptor->Dacl;
- }
+ SecurityDescriptor->Control |= SE_SACL_PRESENT;
}
- if (SecurityDescriptor->Control & SE_DACL_DEFAULTED)
- {
- *DaclDefaulted = TRUE;
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN KPROCESSOR_MODE AccessMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+ OUT PBOOLEAN Present)
+{
+ PSECURITY_QUALITY_OF_SERVICE CapturedQos;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ ASSERT(CapturedSecurityQualityOfService);
+ ASSERT(Present);
+
+ if(ObjectAttributes != NULL)
+ {
+ if(AccessMode != KernelMode)
+ {
+ SECURITY_QUALITY_OF_SERVICE SafeQos;
+
+ _SEH_TRY
+ {
+ ProbeForRead(ObjectAttributes,
+ sizeof(ObjectAttributes),
+ sizeof(ULONG));
+ if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+ {
+ if(ObjectAttributes->SecurityQualityOfService != NULL)
+ {
+ ProbeForRead(ObjectAttributes->SecurityQualityOfService,
+ sizeof(SECURITY_QUALITY_OF_SERVICE),
+ sizeof(ULONG));
+
+ if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+ sizeof(SECURITY_QUALITY_OF_SERVICE))
+ {
+ /* don't allocate memory here because ExAllocate should bugcheck
+ the system if it's buggy, SEH would catch that! So make a local
+ copy of the qos structure.*/
+ RtlCopyMemory(&SafeQos,
+ ObjectAttributes->SecurityQualityOfService,
+ sizeof(SECURITY_QUALITY_OF_SERVICE));
+ *Present = TRUE;
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ *CapturedSecurityQualityOfService = NULL;
+ *Present = FALSE;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(NT_SUCCESS(Status))
+ {
+ if(*Present)
+ {
+ CapturedQos = ExAllocatePool(PoolType,
+ sizeof(SECURITY_QUALITY_OF_SERVICE));
+ if(CapturedQos != NULL)
+ {
+ RtlCopyMemory(CapturedQos,
+ &SafeQos,
+ sizeof(SECURITY_QUALITY_OF_SERVICE));
+ *CapturedSecurityQualityOfService = CapturedQos;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ *CapturedSecurityQualityOfService = NULL;
+ }
+ }
+ }
+ else
+ {
+ if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+ {
+ if(CaptureIfKernel)
+ {
+ if(ObjectAttributes->SecurityQualityOfService != NULL)
+ {
+ if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+ sizeof(SECURITY_QUALITY_OF_SERVICE))
+ {
+ CapturedQos = ExAllocatePool(PoolType,
+ sizeof(SECURITY_QUALITY_OF_SERVICE));
+ if(CapturedQos != NULL)
+ {
+ RtlCopyMemory(CapturedQos,
+ ObjectAttributes->SecurityQualityOfService,
+ sizeof(SECURITY_QUALITY_OF_SERVICE));
+ *CapturedSecurityQualityOfService = CapturedQos;
+ *Present = TRUE;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ *CapturedSecurityQualityOfService = NULL;
+ *Present = FALSE;
+ }
+ }
+ else
+ {
+ *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
+ *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
}
+ }
else
- {
- *DaclDefaulted = FALSE;
- }
+ {
+ *CapturedSecurityQualityOfService = NULL;
+ *Present = FALSE;
+ }
+
+ return Status;
+}
+
- return(STATUS_SUCCESS);
+VOID
+NTAPI
+SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel)
+{
+ PAGED_CODE();
+
+ if(CapturedSecurityQualityOfService != NULL &&
+ (AccessMode != KernelMode ||
+ (AccessMode == KernelMode && CaptureIfKernel)))
+ {
+ ExFreePool(CapturedSecurityQualityOfService);
+ }
}
/*
* @implemented
*/
-NTSTATUS STDCALL
-RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- BOOLEAN DaclPresent,
- PACL Dacl,
- BOOLEAN DaclDefaulted)
+NTSTATUS
+STDCALL
+SeCaptureSecurityDescriptor(
+ IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
+ IN KPROCESSOR_MODE CurrentMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
+ )
{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (!DaclPresent)
- {
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT);
- return(STATUS_SUCCESS);
+ PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
+ SECURITY_DESCRIPTOR DescriptorCopy;
+ PISECURITY_DESCRIPTOR NewDescriptor;
+ ULONG OwnerSAC = 0, GroupSAC = 0;
+ ULONG OwnerSize = 0, GroupSize = 0;
+ ULONG SaclSize = 0, DaclSize = 0;
+ ULONG DescriptorSize = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if(OriginalSecurityDescriptor != NULL)
+ {
+ if(CurrentMode != KernelMode)
+ {
+ RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
+
+ _SEH_TRY
+ {
+ /* first only probe and copy until the control field of the descriptor
+ to determine whether it's a self-relative descriptor */
+ DescriptorSize = (ULONG)((ULONG_PTR)&OriginalSecurityDescriptor->Control -
+ (ULONG_PTR)OriginalSecurityDescriptor) +
+ sizeof(OriginalSecurityDescriptor->Control);
+ ProbeForRead(OriginalSecurityDescriptor,
+ DescriptorSize,
+ sizeof(ULONG));
+
+ if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+ {
+ Status = STATUS_UNKNOWN_REVISION;
+ _SEH_LEAVE;
+ }
+
+ /* make a copy on the stack */
+ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
+ DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
+ DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
+ DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
+
+ /* probe and copy the entire security descriptor structure. The SIDs
+ and ACLs will be probed and copied later though */
+ ProbeForRead(OriginalSecurityDescriptor,
+ DescriptorSize,
+ sizeof(ULONG));
+ if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+ {
+ PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+
+ DescriptorCopy.Owner = (PSID)RelSD->Owner;
+ DescriptorCopy.Group = (PSID)RelSD->Group;
+ DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
+ DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
+ }
+ else
+ {
+ DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
+ DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
+ DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
+ DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else if(!CaptureIfKernel)
+ {
+ if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+ {
+ return STATUS_UNKNOWN_REVISION;
+ }
+
+ *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+ {
+ return STATUS_UNKNOWN_REVISION;
+ }
+
+ /* make a copy on the stack */
+ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
+ DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
+ DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
+ DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
+ if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+ {
+ PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+
+ DescriptorCopy.Owner = (PSID)RelSD->Owner;
+ DescriptorCopy.Group = (PSID)RelSD->Group;
+ DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
+ DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
+ }
+ else
+ {
+ DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
+ DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
+ DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
+ DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
+ }
+ }
+
+ if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+ {
+ /* in case we're dealing with a self-relative descriptor, do a basic convert
+ to an absolute descriptor. We do this so we can simply access the data
+ using the pointers without calculating them again. */
+ DescriptorCopy.Control &= ~SE_SELF_RELATIVE;
+ if(DescriptorCopy.Owner != NULL)
+ {
+ DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner);
+ }
+ if(DescriptorCopy.Group != NULL)
+ {
+ DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group);
+ }
+ if(DescriptorCopy.Dacl != NULL)
+ {
+ DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl);
+ }
+ if(DescriptorCopy.Sacl != NULL)
+ {
+ DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
+ }
+ }
+
+ /* determine the size of the SIDs */
+#define DetermineSIDSize(SidType) \
+ do { \
+ if(DescriptorCopy.SidType != NULL) \
+ { \
+ SID *SidType = (SID*)DescriptorCopy.SidType; \
+ \
+ if(CurrentMode != KernelMode) \
+ { \
+ /* securely access the buffers! */ \
+ _SEH_TRY \
+ { \
+ ProbeForRead(&SidType->SubAuthorityCount, \
+ sizeof(SidType->SubAuthorityCount), \
+ 1); \
+ SidType##SAC = SidType->SubAuthorityCount; \
+ SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
+ DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
+ ProbeForRead(SidType, \
+ SidType##Size, \
+ sizeof(ULONG)); \
+ if(!RtlValidSid(SidType)) \
+ { \
+ Status = STATUS_INVALID_SID; \
+ } \
+ } \
+ _SEH_HANDLE \
+ { \
+ Status = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
+ \
+ if(!NT_SUCCESS(Status)) \
+ { \
+ return Status; \
+ } \
+ } \
+ else \
+ { \
+ SidType##SAC = SidType->SubAuthorityCount; \
+ SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
+ DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
+ } \
+ } \
+ } while(0)
+
+ DetermineSIDSize(Owner);
+ DetermineSIDSize(Group);
+
+ /* determine the size of the ACLs */
+#define DetermineACLSize(AclType, AclFlag) \
+ do { \
+ if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
+ DescriptorCopy.AclType != NULL) \
+ { \
+ PACL AclType = (PACL)DescriptorCopy.AclType; \
+ \
+ if(CurrentMode != KernelMode) \
+ { \
+ /* securely access the buffers! */ \
+ _SEH_TRY \
+ { \
+ ProbeForRead(&AclType->AclSize, \
+ sizeof(AclType->AclSize), \
+ 1); \
+ AclType##Size = AclType->AclSize; \
+ DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
+ ProbeForRead(AclType, \
+ AclType##Size, \
+ sizeof(ULONG)); \
+ if(!RtlValidAcl(AclType)) \
+ { \
+ Status = STATUS_INVALID_ACL; \
+ } \
+ } \
+ _SEH_HANDLE \
+ { \
+ Status = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
+ \
+ if(!NT_SUCCESS(Status)) \
+ { \
+ return Status; \
+ } \
+ } \
+ else \
+ { \
+ AclType##Size = AclType->AclSize; \
+ DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
+ } \
+ } \
+ else \
+ { \
+ DescriptorCopy.AclType = NULL; \
+ } \
+ } while(0)
+
+ DetermineACLSize(Sacl, SACL);
+ DetermineACLSize(Dacl, DACL);
+
+ /* allocate enough memory to store a complete copy of a self-relative
+ security descriptor */
+ NewDescriptor = ExAllocatePool(PoolType,
+ DescriptorSize);
+ if(NewDescriptor != NULL)
+ {
+ ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
+
+ RtlZeroMemory(NewDescriptor, DescriptorSize);
+ NewDescriptor->Revision = DescriptorCopy.Revision;
+ NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
+ NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
+
+ _SEH_TRY
+ {
+ /* setup the offsets and copy the SIDs and ACLs to the new
+ self-relative security descriptor. Probing the pointers is not
+ neccessary anymore as we did that when collecting the sizes! */
+#define CopySIDOrACL(Type) \
+ do { \
+ if(DescriptorCopy.Type != NULL) \
+ { \
+ NewDescriptor->Type = (PVOID)Offset; \
+ RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
+ (ULONG_PTR)NewDescriptor->Type), \
+ DescriptorCopy.Type, \
+ Type##Size); \
+ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
+ } \
+ } while(0)
+
+ CopySIDOrACL(Owner);
+ CopySIDOrACL(Group);
+ CopySIDOrACL(Sacl);
+ CopySIDOrACL(Dacl);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(NT_SUCCESS(Status))
+ {
+ /* we're finally done! copy the pointer to the captured descriptor to
+ to the caller */
+ *CapturedSecurityDescriptor = NewDescriptor;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ /* we failed to copy the data to the new descriptor */
+ ExFreePool(NewDescriptor);
+ }
}
-
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT;
- SecurityDescriptor->Dacl = Dacl;
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED);
-
- if (DaclDefaulted)
+ else
{
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
}
+ }
+ else
+ {
+ /* nothing to do... */
+ *CapturedSecurityDescriptor = NULL;
+ }
- return(STATUS_SUCCESS);
+ return Status;
}
-
/*
* @implemented
*/
-BOOLEAN STDCALL
-RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
+NTSTATUS STDCALL
+SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
+ IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN OUT PULONG Length,
+ IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
{
- PSID Owner;
- PSID Group;
- PACL Sacl;
- PACL Dacl;
-
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(FALSE);
- }
+ PISECURITY_DESCRIPTOR ObjectSd;
+ PISECURITY_DESCRIPTOR_RELATIVE RelSD;
+ PSID Owner = NULL;
+ PSID Group = NULL;
+ PACL Dacl = NULL;
+ PACL Sacl = NULL;
+ ULONG OwnerLength = 0;
+ ULONG GroupLength = 0;
+ ULONG DaclLength = 0;
+ ULONG SaclLength = 0;
+ ULONG Control = 0;
+ ULONG_PTR Current;
+ ULONG SdLength;
+
+ RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
+
+ if (*ObjectsSecurityDescriptor == NULL)
+ {
+ if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
+ {
+ *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
- Owner = SecurityDescriptor->Owner;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor);
+ *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+ RtlCreateSecurityDescriptorRelative(RelSD,
+ SECURITY_DESCRIPTOR_REVISION);
+ return STATUS_SUCCESS;
}
- if (!RtlValidSid(Owner))
- {
- return(FALSE);
- }
+ ObjectSd = *ObjectsSecurityDescriptor;
- Group = SecurityDescriptor->Group;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ /* Calculate the required security descriptor length */
+ Control = SE_SELF_RELATIVE;
+ if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
+ (ObjectSd->Owner != NULL))
{
- Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
+ Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
+ OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+ Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
}
- if (!RtlValidSid(Group))
+ if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
+ (ObjectSd->Group != NULL))
{
- return(FALSE);
+ Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
+ GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+ Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
}
- if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
- SecurityDescriptor->Dacl != NULL)
+ if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
+ (ObjectSd->Control & SE_DACL_PRESENT))
{
- Dacl = SecurityDescriptor->Dacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ if (ObjectSd->Dacl != NULL)
{
- Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor);
- }
-
- if (!RtlValidAcl(Dacl))
- {
- return(FALSE);
+ Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
+ DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
}
+ Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
}
- if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
- SecurityDescriptor->Sacl != NULL)
+ if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
+ (ObjectSd->Control & SE_SACL_PRESENT))
{
- Sacl = SecurityDescriptor->Sacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ if (ObjectSd->Sacl != NULL)
{
- Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor);
+ Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
+ SaclLength = ROUND_UP(Sacl->AclSize, 4);
}
+ Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+ }
- if (!RtlValidAcl(Sacl))
- {
- return(FALSE);
- }
+ SdLength = OwnerLength + GroupLength + DaclLength +
+ SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+ if (*Length < SdLength)
+ {
+ *Length = SdLength;
+ return STATUS_BUFFER_TOO_SMALL;
}
- return(TRUE);
-}
+ /* Build the new security descrtiptor */
+ RtlCreateSecurityDescriptorRelative(RelSD,
+ SECURITY_DESCRIPTOR_REVISION);
+ RelSD->Control = Control;
+ Current = (ULONG_PTR)(RelSD + 1);
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PSID Owner,
- BOOLEAN OwnerDefaulted)
-{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
+ if (OwnerLength != 0)
{
- return(STATUS_UNSUCCESSFUL);
+ RtlCopyMemory((PVOID)Current,
+ Owner,
+ OwnerLength);
+ RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+ Current += OwnerLength;
}
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ if (GroupLength != 0)
{
- return(STATUS_UNSUCCESSFUL);
+ RtlCopyMemory((PVOID)Current,
+ Group,
+ GroupLength);
+ RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+ Current += GroupLength;
}
- SecurityDescriptor->Owner = Owner;
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED);
-
- if (OwnerDefaulted)
+ if (DaclLength != 0)
{
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED;
+ RtlCopyMemory((PVOID)Current,
+ Dacl,
+ DaclLength);
+ RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+ Current += DaclLength;
}
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PSID* Owner,
- PBOOLEAN OwnerDefaulted)
-{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
+ if (SaclLength != 0)
{
- return(STATUS_UNSUCCESSFUL);
+ RtlCopyMemory((PVOID)Current,
+ Sacl,
+ SaclLength);
+ RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+ Current += SaclLength;
}
- if (SecurityDescriptor->Owner != NULL)
- {
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Owner = (PSID)((ULONG)SecurityDescriptor->Owner +
- (PVOID)SecurityDescriptor);
- }
- else
- {
- *Owner = SecurityDescriptor->Owner;
- }
- }
- else
- {
- *Owner = NULL;
- }
- if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED)
- {
- *OwnerDefaulted = 1;
- }
- else
- {
- *OwnerDefaulted = 0;
- }
- return(STATUS_SUCCESS);
-}
+ *Length = SdLength;
+ return STATUS_SUCCESS;
+}
/*
* @implemented
*/
-NTSTATUS STDCALL
-RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PSID Group,
- BOOLEAN GroupDefaulted)
+NTSTATUS
+STDCALL
+SeReleaseSecurityDescriptor(
+ IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+ IN KPROCESSOR_MODE CurrentMode,
+ IN BOOLEAN CaptureIfKernelMode
+ )
{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- SecurityDescriptor->Group = Group;
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED);
-
- if (GroupDefaulted)
- {
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED;
- }
-
- return(STATUS_SUCCESS);
+ PAGED_CODE();
+
+ /* WARNING! You need to call this function with the same value for CurrentMode
+ and CaptureIfKernelMode that you previously passed to
+ SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
+ if(CapturedSecurityDescriptor != NULL &&
+ (CurrentMode != KernelMode ||
+ (CurrentMode == KernelMode && CaptureIfKernelMode)))
+ {
+ /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
+ ExFreePool(CapturedSecurityDescriptor);
+ }
+
+ return STATUS_SUCCESS;
}
-
/*
- * @implemented
+ * @unimplemented
*/
NTSTATUS STDCALL
-RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PSID* Group,
- PBOOLEAN GroupDefaulted)
+SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
+ IN PSECURITY_INFORMATION SecurityInformation,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
+ IN POOL_TYPE PoolType,
+ IN PGENERIC_MAPPING GenericMapping)
{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (SecurityDescriptor->Group != NULL)
- {
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Group = (PSID)((ULONG)SecurityDescriptor->Group +
- (PVOID)SecurityDescriptor);
- }
- else
- {
- *Group = SecurityDescriptor->Group;
- }
- }
- else
- {
- *Group = NULL;
- }
-
- if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED)
- {
- *GroupDefaulted = TRUE;
- }
- else
- {
- *GroupDefaulted = FALSE;
- }
-
- return(STATUS_SUCCESS);
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-
/*
- * @implemented
+ * @unimplemented
*/
-NTSTATUS STDCALL
-RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PBOOLEAN SaclPresent,
- PACL *Sacl,
- PBOOLEAN SaclDefaulted)
+NTSTATUS
+STDCALL
+SeSetSecurityDescriptorInfoEx(
+ IN PVOID Object OPTIONAL,
+ IN PSECURITY_INFORMATION SecurityInformation,
+ IN PSECURITY_DESCRIPTOR ModificationDescriptor,
+ IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
+ IN ULONG AutoInheritFlags,
+ IN POOL_TYPE PoolType,
+ IN PGENERIC_MAPPING GenericMapping
+ )
{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (!(SecurityDescriptor->Control & SE_SACL_PRESENT))
- {
- *SaclPresent = FALSE;
- return(STATUS_SUCCESS);
- }
- *SaclPresent = TRUE;
-
- if (SecurityDescriptor->Sacl == NULL)
- {
- *Sacl = NULL;
- }
- else
- {
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Sacl = (PACL)((ULONG)SecurityDescriptor->Sacl +
- (PVOID)SecurityDescriptor);
- }
- else
- {
- *Sacl = SecurityDescriptor->Sacl;
- }
- }
-
- if (SecurityDescriptor->Control & SE_SACL_DEFAULTED)
- {
- *SaclDefaulted = TRUE;
- }
- else
- {
- *SaclDefaulted = FALSE;
- }
-
- return(STATUS_SUCCESS);
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
-RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- BOOLEAN SaclPresent,
- PACL Sacl,
- BOOLEAN SaclDefaulted)
+BOOLEAN STDCALL
+SeValidSecurityDescriptor(IN ULONG Length,
+ IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
{
- if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ ULONG SdLength;
+ PISID Sid;
+ PACL Acl;
+ PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+
+ if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
{
- return(STATUS_UNSUCCESSFUL);
+ DPRINT1("Invalid Security Descriptor revision\n");
+ return FALSE;
}
- if (!SaclPresent)
+ if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
{
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT);
- return(STATUS_SUCCESS);
+ DPRINT1("Invalid Security Descriptor revision\n");
+ return FALSE;
}
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT;
- SecurityDescriptor->Sacl = Sacl;
- SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED);
-
- if (SaclDefaulted)
+ if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
{
- SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED;
+ DPRINT1("No self-relative Security Descriptor\n");
+ return FALSE;
}
- return(STATUS_SUCCESS);
-}
-
+ SdLength = sizeof(SECURITY_DESCRIPTOR);
-static VOID
-RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
- PSID* Owner,
- PULONG OwnerLength,
- PSID* Group,
- PULONG GroupLength,
- PACL* Dacl,
- PULONG DaclLength,
- PACL* Sacl,
- PULONG SaclLength)
-{
+ /* Check Owner SID */
if (SecurityDescriptor->Owner == NULL)
{
- *Owner = NULL;
- }
- else
- {
- *Owner = SecurityDescriptor->Owner;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor);
- }
+ DPRINT1("No Owner SID\n");
+ return FALSE;
}
- if (*Owner != NULL)
- {
- *OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3;
- }
- else
+ if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
{
- *OwnerLength = 0;
+ DPRINT1("Invalid Owner SID alignment\n");
+ return FALSE;
}
- if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
- SecurityDescriptor->Dacl != NULL)
- {
- *Dacl = SecurityDescriptor->Dacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- *Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor);
- }
- }
- else
+ Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
+ if (Sid->Revision != SID_REVISION)
{
- *Dacl = NULL;
+ DPRINT1("Invalid Owner SID revision\n");
+ return FALSE;
}
- if (*Dacl != NULL)
- {
- *DaclLength = ((*Dacl)->AclSize + 3) & ~3;
- }
- else
+ SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
+ if (Length < SdLength)
{
- *DaclLength = 0;
+ DPRINT1("Invalid Owner SID size\n");
+ return FALSE;
}
+ /* Check Group SID */
if (SecurityDescriptor->Group != NULL)
{
- *Group = NULL;
- }
- else
- {
- *Group = SecurityDescriptor->Group;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
{
- *Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor);
+ DPRINT1("Invalid Group SID alignment\n");
+ return FALSE;
}
- }
- if (*Group != NULL)
- {
- *GroupLength = (RtlLengthSid(*Group) + 3) & ~3;
- }
- else
- {
- *GroupLength = 0;
- }
+ Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
+ if (Sid->Revision != SID_REVISION)
+ {
+ DPRINT1("Invalid Group SID revision\n");
+ return FALSE;
+ }
- if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
- SecurityDescriptor->Sacl != NULL)
- {
- *Sacl = SecurityDescriptor->Sacl;
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+ SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
+ if (Length < SdLength)
{
- *Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor);
+ DPRINT1("Invalid Group SID size\n");
+ return FALSE;
}
}
- else
- {
- *Sacl = NULL;
- }
- if (*Sacl != NULL)
+ /* Check DACL */
+ if (SecurityDescriptor->Dacl != NULL)
{
- *SaclLength = ((*Sacl)->AclSize + 3) & ~3;
- }
-}
-
+ if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
+ {
+ DPRINT1("Invalid DACL alignment\n");
+ return FALSE;
+ }
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
- PSECURITY_DESCRIPTOR RelSD,
- PULONG BufferLength)
-{
- PSID Owner;
- PSID Group;
- PACL Sacl;
- PACL Dacl;
- ULONG OwnerLength;
- ULONG GroupLength;
- ULONG SaclLength;
- ULONG DaclLength;
- ULONG TotalLength;
- ULONG Current;
-
- if (AbsSD->Control & SE_SELF_RELATIVE)
- {
- return(STATUS_BAD_DESCRIPTOR_FORMAT);
- }
-
- RtlpQuerySecurityDescriptor(AbsSD,
- &Owner,
- &OwnerLength,
- &Group,
- &GroupLength,
- &Dacl,
- &DaclLength,
- &Sacl,
- &SaclLength);
-
- TotalLength = OwnerLength + GroupLength + SaclLength +
- DaclLength + sizeof(SECURITY_DESCRIPTOR);
- if (*BufferLength < TotalLength)
- {
- return(STATUS_BUFFER_TOO_SMALL);
- }
-
- RtlZeroMemory(RelSD,
- TotalLength);
- memmove(RelSD,
- AbsSD,
- sizeof(SECURITY_DESCRIPTOR));
- Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR);
+ Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
+ if ((Acl->AclRevision < MIN_ACL_REVISION) &&
+ (Acl->AclRevision > MAX_ACL_REVISION))
+ {
+ DPRINT1("Invalid DACL revision\n");
+ return FALSE;
+ }
- if (SaclLength != 0)
- {
- memmove((PVOID)Current,
- Sacl,
- SaclLength);
- RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD);
- Current += SaclLength;
+ SdLength += Acl->AclSize;
+ if (Length < SdLength)
+ {
+ DPRINT1("Invalid DACL size\n");
+ return FALSE;
+ }
}
- if (DaclLength != 0)
+ /* Check SACL */
+ if (SecurityDescriptor->Sacl != NULL)
{
- memmove((PVOID)Current,
- Dacl,
- DaclLength);
- RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD);
- Current += DaclLength;
- }
+ if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
+ {
+ DPRINT1("Invalid SACL alignment\n");
+ return FALSE;
+ }
- if (OwnerLength != 0)
- {
- memmove((PVOID)Current,
- Owner,
- OwnerLength);
- RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD);
- Current += OwnerLength;
- }
+ Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
+ if ((Acl->AclRevision < MIN_ACL_REVISION) ||
+ (Acl->AclRevision > MAX_ACL_REVISION))
+ {
+ DPRINT1("Invalid SACL revision\n");
+ return FALSE;
+ }
- if (GroupLength != 0)
- {
- memmove((PVOID)Current,
- Group,
- GroupLength);
- RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD);
+ SdLength += Acl->AclSize;
+ if (Length < SdLength)
+ {
+ DPRINT1("Invalid SACL size\n");
+ return FALSE;
+ }
}
- RelSD->Control |= SE_SELF_RELATIVE;
-
- return(STATUS_SUCCESS);
+ return TRUE;
}
/* EOF */