Author: ion
Date: Mon Oct 1 03:02:12 2012
New Revision: 57450
URL:
http://svn.reactos.org/svn/reactos?rev=57450&view=rev
Log:
[RTL]: Reformat, rewrite, comment, and fix when relevant the Rtl*SecurityDescriptor* APIs,
as well as fix one wrong prototype and implement some unimplemented ones.
Modified:
trunk/reactos/include/ndk/rtlfuncs.h
trunk/reactos/include/psdk/winnt.h
trunk/reactos/lib/rtl/sd.c
Modified: trunk/reactos/include/ndk/rtlfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] Mon Oct 1 03:02:12 2012
@@ -1240,7 +1240,7 @@
NTAPI
RtlCopySecurityDescriptor(
IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor,
- OUT PSECURITY_DESCRIPTOR pDestinationSecurityDescriptor
+ OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor
);
NTSYSAPI
Modified: trunk/reactos/include/psdk/winnt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winnt.h?rev=5…
==============================================================================
--- trunk/reactos/include/psdk/winnt.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/winnt.h [iso-8859-1] Mon Oct 1 03:02:12 2012
@@ -1875,20 +1875,22 @@
#define SERVICE_ERROR_NORMAL 1
#define SERVICE_ERROR_SEVERE 2
#define SERVICE_ERROR_CRITICAL 3
-#define SE_OWNER_DEFAULTED 1
-#define SE_GROUP_DEFAULTED 2
-#define SE_DACL_PRESENT 4
-#define SE_DACL_DEFAULTED 8
-#define SE_SACL_PRESENT 16
-#define SE_SACL_DEFAULTED 32
-#define SE_DACL_AUTO_INHERIT_REQ 256
-#define SE_SACL_AUTO_INHERIT_REQ 512
-#define SE_DACL_AUTO_INHERITED 1024
-#define SE_SACL_AUTO_INHERITED 2048
-#define SE_DACL_PROTECTED 4096
-#define SE_SACL_PROTECTED 8192
-#define SE_RM_CONTROL_VALID 0x4000
-#define SE_SELF_RELATIVE 0x8000
+#define SE_OWNER_DEFAULTED 0x0001
+#define SE_GROUP_DEFAULTED 0x0002
+#define SE_DACL_PRESENT 0x0004
+#define SE_DACL_DEFAULTED 0x0008
+#define SE_SACL_PRESENT 0x0010
+#define SE_SACL_DEFAULTED 0x0020
+#define SE_DACL_UNTRUSTED 0x0040
+#define SE_SERVER_SECURITY 0x0080
+#define SE_DACL_AUTO_INHERIT_REQ 0x0100
+#define SE_SACL_AUTO_INHERIT_REQ 0x0200
+#define SE_DACL_AUTO_INHERITED 0x0400
+#define SE_SACL_AUTO_INHERITED 0x0800
+#define SE_DACL_PROTECTED 0x1000
+#define SE_SACL_PROTECTED 0x2000
+#define SE_RM_CONTROL_VALID 0x4000
+#define SE_SELF_RELATIVE 0x8000
#define SECURITY_DESCRIPTOR_MIN_LENGTH 20
#define SECURITY_DESCRIPTOR_REVISION 1
#define SECURITY_DESCRIPTOR_REVISION1 1
Modified: trunk/reactos/lib/rtl/sd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/sd.c?rev=57450&…
==============================================================================
--- trunk/reactos/lib/rtl/sd.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/sd.c [iso-8859-1] Mon Oct 1 03:02:12 2012
@@ -9,244 +9,148 @@
/* INCLUDES *****************************************************************/
#include <rtl.h>
-
+#include "../../ntoskrnl/include/internal/se.h"
#define NDEBUG
#include <debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-static VOID
-RtlpQuerySecurityDescriptorPointers(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PSID *Owner OPTIONAL,
- OUT PSID *Group OPTIONAL,
- OUT PACL *Sacl OPTIONAL,
- OUT PACL *Dacl OPTIONAL)
-{
- if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
- {
- PISECURITY_DESCRIPTOR_RELATIVE RelSD =
(PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
- if (Owner != NULL)
- {
- *Owner = ((RelSD->Owner != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Owner)
: NULL);
- }
-
- if (Group != NULL)
- {
- *Group = ((RelSD->Group != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Group)
: NULL);
- }
- if (Sacl != NULL)
- {
- *Sacl = (((RelSD->Control & SE_SACL_PRESENT) &&
(RelSD->Sacl != 0)) ?
- (PSID)((ULONG_PTR)RelSD + RelSD->Sacl) : NULL);
- }
- if (Dacl != NULL)
- {
- *Dacl = (((RelSD->Control & SE_DACL_PRESENT) &&
(RelSD->Dacl != 0)) ?
- (PSID)((ULONG_PTR)RelSD + RelSD->Dacl) : NULL);
- }
+/* PRIVATE FUNCTIONS **********************************************************/
+
+BOOLEAN
+NTAPI
+RtlpValidateSDOffsetAndSize(IN ULONG Offset,
+ IN ULONG Length,
+ IN ULONG MinLength,
+ OUT PULONG MaxLength)
+{
+ /* Assume failure */
+ *MaxLength = 0;
+
+ /* Reject out of bounds lengths */
+ if (Offset < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) return FALSE;
+ if (Offset >= Length) return FALSE;
+
+ /* Reject insufficient lengths */
+ if ((Length - Offset) < MinLength) return FALSE;
+
+ /* Reject unaligned offsets */
+ if (ALIGN_DOWN(Offset, ULONG) != Offset) return FALSE;
+
+ /* Return length that is safe to read */
+ *MaxLength = Length - Offset;
+ return TRUE;
+}
+
+VOID
+NTAPI
+RtlpQuerySecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PSID *Owner,
+ OUT PULONG OwnerSize,
+ OUT PSID *PrimaryGroup,
+ OUT PULONG PrimaryGroupSize,
+ OUT PACL *Dacl,
+ OUT PULONG DaclSize,
+ OUT PACL *Sacl,
+ OUT PULONG SaclSize)
+{
+ PAGED_CODE_RTL();
+
+ /* Get the owner */
+ *Owner = SepGetOwnerFromDescriptor(SecurityDescriptor);
+ if (*Owner)
+ {
+ /* There's an owner, so align the size */
+ *OwnerSize = ROUND_UP(RtlLengthSid(*Owner), sizeof(ULONG));
}
else
{
- if (Owner != NULL)
- {
- *Owner = SecurityDescriptor->Owner;
- }
- if (Group != NULL)
- {
- *Group = SecurityDescriptor->Group;
- }
- if (Sacl != NULL)
- {
- *Sacl = ((SecurityDescriptor->Control & SE_SACL_PRESENT) ?
SecurityDescriptor->Sacl : NULL);
- }
- if (Dacl != NULL)
- {
- *Dacl = ((SecurityDescriptor->Control & SE_DACL_PRESENT) ?
SecurityDescriptor->Dacl : NULL);
- }
- }
-}
-
-static VOID
-RtlpQuerySecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
- PSID* Owner,
- PULONG OwnerLength,
- PSID* Group,
- PULONG GroupLength,
- PACL* Dacl,
- PULONG DaclLength,
- PACL* Sacl,
- PULONG SaclLength)
-{
- RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
- Owner,
- Group,
- Sacl,
- Dacl);
-
- if (Owner != NULL)
- {
- *OwnerLength = ((*Owner != NULL) ? ROUND_UP(RtlLengthSid(*Owner), 4) : 0);
- }
-
- if (Group != NULL)
- {
- *GroupLength = ((*Group != NULL) ? ROUND_UP(RtlLengthSid(*Group), 4) : 0);
- }
-
- if (Dacl != NULL)
- {
- *DaclLength = ((*Dacl != NULL) ? ROUND_UP((*Dacl)->AclSize, 4) : 0);
- }
-
- if (Sacl != NULL)
- {
- *SaclLength = ((*Sacl != NULL) ? ROUND_UP((*Sacl)->AclSize, 4) : 0);
- }
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlCreateSecurityDescriptor(OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ /* No owner, no size */
+ *OwnerSize = 0;
+ }
+
+ /* Get the group */
+ *PrimaryGroup = SepGetGroupFromDescriptor(SecurityDescriptor);
+ if (*PrimaryGroup)
+ {
+ /* There's a group, so align the size */
+ *PrimaryGroupSize = ROUND_UP(RtlLengthSid(*PrimaryGroup), sizeof(ULONG));
+ }
+ else
+ {
+ /* No group, no size */
+ *PrimaryGroupSize = 0;
+ }
+
+ /* Get the DACL */
+ *Dacl = SepGetDaclFromDescriptor(SecurityDescriptor);
+ if (*Dacl)
+ {
+ /* There's a DACL, align the size */
+ *DaclSize = ROUND_UP((*Dacl)->AclSize, sizeof(ULONG));
+ }
+ else
+ {
+ /* No DACL, no size */
+ *DaclSize = 0;
+ }
+
+ /* Get the SACL */
+ *Sacl = SepGetSaclFromDescriptor(SecurityDescriptor);
+ if (*Sacl)
+ {
+ /* There's a SACL, align the size */
+ *SaclSize = ROUND_UP((*Sacl)->AclSize, sizeof(ULONG));
+ }
+ else
+ {
+ /* No SACL, no size */
+ *SaclSize = 0;
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlCreateSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG Revision)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- pSD->Revision = SECURITY_DESCRIPTOR_REVISION1;
- pSD->Sbz1 = 0;
- pSD->Control = 0;
- pSD->Owner = NULL;
- pSD->Group = NULL;
- pSD->Sacl = NULL;
- pSD->Dacl = NULL;
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor,
- OUT PSECURITY_DESCRIPTOR pDestinationSecurityDescriptor)
-{
- PSID Owner = NULL, Group = NULL;
- PACL Dacl = NULL, Sacl = NULL;
- BOOLEAN Defaulted, Present;
- DWORD OwnerLength, GroupLength;
- PISECURITY_DESCRIPTOR srcSD = pSourceSecurityDescriptor;
- PISECURITY_DESCRIPTOR destSD = pDestinationSecurityDescriptor;
-
- if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION)
- return STATUS_UNKNOWN_REVISION;
-
- /* Copy non relative dependent data */
- destSD->Revision = srcSD->Revision;
- destSD->Sbz1 = srcSD->Sbz1;
- destSD->Control = srcSD->Control;
-
- /* Read relative data */
- RtlGetOwnerSecurityDescriptor(srcSD, &Owner, &Defaulted);
- OwnerLength = RtlLengthSid(Owner);
- RtlGetGroupSecurityDescriptor(srcSD, &Group, &Defaulted);
- GroupLength = RtlLengthSid(Group);
- RtlGetDaclSecurityDescriptor(srcSD, &Present, &Dacl, &Defaulted);
- RtlGetSaclSecurityDescriptor(srcSD, &Present, &Sacl, &Defaulted);
-
- if (srcSD->Control & SE_SELF_RELATIVE)
- {
- destSD->Owner = srcSD->Owner;
- RtlCopySid(OwnerLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Owner, Owner);
-
- destSD->Group = srcSD->Group;
- RtlCopySid(GroupLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Group, Group);
-
- if (srcSD->Control & SE_DACL_PRESENT)
- {
- destSD->Dacl = srcSD->Dacl;
-
- if (srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl))
- {
- RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Dacl), Dacl,
Dacl->AclSize);
- }
- }
-
- if (srcSD->Control & SE_SACL_PRESENT)
- {
- destSD->Sacl = srcSD->Sacl;
-
- if (srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl))
- {
- RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Sacl), Sacl,
Sacl->AclSize);
- }
- }
- }
- else
- {
- RtlCopySid(OwnerLength, destSD->Owner, Owner);
- RtlCopySid(GroupLength, destSD->Group, Group);
-
- if (srcSD->Control & SE_DACL_PRESENT)
- {
- destSD->Dacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Dacl->AclSize);
-
- if (srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl))
- {
- RtlCopyMemory(destSD->Dacl, Dacl, Dacl->AclSize);
- }
- }
-
- if (srcSD->Control & SE_SACL_PRESENT)
- {
- destSD->Sacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Sacl->AclSize);
-
- if (srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl))
- {
- RtlCopyMemory(destSD->Sacl, Sacl, Sacl->AclSize);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-NTAPI
-RtlCreateSecurityDescriptorRelative(OUT PISECURITY_DESCRIPTOR_RELATIVE
SecurityDescriptor,
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revisions */
+ if (Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Setup an empty SD */
+ RtlZeroMemory(Sd, sizeof(*Sd));
+ Sd->Revision = SECURITY_DESCRIPTOR_REVISION;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlCreateSecurityDescriptorRelative(IN PISECURITY_DESCRIPTOR_RELATIVE
SecurityDescriptor,
IN ULONG Revision)
{
PAGED_CODE_RTL();
- if (Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION1;
- SecurityDescriptor->Sbz1 = 0;
- SecurityDescriptor->Control = SE_SELF_RELATIVE;
- SecurityDescriptor->Owner = 0;
- SecurityDescriptor->Group = 0;
- SecurityDescriptor->Sacl = 0;
- SecurityDescriptor->Dacl = 0;
-
- return STATUS_SUCCESS;
-}
-
+ /* Fail on invalid revisions */
+ if (Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Setup an empty SD */
+ RtlZeroMemory(SecurityDescriptor, sizeof(*SecurityDescriptor));
+ SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -255,46 +159,36 @@
NTAPI
RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
+ PISECURITY_DESCRIPTOR Sd;
PSID Owner, Group;
PACL Sacl, Dacl;
ULONG Length;
-
- PAGED_CODE_RTL();
-
- if (((PISECURITY_DESCRIPTOR)SecurityDescriptor)->Control & SE_SELF_RELATIVE)
+ PAGED_CODE_RTL();
+
+ /* Start with the initial length of the SD itself */
+ Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ if (Sd->Control & SE_SELF_RELATIVE)
+ {
Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+ }
else
+ {
Length = sizeof(SECURITY_DESCRIPTOR);
-
- RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)SecurityDescriptor,
- &Owner,
- &Group,
- &Sacl,
- &Dacl);
-
- if (Owner != NULL)
- {
- Length += ROUND_UP(RtlLengthSid(Owner), 4);
- }
-
- if (Group != NULL)
- {
- Length += ROUND_UP(RtlLengthSid(Group), 4);
- }
-
- if (Dacl != NULL)
- {
- Length += ROUND_UP(Dacl->AclSize, 4);
- }
-
- if (Sacl != NULL)
- {
- Length += ROUND_UP(Sacl->AclSize, 4);
- }
-
+ }
+
+ /* Add the length of the individual subcomponents */
+ Owner = SepGetOwnerFromDescriptor(Sd);
+ if (Owner) Length += ROUND_UP(RtlLengthSid(Owner), sizeof(ULONG));
+ Group = SepGetGroupFromDescriptor(Sd);
+ if (Group) Length += ROUND_UP(RtlLengthSid(Group), sizeof(ULONG));
+ Dacl = SepGetDaclFromDescriptor(Sd);
+ if (Dacl) Length += ROUND_UP(Dacl->AclSize, sizeof(ULONG));
+ Sacl = SepGetSaclFromDescriptor(Sd);
+ if (Sacl) Length += ROUND_UP(Sacl->AclSize, sizeof(ULONG));
+
+ /* Return the final length */
return Length;
}
-
/*
* @implemented
@@ -306,34 +200,99 @@
OUT PACL* Dacl,
OUT PBOOLEAN DaclDefaulted)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (!(pSD->Control & SE_DACL_PRESENT))
- {
- *DaclPresent = FALSE;
- return STATUS_SUCCESS;
- }
-
- *DaclPresent = TRUE;
-
- RtlpQuerySecurityDescriptorPointers(pSD,
- NULL,
- NULL,
- NULL,
- Dacl);
-
- *DaclDefaulted = ((pSD->Control & SE_DACL_DEFAULTED) != 0);
-
- return STATUS_SUCCESS;
-}
-
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revisions */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Is there a DACL? */
+ *DaclPresent = Sd->Control & SE_DACL_PRESENT;
+ if (*DaclPresent)
+ {
+ /* Yes, return it, and check if defaulted */
+ *Dacl = SepGetDaclFromDescriptor(Sd);
+ *DaclDefaulted = Sd->Control & SE_DACL_DEFAULTED;
+ }
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PBOOLEAN SaclPresent,
+ OUT PACL* Sacl,
+ OUT PBOOLEAN SaclDefaulted)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revisions */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Is there a SACL? */
+ *SaclPresent = Sd->Control & SE_SACL_PRESENT;
+ if (*SaclPresent)
+ {
+ /* Yes, return it, and check if defaulted */
+ *Sacl = SepGetSaclFromDescriptor(Sd);
+ *SaclDefaulted = Sd->Control & SE_SACL_DEFAULTED;
+ }
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PSID* Owner,
+ OUT PBOOLEAN OwnerDefaulted)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Get the owner and if defaulted */
+ *Owner = SepGetOwnerFromDescriptor(Sd);
+ *OwnerDefaulted = Sd->Control & SE_OWNER_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PSID* Group,
+ OUT PBOOLEAN GroupDefaulted)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Get the group and if defaulted */
+ *Group = SepGetGroupFromDescriptor(Sd);
+ *GroupDefaulted = Sd->Control & SE_GROUP_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -345,74 +304,73 @@
IN PACL Dacl,
IN BOOLEAN DaclDefaulted)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (pSD->Control & SE_SELF_RELATIVE)
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Fail on relative descriptors */
+ if (Sd->Control & SE_SELF_RELATIVE) return STATUS_INVALID_SECURITY_DESCR;
+
+ /* Is there a DACL? */
if (!DaclPresent)
{
- pSD->Control = pSD->Control & ~(SE_DACL_PRESENT);
+ /* Caller is destroying the DACL, unset the flag and we're done */
+ Sd->Control = Sd->Control & ~SE_DACL_PRESENT;
return STATUS_SUCCESS;
}
- pSD->Dacl = Dacl;
- pSD->Control |= SE_DACL_PRESENT;
- pSD->Control &= ~(SE_DACL_DEFAULTED);
-
- if (DaclDefaulted)
- {
- pSD->Control |= SE_DACL_DEFAULTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN
-NTAPI
-RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
- PSID Owner, Group;
- PACL Sacl, Dacl;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return FALSE;
- }
-
- RtlpQuerySecurityDescriptorPointers(pSD,
- &Owner,
- &Group,
- &Sacl,
- &Dacl);
-
- if ((Owner != NULL && !RtlValidSid(Owner)) ||
- (Group != NULL && !RtlValidSid(Group)) ||
- (Sacl != NULL && !RtlValidAcl(Sacl)) ||
- (Dacl != NULL && !RtlValidAcl(Dacl)))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
+ /* Caller is setting a new DACL, set the pointer and flag */
+ Sd->Dacl = Dacl;
+ Sd->Control |= SE_DACL_PRESENT;
+
+ /* Set if defaulted */
+ Sd->Control &= ~SE_DACL_DEFAULTED;
+ if (DaclDefaulted) Sd->Control |= SE_DACL_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN BOOLEAN SaclPresent,
+ IN PACL Sacl,
+ IN BOOLEAN SaclDefaulted)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Fail on relative descriptors */
+ if (Sd->Control & SE_SELF_RELATIVE) return STATUS_INVALID_SECURITY_DESCR;
+
+ /* Is there a SACL? */
+ if (!SaclPresent)
+ {
+ /* Caller is clearing the SACL, unset the flag and we're done */
+ Sd->Control = Sd->Control & ~SE_SACL_PRESENT;
+ return STATUS_SUCCESS;
+ }
+
+ /* Caller is setting a new SACL, set it and the flag */
+ Sd->Sacl = Sacl;
+ Sd->Control |= SE_SACL_PRESENT;
+
+ /* Set if defaulted */
+ Sd->Control &= ~SE_SACL_DEFAULTED;
+ if (SaclDefaulted) Sd->Control |= SE_SACL_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -423,61 +381,25 @@
IN PSID Owner,
IN BOOLEAN OwnerDefaulted)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (pSD->Control & SE_SELF_RELATIVE)
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
- pSD->Owner = Owner;
- pSD->Control &= ~(SE_OWNER_DEFAULTED);
-
- if (OwnerDefaulted)
- {
- pSD->Control |= SE_OWNER_DEFAULTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PSID* Owner,
- OUT PBOOLEAN OwnerDefaulted)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- RtlpQuerySecurityDescriptorPointers(pSD,
- Owner,
- NULL,
- NULL,
- NULL);
-
- *OwnerDefaulted = ((pSD->Control & SE_OWNER_DEFAULTED) != 0);
-
- return STATUS_SUCCESS;
-}
-
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Fail on relative descriptors */
+ if (Sd->Control & SE_SELF_RELATIVE) return STATUS_INVALID_SECURITY_DESCR;
+
+ /* Owner being set or cleared */
+ Sd->Owner = Owner;
+
+ /* Set if defaulted */
+ Sd->Control &= ~SE_OWNER_DEFAULTED;
+ if (OwnerDefaulted) Sd->Control |= SE_OWNER_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -488,86 +410,184 @@
IN PSID Group,
IN BOOLEAN GroupDefaulted)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (pSD->Control & SE_SELF_RELATIVE)
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
- pSD->Group = Group;
- pSD->Control &= ~(SE_GROUP_DEFAULTED);
- if (GroupDefaulted)
- {
- pSD->Control |= SE_GROUP_DEFAULTED;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PSID* Group,
- OUT PBOOLEAN GroupDefaulted)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- RtlpQuerySecurityDescriptorPointers(pSD,
- NULL,
- Group,
- NULL,
- NULL);
-
- *GroupDefaulted = ((pSD->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE);
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD,
- OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
- IN OUT PULONG BufferLength)
-{
- PSID Owner;
- PSID Group;
- PACL Sacl;
- PACL Dacl;
- ULONG OwnerLength;
- ULONG GroupLength;
- ULONG SaclLength;
- ULONG DaclLength;
- ULONG TotalLength;
- ULONG_PTR Current;
- PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD;
- PISECURITY_DESCRIPTOR_RELATIVE pRelSD =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
-
- PAGED_CODE_RTL();
-
- RtlpQuerySecurityDescriptor(pAbsSD,
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Fail on relative descriptors */
+ if (Sd->Control & SE_SELF_RELATIVE) return STATUS_INVALID_SECURITY_DESCR;
+
+ /* Group being set or cleared */
+ Sd->Group = Group;
+
+ /* Set if defaulted */
+ Sd->Control &= ~SE_GROUP_DEFAULTED;
+ if (GroupDefaulted) Sd->Control |= SE_GROUP_DEFAULTED;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PSECURITY_DESCRIPTOR_CONTROL Control,
+ OUT PULONG Revision)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Read current revision, even if invalid */
+ *Revision = Sd->Revision;
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Read current control */
+ *Control = Sd->Control;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
+ IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+
+ /* Check for invalid bits */
+ if ((ControlBitsOfInterest & ~(SE_DACL_UNTRUSTED |
+ SE_SERVER_SECURITY |
+ SE_DACL_AUTO_INHERIT_REQ |
+ SE_SACL_AUTO_INHERIT_REQ |
+ SE_DACL_AUTO_INHERITED |
+ SE_SACL_AUTO_INHERITED |
+ SE_DACL_PROTECTED |
+ SE_SACL_PROTECTED)) ||
+ (ControlBitsToSet & ~ControlBitsOfInterest))
+ {
+ /* Fail */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Zero the 'bits of interest' */
+ Sd->Control &= ~ControlBitsOfInterest;
+
+ /* Set the 'bits to set' */
+ Sd->Control |= (ControlBitsToSet & ControlBitsOfInterest);
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PUCHAR RMControl)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Check if there's no valid RM control */
+ if (!(Sd->Control & SE_RM_CONTROL_VALID))
+ {
+ /* Fail and return nothing */
+ *RMControl = 0;
+ return FALSE;
+ }
+
+ /* Return it, ironically the member is "should be zero" */
+ *RMControl = Sd->Sbz1;
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+RtlSetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN PUCHAR RMControl)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* RM Control is being cleared or set */
+ if (!RMControl)
+ {
+ /* Clear it */
+ Sd->Control &= ~SE_RM_CONTROL_VALID;
+ Sd->Sbz1 = 0;
+ }
+ else
+ {
+ /* Set it */
+ Sd->Control |= SE_RM_CONTROL_VALID;
+ Sd->Sbz1 = *RMControl;
+ }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlSetAttributesSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN SECURITY_DESCRIPTOR_CONTROL Control,
+ OUT PULONG Revision)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Always return revision, even if invalid */
+ *Revision = Sd->Revision;
+
+ /* Fail on invalid revision */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return STATUS_UNKNOWN_REVISION;
+
+ /* Mask out flags which are not attributes */
+ Control &= ~SE_DACL_UNTRUSTED |
+ SE_SERVER_SECURITY |
+ SE_DACL_AUTO_INHERIT_REQ |
+ SE_SACL_AUTO_INHERIT_REQ |
+ SE_DACL_AUTO_INHERITED |
+ SE_SACL_AUTO_INHERITED |
+ SE_DACL_PROTECTED |
+ SE_SACL_PROTECTED;
+
+ /* Call the newer API */
+ return RtlSetControlSecurityDescriptor(SecurityDescriptor, Control, Control);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor,
+ OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
+{
+ PSID Owner, Group;
+ PACL Dacl, Sacl;
+ DWORD OwnerLength, GroupLength, DaclLength, SaclLength, TotalLength;
+ PISECURITY_DESCRIPTOR Sd = pSourceSecurityDescriptor;
+
+ /* Get all the components */
+ RtlpQuerySecurityDescriptor(Sd,
&Owner,
&OwnerLength,
&Group,
@@ -577,60 +597,25 @@
&Sacl,
&SaclLength);
- TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength +
SaclLength + DaclLength;
- if (*BufferLength < TotalLength)
- {
- *BufferLength = TotalLength;
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- RtlZeroMemory(pRelSD,
- TotalLength);
-
- pRelSD->Revision = pAbsSD->Revision;
- pRelSD->Sbz1 = pAbsSD->Sbz1;
- pRelSD->Control = pAbsSD->Control | SE_SELF_RELATIVE;
-
- Current = (ULONG_PTR)(pRelSD + 1);
-
- if (SaclLength != 0)
- {
- RtlCopyMemory((PVOID)Current,
- Sacl,
- SaclLength);
- pRelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
- Current += SaclLength;
- }
-
- if (DaclLength != 0)
- {
- RtlCopyMemory((PVOID)Current,
- Dacl,
- DaclLength);
- pRelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
- Current += DaclLength;
- }
-
- if (OwnerLength != 0)
- {
- RtlCopyMemory((PVOID)Current,
- Owner,
- OwnerLength);
- pRelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
- Current += OwnerLength;
- }
-
- if (GroupLength != 0)
- {
- RtlCopyMemory((PVOID)Current,
- Group,
- GroupLength);
- pRelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD);
- }
-
- return STATUS_SUCCESS;
-}
-
+ /* Add up their lengths */
+ TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
+ OwnerLength +
+ GroupLength +
+ DaclLength +
+ SaclLength;
+
+ /* Allocate a copy */
+ *pDestinationSecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ TotalLength);
+ if (*pDestinationSecurityDescriptor == NULL) return STATUS_NO_MEMORY;
+
+ /* Copy the old in the new */
+ RtlCopyMemory(*pDestinationSecurityDescriptor, Sd, TotalLength);
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -641,164 +626,113 @@
IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
IN PULONG BufferLength)
{
- PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pAbsSD->Control & SE_SELF_RELATIVE)
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
- return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
- SelfRelativeSecurityDescriptor,
- BufferLength);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PSECURITY_DESCRIPTOR_CONTROL Control,
- OUT PULONG Revision)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- *Revision = pSD->Revision;
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- *Control = pSD->Control;
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
- IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
-{
- SECURITY_DESCRIPTOR_CONTROL const immutable
- = SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
- | SE_DACL_PRESENT | SE_DACL_DEFAULTED
- | SE_SACL_PRESENT | SE_SACL_DEFAULTED
- | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE;
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if ((ControlBitsOfInterest | ControlBitsToSet) & immutable)
- return STATUS_INVALID_PARAMETER;
-
- /* Zero the 'bits of interest' */
- pSD->Control &= ~ControlBitsOfInterest;
-
- /* Set the 'bits to set' */
- pSD->Control |= (ControlBitsToSet & ControlBitsOfInterest);
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PBOOLEAN SaclPresent,
- OUT PACL *Sacl,
- OUT PBOOLEAN SaclDefaulted)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (!(pSD->Control & SE_SACL_PRESENT))
- {
- *SaclPresent = FALSE;
- return STATUS_SUCCESS;
- }
-
- *SaclPresent = TRUE;
-
- RtlpQuerySecurityDescriptorPointers(pSD,
- NULL,
- NULL,
- Sacl,
- NULL);
-
- *SaclDefaulted = ((pSD->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE);
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN BOOLEAN SaclPresent,
- IN PACL Sacl,
- IN BOOLEAN SaclDefaulted)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (pSD->Control & SE_SELF_RELATIVE)
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
- if (!SaclPresent)
- {
- pSD->Control &= ~(SE_SACL_PRESENT);
- return STATUS_SUCCESS;
- }
-
- pSD->Sacl = Sacl;
- pSD->Control |= SE_SACL_PRESENT;
- pSD->Control &= ~(SE_SACL_DEFAULTED);
-
- if (SaclDefaulted)
- {
- pSD->Control |= SE_SACL_DEFAULTED;
- }
-
- return STATUS_SUCCESS;
-}
-
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor;
+ PAGED_CODE_RTL();
+
+ /* Can't already be relative */
+ if (Sd->Control & SE_SELF_RELATIVE) return STATUS_BAD_DESCRIPTOR_FORMAT;
+
+ /* Call the other API */
+ return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
+ SelfRelativeSecurityDescriptor,
+ BufferLength);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD,
+ OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
+ IN OUT PULONG BufferLength)
+{
+ PSID Owner, Group;
+ PACL Sacl, Dacl;
+ ULONG OwnerLength, GroupLength, SaclLength, DaclLength, TotalLength;
+ ULONG_PTR Current;
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)AbsoluteSD;
+ PISECURITY_DESCRIPTOR_RELATIVE RelSd =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
+ PAGED_CODE_RTL();
+
+ /* Query all components */
+ RtlpQuerySecurityDescriptor(Sd,
+ &Owner,
+ &OwnerLength,
+ &Group,
+ &GroupLength,
+ &Dacl,
+ &DaclLength,
+ &Sacl,
+ &SaclLength);
+
+ /* Calculate final length */
+ TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
+ OwnerLength +
+ GroupLength +
+ SaclLength +
+ DaclLength;
+
+ /* Is there enough space? */
+ if (*BufferLength < TotalLength)
+ {
+ /* Nope, return how much is needed */
+ *BufferLength = TotalLength;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Start fresh */
+ RtlZeroMemory(RelSd, TotalLength);
+
+ /* Copy the header fields */
+ RtlCopyMemory(RelSd,
+ Sd,
+ FIELD_OFFSET(SECURITY_DESCRIPTOR_RELATIVE, Owner));
+
+ /* Set the current copy pointer */
+ Current = (ULONG_PTR)(RelSd + 1);
+
+ /* Is there a SACL? */
+ if (SaclLength)
+ {
+ /* Copy it */
+ RtlCopyMemory((PVOID)Current, Sacl, SaclLength);
+ RelSd->Sacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
+ Current += SaclLength;
+ }
+
+ /* Is there a DACL? */
+ if (DaclLength)
+ {
+ /* Copy it */
+ RtlCopyMemory((PVOID)Current, Dacl, DaclLength);
+ RelSd->Dacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
+ Current += DaclLength;
+ }
+
+ /* Is there an owner? */
+ if (OwnerLength)
+ {
+ /* Copy it */
+ RtlCopyMemory((PVOID)Current, Owner, OwnerLength);
+ RelSd->Owner = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
+ Current += OwnerLength;
+ }
+
+ /* Is there a group? */
+ if (GroupLength)
+ {
+ /* Copy it */
+ RtlCopyMemory((PVOID)Current, Group, GroupLength);
+ RelSd->Group = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
+ }
+
+ /* Mark it as relative */
+ RelSd->Control |= SE_SELF_RELATIVE;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -817,30 +751,18 @@
IN PSID PrimaryGroup,
IN PULONG PrimaryGroupSize)
{
- PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD;
- PISECURITY_DESCRIPTOR pRelSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
- ULONG OwnerLength;
- ULONG GroupLength;
- ULONG DaclLength;
- ULONG SaclLength;
- PSID pOwner;
- PSID pGroup;
- PACL pDacl;
- PACL pSacl;
-
- PAGED_CODE_RTL();
-
- if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (!(pRelSD->Control & SE_SELF_RELATIVE))
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
- RtlpQuerySecurityDescriptor(pRelSD,
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)AbsoluteSD;
+ PISECURITY_DESCRIPTOR RelSd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
+ ULONG OwnerLength, GroupLength, DaclLength, SaclLength;
+ PSID pOwner, pGroup;
+ PACL pDacl, pSacl;
+ PAGED_CODE_RTL();
+
+ /* Must be relative, otherwiise fail */
+ if (!(RelSd->Control & SE_SELF_RELATIVE)) return
STATUS_BAD_DESCRIPTOR_FORMAT;
+
+ /* Get all the components */
+ RtlpQuerySecurityDescriptor(RelSd,
&pOwner,
&OwnerLength,
&pGroup,
@@ -850,11 +772,16 @@
&pSacl,
&SaclLength);
- if (OwnerLength > *OwnerSize ||
- GroupLength > *PrimaryGroupSize ||
- DaclLength > *DaclSize ||
- SaclLength > *SaclSize)
- {
+ /* Fail if there's not enough space */
+ if (!(Sd) ||
+ (sizeof(SECURITY_DESCRIPTOR) > *AbsoluteSDSize) ||
+ (OwnerLength > *OwnerSize) ||
+ (GroupLength > *PrimaryGroupSize) ||
+ (DaclLength > *DaclSize) ||
+ (SaclLength > *SaclSize))
+ {
+ /* Return how much space is needed for each components */
+ *AbsoluteSDSize = sizeof(SECURITY_DESCRIPTOR);
*OwnerSize = OwnerLength;
*PrimaryGroupSize = GroupLength;
*DaclSize = DaclLength;
@@ -862,27 +789,51 @@
return STATUS_BUFFER_TOO_SMALL;
}
- RtlCopyMemory(Owner, pOwner, OwnerLength);
- RtlCopyMemory(PrimaryGroup, pGroup, GroupLength);
- RtlCopyMemory(Dacl, pDacl, DaclLength);
- RtlCopyMemory(Sacl, pSacl, SaclLength);
-
- pAbsSD->Revision = pRelSD->Revision;
- pAbsSD->Sbz1 = pRelSD->Sbz1;
- pAbsSD->Control = pRelSD->Control & ~SE_SELF_RELATIVE;
- pAbsSD->Owner = Owner;
- pAbsSD->Group = PrimaryGroup;
- pAbsSD->Dacl = Dacl;
- pAbsSD->Sacl = Sacl;
-
- *OwnerSize = OwnerLength;
- *PrimaryGroupSize = GroupLength;
- *DaclSize = DaclLength;
- *SaclSize = SaclLength;
-
- return STATUS_SUCCESS;
-}
-
+ /* Copy the header fields */
+ RtlMoveMemory(Sd, RelSd, sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+
+ /* Wipe out the pointers and the relative flag */
+ Sd->Owner = NULL;
+ Sd->Group = NULL;
+ Sd->Sacl = NULL;
+ Sd->Dacl = NULL;
+ Sd->Control &= ~SE_SELF_RELATIVE;
+
+ /* Is there an owner? */
+ if (pOwner)
+ {
+ /* Copy it */
+ RtlMoveMemory(Owner, pOwner, RtlLengthSid(pOwner));
+ Sd->Owner = Owner;
+ }
+
+ /* Is there a group? */
+ if (pGroup)
+ {
+ /* Copy it */
+ RtlMoveMemory(PrimaryGroup, pGroup, RtlLengthSid(pGroup));
+ Sd->Group = PrimaryGroup;
+ }
+
+ /* Is there a DACL? */
+ if (pDacl)
+ {
+ /* Copy it */
+ RtlMoveMemory(Dacl, pDacl, pDacl->AclSize);
+ Sd->Dacl = Dacl;
+ }
+
+ /* Is there a SACL? */
+ if (pSacl)
+ {
+ /* Copy it */
+ RtlMoveMemory(Sacl, pSacl, pSacl->AclSize);
+ Sd->Sacl = Sacl;
+ }
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
/*
* @implemented
@@ -892,47 +843,26 @@
RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
OUT PULONG BufferSize)
{
- PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
- PISECURITY_DESCRIPTOR_RELATIVE pRelSD =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
-#ifdef _WIN64
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
+ PISECURITY_DESCRIPTOR_RELATIVE RelSd =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD;
PVOID DataStart, DataEnd;
- ULONG DataSize;
LONG MoveDelta;
- ULONG OwnerLength;
- ULONG GroupLength;
- ULONG DaclLength;
- ULONG SaclLength;
-#endif
- PSID pOwner;
- PSID pGroup;
- PACL pDacl;
- PACL pSacl;
-
- PAGED_CODE_RTL();
-
- if (SelfRelativeSD == NULL)
- {
- return STATUS_INVALID_PARAMETER_1;
- }
-
- if (BufferSize == NULL)
- {
- return STATUS_INVALID_PARAMETER_2;
- }
-
- if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- {
- return STATUS_UNKNOWN_REVISION;
- }
-
- if (!(pRelSD->Control & SE_SELF_RELATIVE))
- {
- return STATUS_BAD_DESCRIPTOR_FORMAT;
- }
-
-#ifdef _WIN64
-
- RtlpQuerySecurityDescriptor((PISECURITY_DESCRIPTOR)pRelSD,
+ ULONG DataSize, OwnerLength, GroupLength, DaclLength, SaclLength;
+ PSID pOwner, pGroup;
+ PACL pDacl, pSacl;
+ PAGED_CODE_RTL();
+
+ /* Need input */
+ if (!RelSd) return STATUS_INVALID_PARAMETER_1;
+
+ /* Need to know how much space we have */
+ if (!BufferSize) return STATUS_INVALID_PARAMETER_2;
+
+ /* Input must be relative */
+ if (!(RelSd->Control & SE_SELF_RELATIVE)) return
STATUS_BAD_DESCRIPTOR_FORMAT;
+
+ /* Query all the component sizes */
+ RtlpQuerySecurityDescriptor(Sd,
&pOwner,
&OwnerLength,
&pGroup,
@@ -942,272 +872,334 @@
&pSacl,
&SaclLength);
- /* calculate the start and end of the data area, we simply just move the
- data by the difference between the size of the relative and absolute
- security descriptor structure */
+ /*
+ * Check if there's a difference in structure layout between relatiev and
+ * absolute descriptors. On 32-bit, there won't be, since an offset is the
+ * same size as a pointer (32-bit), but on 64-bit, the offsets remain 32-bit
+ * as they are not SIZE_T, but ULONG, while the pointers now become 64-bit
+ * and thus the structure is different */
+ MoveDelta = sizeof(SECURITY_DESCRIPTOR) - sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+ if (!MoveDelta)
+ {
+ /* So on 32-bit, simply clear the flag... */
+ Sd->Control &= ~SE_SELF_RELATIVE;
+
+ /* Ensure we're *really* on 32-bit */
+ ASSERT(sizeof(Sd->Owner) == sizeof(RelSd->Owner));
+ ASSERT(sizeof(Sd->Group) == sizeof(RelSd->Group));
+ ASSERT(sizeof(Sd->Sacl) == sizeof(RelSd->Sacl));
+ ASSERT(sizeof(Sd->Dacl) == sizeof(RelSd->Dacl));
+
+ /* And simply set pointers where there used to be offsets */
+ Sd->Owner = pOwner;
+ Sd->Group = pGroup;
+ Sd->Sacl = pSacl;
+ Sd->Dacl = pDacl;
+ return STATUS_SUCCESS;
+ }
+
+ /*
+ * Calculate the start and end of the data area, we simply just move the
+ * data by the difference between the size of the relative and absolute
+ * security descriptor structure
+ */
DataStart = pOwner;
DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
- if (pGroup != NULL)
- {
- if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || DataStart == NULL)
+
+ /* Is there a group? */
+ if (pGroup)
+ {
+ /* Is the group higher than where we started? */
+ if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || !DataStart)
+ {
+ /* Update the start pointer */
DataStart = pGroup;
-
- if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || DataEnd ==
NULL)
+ }
+
+ /* Is the group beyond where we ended? */
+ if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || !DataEnd)
+ {
+ /* Update the end pointer */
DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
- }
- if (pDacl != NULL)
- {
- if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || DataStart == NULL)
+ }
+ }
+
+ /* Is there a DACL? */
+ if (pDacl)
+ {
+ /* Is the DACL higher than where we started? */
+ if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || !DataStart)
+ {
+ /* Update the start pointer */
DataStart = pDacl;
-
- if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
+ }
+
+ /* Is the DACL beyond where we ended? */
+ if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
+ {
+ /* Update the end pointer */
DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
- }
- if (pSacl != NULL)
- {
- if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || DataStart == NULL)
+ }
+ }
+
+ /* Is there a SACL? */
+ if (pSacl)
+ {
+ /* Is the SACL higher than where we started? */
+ if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || !DataStart)
+ {
+ /* Update the start pointer */
DataStart = pSacl;
-
- if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
+ }
+
+ /* Is the SACL beyond where we ended? */
+ if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
+ {
+ /* Update the end pointer */
DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
- }
-
+ }
+ }
+
+ /* Sanity check */
ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
+ /* Now compute the difference between relative and absolute */
DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
+ /* Is the new buffer large enough for this difference? */
if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
{
+ /* Nope, bail out */
*BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
return STATUS_BUFFER_TOO_SMALL;
}
- if (DataSize != 0)
- {
- /* if DataSize != 0 ther must be at least one SID or ACL in the security
- descriptor! Also the data area must be located somewhere after the
- end of the SECURITY_DESCRIPTOR_RELATIVE structure */
+ /* Is there anything actually to copy? */
+ if (DataSize)
+ {
+ /*
+ * There must be at least one SID or ACL in the security descriptor!
+ * Also the data area must be located somewhere after the end of the
+ * SECURITY_DESCRIPTOR_RELATIVE structure
+ */
ASSERT(DataStart != NULL);
- ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(pRelSD + 1));
-
- /* it's time to move the data */
- RtlMoveMemory((PVOID)(pAbsSD + 1),
+ ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSd + 1));
+
+ /* It's time to move the data */
+ RtlMoveMemory((PVOID)(Sd + 1),
DataStart,
DataSize);
-
- MoveDelta = (LONG)((LONG_PTR)(pAbsSD + 1) - (LONG_PTR)DataStart);
-
- /* adjust the pointers if neccessary */
- if (pOwner != NULL)
- pAbsSD->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
- else
- pAbsSD->Owner = NULL;
-
- if (pGroup != NULL)
- pAbsSD->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
- else
- pAbsSD->Group = NULL;
-
- if (pSacl != NULL)
- pAbsSD->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
- else
- pAbsSD->Sacl = NULL;
-
- if (pDacl != NULL)
- pAbsSD->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
- else
- pAbsSD->Dacl = NULL;
+ }
+
+ /* Is there an owner? */
+ if (pOwner)
+ {
+ /* Set the pointer to the relative position */
+ Sd->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
}
else
{
- /* all pointers must be NULL! */
- ASSERT(pOwner == NULL);
- ASSERT(pGroup == NULL);
- ASSERT(pSacl == NULL);
- ASSERT(pDacl == NULL);
-
- pAbsSD->Owner = NULL;
- pAbsSD->Group = NULL;
- pAbsSD->Sacl = NULL;
- pAbsSD->Dacl = NULL;
- }
-
- /* clear the self-relative flag */
- pAbsSD->Control &= ~SE_SELF_RELATIVE;
-
-#else
-
- RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)pRelSD,
- &pOwner,
- &pGroup,
- &pSacl,
- &pDacl);
-
- /* clear the self-relative flag and simply convert the offsets to pointers */
- pAbsSD->Control &= ~SE_SELF_RELATIVE;
- pAbsSD->Owner = pOwner;
- pAbsSD->Group = pGroup;
- pAbsSD->Sacl = pSacl;
- pAbsSD->Dacl = pDacl;
-
-#endif
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN NTAPI
+ /* No owner, clear the pointer */
+ Sd->Owner = NULL;
+ }
+
+ /* Is there a group */
+ if (pGroup)
+ {
+ /* Set the pointer to the relative position */
+ Sd->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
+ }
+ else
+ {
+ /* No group, clear the pointer */
+ Sd->Group = NULL;
+ }
+
+ /* Is there a SACL? */
+ if (pSacl)
+ {
+ /* Set the pointer to the relative position */
+ Sd->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
+ }
+ else
+ {
+ /* No SACL, clear the pointer */
+ Sd->Sacl = NULL;
+ }
+
+ /* Is there a DACL? */
+ if (pDacl)
+ {
+ /* Set the pointer to the relative position */
+ Sd->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
+ }
+ else
+ {
+ /* No DACL, clear the pointer */
+ Sd->Dacl = NULL;
+ }
+
+ /* Clear the self-relative flag */
+ Sd->Control &= ~SE_SELF_RELATIVE;
+
+ /* All good */
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+ PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
+ PSID Owner, Group;
+ PACL Sacl, Dacl;
+ PAGED_CODE_RTL();
+
+ _SEH2_TRY
+ {
+ /* Fail on bad revisions */
+ if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return FALSE;
+
+ /* Owner SID must be valid if present */
+ Owner = SepGetOwnerFromDescriptor(Sd);
+ if ((Owner) && (!RtlValidSid(Owner))) return FALSE;
+
+ /* Group SID must be valid if present */
+ Group = SepGetGroupFromDescriptor(Sd);
+ if ((Owner) && (!RtlValidSid(Group))) return FALSE;
+
+ /* DACL must be valid if present */
+ Dacl = SepGetDaclFromDescriptor(Sd);
+ if ((Dacl) && (!RtlValidAcl(Dacl))) return FALSE;
+
+ /* SACL must be valid if present */
+ Sacl = SepGetSaclFromDescriptor(Sd);
+ if ((Sacl) && (!RtlValidAcl(Sacl))) return FALSE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Access fault, bail out */
+ return FALSE;
+ }
+ _SEH2_END;
+
+ /* All good */
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
IN ULONG SecurityDescriptorLength,
IN SECURITY_INFORMATION RequiredInformation)
{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptorInput;
- PSID Owner;
- PSID Group;
-
- PAGED_CODE_RTL();
-
- if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
- pSD->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
- !(pSD->Control & SE_SELF_RELATIVE))
- {
- return FALSE;
- }
-
- if (pSD->Owner != 0)
- {
- Owner = (PSID)((ULONG_PTR)pSD->Owner + (ULONG_PTR)pSD);
- if (!RtlValidSid(Owner))
- {
- return FALSE;
- }
- }
- else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
- {
- return FALSE;
- }
-
- if (pSD->Group != 0)
- {
- Group = (PSID)((ULONG_PTR)pSD->Group + (ULONG_PTR)pSD);
- if (!RtlValidSid(Group))
- {
- return FALSE;
- }
- }
- else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
- {
- return FALSE;
- }
-
- if (pSD->Control & SE_DACL_PRESENT)
- {
- if (pSD->Dacl != 0 &&
- !RtlValidAcl((PACL)((ULONG_PTR)pSD->Dacl + (ULONG_PTR)pSD)))
- {
- return FALSE;
- }
- }
- else if (RequiredInformation & DACL_SECURITY_INFORMATION)
- {
- return FALSE;
- }
-
- if (pSD->Control & SE_SACL_PRESENT)
- {
- if (pSD->Sacl != 0 &&
- !RtlValidAcl((PACL)((ULONG_PTR)pSD->Sacl + (ULONG_PTR)pSD)))
- {
- return FALSE;
- }
- }
- else if (RequiredInformation & SACL_SECURITY_INFORMATION)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN
-NTAPI
-RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- OUT PUCHAR RMControl)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (!(pSD->Control & SE_RM_CONTROL_VALID))
- {
- *RMControl = 0;
+ PISECURITY_DESCRIPTOR_RELATIVE Sd =
(PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptorInput;
+ PSID Owner, Group;
+ PACL Dacl, Sacl;
+ ULONG Length;
+ PAGED_CODE_RTL();
+
+ /* Note that Windows allows no DACL/SACL even if RequiredInfo wants it */
+
+ /* Do we have enough space, is the revision vaild, and is this SD relative? */
+ if ((SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) ||
+ (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) ||
+ !(Sd->Control & SE_SELF_RELATIVE))
+ {
+ /* Nope, bail out */
return FALSE;
}
- *RMControl = pSD->Sbz1;
-
+ /* Is there an owner? */
+ if (Sd->Owner)
+ {
+ /* Try to access it */
+ if (!RtlpValidateSDOffsetAndSize(Sd->Owner,
+ SecurityDescriptorLength,
+ sizeof(SID),
+ &Length))
+ {
+ /* It's beyond the buffer, fail */
+ return FALSE;
+ }
+
+ /* Read the owner, check if it's valid and if the buffer contains it */
+ Owner = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
+ if (!RtlValidSid(Owner) || (Length < RtlLengthSid(Owner))) return FALSE;
+ }
+ else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
+ {
+ /* No owner but the caller expects one, fail */
+ return FALSE;
+ }
+
+ /* Is there a group? */
+ if (Sd->Group)
+ {
+ /* Try to access it */
+ if (!RtlpValidateSDOffsetAndSize(Sd->Group,
+ SecurityDescriptorLength,
+ sizeof(SID),
+ &Length))
+ {
+ /* It's beyond the buffer, fail */
+ return FALSE;
+ }
+
+ /* Read the group, check if it's valid and if the buffer contains it */
+ Group = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
+ if (!RtlValidSid(Group) || (Length < RtlLengthSid(Group))) return FALSE;
+ }
+ else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
+ {
+ /* No group, but the caller expects one, fail */
+ return FALSE;
+ }
+
+ /* Is there a DACL? */
+ if (Sd->Control & SE_DACL_PRESENT)
+ {
+ /* Try to access it */
+ if (!RtlpValidateSDOffsetAndSize(Sd->Dacl,
+ SecurityDescriptorLength,
+ sizeof(ACL),
+ &Length))
+ {
+ /* It's beyond the buffer, fail */
+ return FALSE;
+ }
+
+ /* Read the DACL, check if it's valid and if the buffer contains it */
+ Dacl = (PSID)((ULONG_PTR)Sd->Dacl + (ULONG_PTR)Sd);
+ if (!(RtlValidAcl(Dacl)) || (Length < Dacl->AclSize)) return FALSE;
+ }
+
+ /* Is there a SACL? */
+ if (Sd->Control & SE_SACL_PRESENT)
+ {
+ /* Try to access it */
+ if (!RtlpValidateSDOffsetAndSize(Sd->Sacl,
+ SecurityDescriptorLength,
+ sizeof(ACL),
+ &Length))
+ {
+ /* It's beyond the buffer, fail */
+ return FALSE;
+ }
+
+ /* Read the SACL, check if it's valid and if the buffer contains it */
+ Sacl = (PSID)((ULONG_PTR)Sd->Sacl + (ULONG_PTR)Sd);
+ if (!(RtlValidAcl(Sacl)) || (Length < Sacl->AclSize)) return FALSE;
+ }
+
+ /* All good */
return TRUE;
}
-
-/*
- * @implemented
- */
-VOID
-NTAPI
-RtlSetSecurityDescriptorRMControl(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN PUCHAR RMControl)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- if (RMControl == NULL)
- {
- pSD->Control &= ~SE_RM_CONTROL_VALID;
- pSD->Sbz1 = 0;
- }
- else
- {
- pSD->Control |= SE_RM_CONTROL_VALID;
- pSD->Sbz1 = *RMControl;
- }
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-RtlSetAttributesSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN SECURITY_DESCRIPTOR_CONTROL Control,
- OUT PULONG Revision)
-{
- PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
-
- PAGED_CODE_RTL();
-
- *Revision = pSD->Revision;
-
- if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
- return STATUS_UNKNOWN_REVISION;
-
- Control &=
- ~(SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED | SE_DACL_PRESENT |
- SE_DACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_DEFAULTED |
- SE_RM_CONTROL_VALID | SE_SELF_RELATIVE);
-
- return RtlSetControlSecurityDescriptor(SecurityDescriptor,
- Control,
- Control);
-}
-
/* EOF */