Author: tkreuzer
Date: Fri Jan 17 21:58:28 2014
New Revision: 61661
URL:
http://svn.reactos.org/svn/reactos?rev=61661&view=rev
Log:
[NTOSKRNL]
Implement SeCaptureSidAndAttributesArray and SeReleaseSidAndAttributesArray (not used yet,
but very soon)
Modified:
trunk/reactos/ntoskrnl/include/internal/se.h
trunk/reactos/ntoskrnl/se/sid.c
Modified: trunk/reactos/ntoskrnl/include/internal/se.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] Fri Jan 17 21:58:28 2014
@@ -444,6 +444,26 @@
NTSTATUS
NTAPI
+SeCaptureSidAndAttributesArray(
+ _In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes,
+ _In_ ULONG AttributeCount,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _In_opt_ PVOID AllocatedMem,
+ _In_ ULONG AllocatedLength,
+ _In_ POOL_TYPE PoolType,
+ _In_ BOOLEAN CaptureIfKernel,
+ _Out_ PSID_AND_ATTRIBUTES *CapturedSidAndAttributes,
+ _Out_ PULONG ResultLength);
+
+VOID
+NTAPI
+SeReleaseSidAndAttributesArray(
+ _In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes,
+ _In_ KPROCESSOR_MODE AccessMode,
+ _In_ BOOLEAN CaptureIfKernel);
+
+NTSTATUS
+NTAPI
SepCaptureAcl(
IN PACL InputAcl,
IN KPROCESSOR_MODE AccessMode,
Modified: trunk/reactos/ntoskrnl/se/sid.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/sid.c?rev=6166…
==============================================================================
--- trunk/reactos/ntoskrnl/se/sid.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/sid.c [iso-8859-1] Fri Jan 17 21:58:28 2014
@@ -12,6 +12,8 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
+
+#define TAG_SID_AND_ATTRIBUTES 'aSeS'
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, SepInitSecurityIDs)
@@ -340,4 +342,222 @@
}
}
+NTSTATUS
+NTAPI
+SeCaptureSidAndAttributesArray(
+ _In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes,
+ _In_ ULONG AttributeCount,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _In_opt_ PVOID AllocatedMem,
+ _In_ ULONG AllocatedLength,
+ _In_ POOL_TYPE PoolType,
+ _In_ BOOLEAN CaptureIfKernel,
+ _Out_ PSID_AND_ATTRIBUTES *CapturedSidAndAttributes,
+ _Out_ PULONG ResultLength)
+{
+ ULONG ArraySize, RequiredLength, SidLength, i;
+ PSID_AND_ATTRIBUTES SidAndAttributes;
+ PUCHAR CurrentDest;
+ PISID Sid;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ *CapturedSidAndAttributes = NULL;
+ *ResultLength = 0;
+
+ if (AttributeCount == 0)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ if (AttributeCount > 0x1000)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if ((PreviousMode == KernelMode) && !CaptureIfKernel)
+ {
+ *CapturedSidAndAttributes = SrcSidAndAttributes;
+ return STATUS_SUCCESS;
+ }
+
+ ArraySize = AttributeCount * sizeof(SID_AND_ATTRIBUTES);
+ RequiredLength = ALIGN_UP_BY(ArraySize, sizeof(ULONG));
+
+ /* Check for user mode data */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* First probe the whole array */
+ ProbeForRead(SrcSidAndAttributes, ArraySize, sizeof(ULONG));
+
+ /* Loop the array elements */
+ for (i = 0; i < AttributeCount; i++)
+ {
+ /* Get the SID and probe the minimal structure */
+ Sid = SrcSidAndAttributes[i].Sid;
+ ProbeForRead(Sid, sizeof(*Sid), sizeof(ULONG));
+
+ /* Verify that the SID is valid */
+ if (((Sid->Revision & 0xF) != SID_REVISION) ||
+ (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES))
+ {
+ return STATUS_INVALID_SID;
+ }
+
+ /* Calculate the SID length and probe the full SID */
+ SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+ ProbeForRead(Sid, SidLength, sizeof(ULONG));
+
+ /* Add the aligned length to the required length */
+ RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* Loop the array elements */
+ for (i = 0; i < AttributeCount; i++)
+ {
+ /* Get the SID and it's length */
+ Sid = SrcSidAndAttributes[i].Sid;
+ SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+
+ /* Add the aligned length to the required length */
+ RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG));
+ }
+ }
+
+ /* Assume success */
+ Status = STATUS_SUCCESS;
+ *ResultLength = RequiredLength;
+
+ /* Check if we have no buffer */
+ if (AllocatedMem == NULL)
+ {
+ /* Allocate a new buffer */
+ SidAndAttributes = ExAllocatePoolWithTag(PoolType,
+ RequiredLength,
+ TAG_SID_AND_ATTRIBUTES);
+ if (SidAndAttributes == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ /* Otherwise check if the buffer is large enough */
+ else if (AllocatedLength >= RequiredLength)
+ {
+ /* Buffer is large enough, use it */
+ SidAndAttributes = AllocatedMem;
+ }
+ else
+ {
+ /* Buffer is too small, fail */
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ *CapturedSidAndAttributes = SidAndAttributes;
+
+ /* Check again for user mode */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* The rest of the data starts after the array */
+ CurrentDest = (PUCHAR)SidAndAttributes;
+ CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG));
+
+ /* Loop the array elements */
+ for (i = 0; i < AttributeCount; i++)
+ {
+ /* Get the SID and it's length */
+ Sid = SrcSidAndAttributes[i].Sid;
+ SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+
+ /* Copy attributes */
+ SidAndAttributes[i].Attributes = SrcSidAndAttributes[i].Attributes;
+
+ /* Copy the SID to the current destination address */
+ SidAndAttributes[i].Sid = (PSID)CurrentDest;
+ RtlCopyMemory(CurrentDest, SrcSidAndAttributes[i].Sid, SidLength);
+
+ /* Sanity checks */
+ NT_ASSERT(RtlLengthSid(SidAndAttributes[i].Sid) == SidLength);
+ NT_ASSERT(RtlValidSid(SidAndAttributes[i].Sid));
+
+ /* Update the current destination address */
+ CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* First copy the source array */
+ RtlCopyMemory(SidAndAttributes, SrcSidAndAttributes, ArraySize);
+
+ /* The rest of the data starts after the array */
+ CurrentDest = (PUCHAR)SidAndAttributes;
+ CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG));
+
+ /* Loop the array elements */
+ for (i = 0; i < AttributeCount; i++)
+ {
+ /* Get the SID and it's length */
+ Sid = SrcSidAndAttributes[i].Sid;
+ SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+
+ /* Copy the SID to the current destination address */
+ SidAndAttributes[i].Sid = (PSID)CurrentDest;
+ RtlCopyMemory(CurrentDest, SrcSidAndAttributes[i].Sid, SidLength);
+
+ /* Update the current destination address */
+ CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG));
+ }
+ }
+
+ /* Check for failure */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Check if we allocated a new array */
+ if (SidAndAttributes != AllocatedMem)
+ {
+ /* Free the array */
+ ExFreePoolWithTag(SidAndAttributes, TAG_SID_AND_ATTRIBUTES);
+ }
+
+ /* Set returned address to NULL */
+ *CapturedSidAndAttributes = NULL ;
+ }
+
+ return Status;
+}
+
+VOID
+NTAPI
+SeReleaseSidAndAttributesArray(
+ _In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes,
+ _In_ KPROCESSOR_MODE AccessMode,
+ _In_ BOOLEAN CaptureIfKernel)
+{
+ PAGED_CODE();
+
+ if ((CapturedSidAndAttributes != NULL) &&
+ ((AccessMode != KernelMode) || CaptureIfKernel))
+ {
+ ExFreePoolWithTag(CapturedSidAndAttributes, TAG_SID_AND_ATTRIBUTES);
+ }
+}
+
+
/* EOF */