The structure layout of self-relative security descriptors may be different from absolute security descriptors depending on the platform. Self-relative security descriptors always use 32 bit offsets while absolute security descriptors use pointers which could be 64 bits.

svn path=/trunk/; revision=13502
This commit is contained in:
Thomas Bluemel 2005-02-12 11:47:03 +00:00
parent 18e42fda45
commit df616c9b3b
8 changed files with 351 additions and 363 deletions

View file

@ -521,7 +521,7 @@ PushEntryList (
NTSTATUS STDCALL NTSTATUS STDCALL
RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD, RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PULONG BufferLength); PULONG BufferLength);
NTSTATUS STDCALL NTSTATUS STDCALL
@ -852,6 +852,10 @@ NTSTATUS STDCALL
RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG Revision); ULONG Revision);
NTSTATUS STDCALL
RtlCreateSecurityDescriptorRelative (PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
ULONG Revision);
NTSTATUS NTSTATUS
STDCALL STDCALL
RtlCreateSystemVolumeInformationFolder( RtlCreateSystemVolumeInformationFolder(
@ -1999,7 +2003,7 @@ RtlLookupElementGenericTableFullAvl (
NTSTATUS STDCALL NTSTATUS STDCALL
RtlMakeSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD, RtlMakeSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PULONG BufferLength); PULONG BufferLength);
VOID STDCALL VOID STDCALL
@ -2261,7 +2265,7 @@ RtlSecondsSince1980ToTime (ULONG SecondsSince1980,
PLARGE_INTEGER Time); PLARGE_INTEGER Time);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR RelSD, RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PSECURITY_DESCRIPTOR AbsSD, PSECURITY_DESCRIPTOR AbsSD,
PULONG AbsSDSize, PULONG AbsSDSize,
PACL Dacl, PACL Dacl,
@ -2276,7 +2280,7 @@ RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR RelSD,
NTSTATUS NTSTATUS
STDCALL STDCALL
RtlSelfRelativeToAbsoluteSD2( RtlSelfRelativeToAbsoluteSD2(
PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor,
PULONG BufferSize PULONG BufferSize
); );
@ -2659,7 +2663,7 @@ RtlValidateHeap (
BOOLEAN BOOLEAN
STDCALL STDCALL
RtlValidRelativeSecurityDescriptor ( RtlValidRelativeSecurityDescriptor (
IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput,
IN ULONG SecurityDescriptorLength, IN ULONG SecurityDescriptorLength,
IN SECURITY_INFORMATION RequiredInformation IN SECURITY_INFORMATION RequiredInformation
); );

View file

@ -283,6 +283,17 @@ typedef struct _SECURITY_DESCRIPTOR
PACL Dacl; PACL Dacl;
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR; } SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
typedef struct _SECURITY_DESCRIPTOR_RELATIVE
{
UCHAR Revision;
UCHAR Sbz1;
SECURITY_DESCRIPTOR_CONTROL Control;
ULONG Owner;
ULONG Group;
ULONG Sacl;
ULONG Dacl;
} SECURITY_DESCRIPTOR_RELATIVE, *PSECURITY_DESCRIPTOR_RELATIVE;
typedef struct _LUID_AND_ATTRIBUTES typedef struct _LUID_AND_ATTRIBUTES
{ {
LUID Luid; LUID Luid;

View file

@ -258,7 +258,7 @@ MakeAbsoluteSD (
{ {
NTSTATUS Status; NTSTATUS Status;
Status = RtlSelfRelativeToAbsoluteSD (pSelfRelativeSecurityDescriptor, Status = RtlSelfRelativeToAbsoluteSD ((PSECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor,
pAbsoluteSecurityDescriptor, pAbsoluteSecurityDescriptor,
lpdwAbsoluteSecurityDescriptorSize, lpdwAbsoluteSecurityDescriptorSize,
pDacl, pDacl,
@ -293,7 +293,7 @@ MakeSelfRelativeSD (
NTSTATUS Status; NTSTATUS Status;
Status = RtlAbsoluteToSelfRelativeSD (pAbsoluteSecurityDescriptor, Status = RtlAbsoluteToSelfRelativeSD (pAbsoluteSecurityDescriptor,
pSelfRelativeSecurityDescriptor, (PSECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor,
(PULONG)lpdwBufferLength); (PULONG)lpdwBufferLength);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -17,6 +17,95 @@
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
static VOID
RtlpQuerySecurityDescriptorPointers(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
OUT PSID *Owner OPTIONAL,
OUT PSID *Group OPTIONAL,
OUT PACL *Sacl OPTIONAL,
OUT PACL *Dacl OPTIONAL)
{
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_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);
}
}
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(PSECURITY_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 * @implemented
*/ */
@ -41,54 +130,61 @@ RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
} }
NTSTATUS STDCALL
RtlCreateSecurityDescriptorRelative (PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
ULONG Revision)
{
if (Revision != SECURITY_DESCRIPTOR_REVISION1)
{
return STATUS_UNKNOWN_REVISION;
}
SecurityDescriptor->Revision = Revision;
SecurityDescriptor->Sbz1 = 0;
SecurityDescriptor->Control = SE_SELF_RELATIVE;
SecurityDescriptor->Owner = 0;
SecurityDescriptor->Group = 0;
SecurityDescriptor->Sacl = 0;
SecurityDescriptor->Dacl = 0;
return STATUS_SUCCESS;
}
/* /*
* @implemented * @implemented
*/ */
ULONG STDCALL ULONG STDCALL
RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{ {
PSID Owner, Group;
PACL Sacl, Dacl;
ULONG Length = sizeof(SECURITY_DESCRIPTOR); ULONG Length = sizeof(SECURITY_DESCRIPTOR);
RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
&Owner,
&Group,
&Sacl,
&Dacl);
if (SecurityDescriptor->Owner != NULL) if (Owner != NULL)
{ {
PSID Owner = SecurityDescriptor->Owner; Length += ROUND_UP(RtlLengthSid(Owner), 4);
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Owner = (PSID)((ULONG_PTR)Owner + (ULONG_PTR)SecurityDescriptor);
}
Length = Length + ROUND_UP(RtlLengthSid(Owner), 4);
} }
if (SecurityDescriptor->Group != NULL) if (Group != NULL)
{ {
PSID Group = SecurityDescriptor->Group; Length += ROUND_UP(RtlLengthSid(Group), 4);
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Group = (PSID)((ULONG_PTR)Group + (ULONG_PTR)SecurityDescriptor);
}
Length = Length + ROUND_UP(RtlLengthSid(Group), 4);
} }
if (SecurityDescriptor->Control & SE_DACL_PRESENT && if (Dacl != NULL)
SecurityDescriptor->Dacl != NULL)
{ {
PACL Dacl = SecurityDescriptor->Dacl; Length += ROUND_UP(Dacl->AclSize, 4);
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Dacl = (PACL)((ULONG_PTR)Dacl + (ULONG_PTR)SecurityDescriptor);
}
Length = Length + ROUND_UP(Dacl->AclSize, 4);
} }
if (SecurityDescriptor->Control & SE_SACL_PRESENT && if (Sacl != NULL)
SecurityDescriptor->Sacl != NULL)
{ {
PACL Sacl = SecurityDescriptor->Sacl; Length += ROUND_UP(Sacl->AclSize, 4);
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Sacl = (PACL)((ULONG_PTR)Sacl + (ULONG_PTR)SecurityDescriptor);
}
Length = Length + ROUND_UP(Sacl->AclSize, 4);
} }
return Length; return Length;
@ -116,27 +212,13 @@ RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
} }
*DaclPresent = TRUE; *DaclPresent = TRUE;
if (SecurityDescriptor->Dacl == NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
{ NULL,
*Dacl = NULL; NULL,
} NULL,
else Dacl);
{
*Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Dacl = (PACL)((ULONG_PTR)*Dacl + (ULONG_PTR)SecurityDescriptor);
}
}
if (SecurityDescriptor->Control & SE_DACL_DEFAULTED) *DaclDefaulted = ((SecurityDescriptor->Control & SE_DACL_DEFAULTED) ? TRUE : FALSE);
{
*DaclDefaulted = TRUE;
}
else
{
*DaclDefaulted = FALSE;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -186,67 +268,26 @@ RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
BOOLEAN STDCALL BOOLEAN STDCALL
RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{ {
PSID Owner, Group;
PACL Sacl, Dacl;
if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
{ {
return FALSE; return FALSE;
} }
RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
&Owner,
&Group,
&Sacl,
&Dacl);
if (SecurityDescriptor->Owner != NULL) if ((Owner != NULL && !RtlValidSid(Owner)) ||
(Group != NULL && !RtlValidSid(Group)) ||
(Sacl != NULL && !RtlValidAcl(Sacl)) ||
(Dacl != NULL && !RtlValidAcl(Dacl)))
{ {
PSID Owner = SecurityDescriptor->Owner; return FALSE;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Owner = (PSID)((ULONG_PTR)Owner + (ULONG_PTR)SecurityDescriptor);
}
if (!RtlValidSid(Owner))
{
return FALSE;
}
}
if (SecurityDescriptor->Group != NULL)
{
PSID Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Group = (PSID)((ULONG_PTR)Group + (ULONG_PTR)SecurityDescriptor);
}
if (!RtlValidSid(Group))
{
return FALSE;
}
}
if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
SecurityDescriptor->Dacl != NULL)
{
PACL Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Dacl = (PACL)((ULONG_PTR)Dacl + (ULONG_PTR)SecurityDescriptor);
}
if (!RtlValidAcl(Dacl))
{
return FALSE;
}
}
if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
SecurityDescriptor->Sacl != NULL)
{
PACL Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Sacl = (PACL)((ULONG_PTR)Sacl + (ULONG_PTR)SecurityDescriptor);
}
if (!RtlValidAcl(Sacl))
{
return FALSE;
}
} }
return TRUE; return TRUE;
@ -296,27 +337,13 @@ RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return STATUS_UNKNOWN_REVISION; return STATUS_UNKNOWN_REVISION;
} }
if (SecurityDescriptor->Owner != NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
{ Owner,
*Owner = SecurityDescriptor->Owner; NULL,
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) NULL,
{ NULL);
*Owner = (PSID)((ULONG_PTR)*Owner + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Owner = NULL;
}
if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED) *OwnerDefaulted = ((SecurityDescriptor->Control & SE_OWNER_DEFAULTED) ? TRUE : FALSE);
{
*OwnerDefaulted = TRUE;
}
else
{
*OwnerDefaulted = FALSE;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -364,142 +391,25 @@ RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return STATUS_UNKNOWN_REVISION; return STATUS_UNKNOWN_REVISION;
} }
if (SecurityDescriptor->Group != NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
{ NULL,
*Group = SecurityDescriptor->Group; Group,
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) NULL,
{ NULL);
*Group = (PSID)((ULONG_PTR)*Group + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Group = NULL;
}
if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED) *GroupDefaulted = ((SecurityDescriptor->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE);
{
*GroupDefaulted = TRUE;
}
else
{
*GroupDefaulted = FALSE;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static VOID
RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID* Owner,
PULONG OwnerLength,
PSID* Group,
PULONG GroupLength,
PACL* Dacl,
PULONG DaclLength,
PACL* Sacl,
PULONG SaclLength)
{
if (SecurityDescriptor->Owner != NULL)
{
*Owner = SecurityDescriptor->Owner;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Owner = (PSID)((ULONG_PTR)*Owner + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Owner = NULL;
}
if (*Owner != NULL)
{
*OwnerLength = ROUND_UP(RtlLengthSid(*Owner), 4);
}
else
{
*OwnerLength = 0;
}
if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
SecurityDescriptor->Dacl != NULL)
{
*Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Dacl = (PACL)((ULONG_PTR)*Dacl + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Dacl = NULL;
}
if (*Dacl != NULL)
{
*DaclLength = ROUND_UP((*Dacl)->AclSize, 4);
}
else
{
*DaclLength = 0;
}
if (SecurityDescriptor->Group != NULL)
{
*Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Group = (PSID)((ULONG_PTR)*Group + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Group = NULL;
}
if (*Group != NULL)
{
*GroupLength = ROUND_UP(RtlLengthSid(*Group), 4);
}
else
{
*GroupLength = 0;
}
if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
SecurityDescriptor->Sacl != NULL)
{
*Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Sacl = (PACL)((ULONG_PTR)*Sacl + (ULONG_PTR)SecurityDescriptor);
}
}
else
{
*Sacl = NULL;
}
if (*Sacl != NULL)
{
*SaclLength = ROUND_UP((*Sacl)->AclSize, 4);
}
else
{
*SaclLength = 0;
}
}
/* /*
* @implemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PULONG BufferLength) PULONG BufferLength)
{ {
PSID Owner; PSID Owner;
PSID Group; PSID Group;
@ -522,7 +432,7 @@ RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
&Sacl, &Sacl,
&SaclLength); &SaclLength);
TotalLength = OwnerLength + GroupLength + SaclLength + DaclLength + sizeof(SECURITY_DESCRIPTOR); TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength;
if (*BufferLength < TotalLength) if (*BufferLength < TotalLength)
{ {
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
@ -530,48 +440,48 @@ RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
RtlZeroMemory(RelSD, RtlZeroMemory(RelSD,
TotalLength); TotalLength);
memmove(RelSD,
AbsSD, RelSD->Revision = AbsSD->Revision;
sizeof(SECURITY_DESCRIPTOR)); RelSD->Sbz1 = AbsSD->Sbz1;
Current = (ULONG_PTR)RelSD + sizeof(SECURITY_DESCRIPTOR); RelSD->Control = AbsSD->Control | SE_SELF_RELATIVE;
Current = (ULONG_PTR)(RelSD + 1);
if (SaclLength != 0) if (SaclLength != 0)
{ {
memmove((PVOID)Current, RtlCopyMemory((PVOID)Current,
Sacl, Sacl,
SaclLength); SaclLength);
RelSD->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)RelSD); RelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
Current += SaclLength; Current += SaclLength;
} }
if (DaclLength != 0) if (DaclLength != 0)
{ {
memmove((PVOID)Current, RtlCopyMemory((PVOID)Current,
Dacl, Dacl,
DaclLength); DaclLength);
RelSD->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)RelSD); RelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
Current += DaclLength; Current += DaclLength;
} }
if (OwnerLength != 0) if (OwnerLength != 0)
{ {
memmove((PVOID)Current, RtlCopyMemory((PVOID)Current,
Owner, Owner,
OwnerLength); OwnerLength);
RelSD->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)RelSD); RelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
Current += OwnerLength; Current += OwnerLength;
} }
if (GroupLength != 0) if (GroupLength != 0)
{ {
memmove((PVOID)Current, RtlCopyMemory((PVOID)Current,
Group, Group,
GroupLength); GroupLength);
RelSD->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)RelSD); RelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
} }
RelSD->Control |= SE_SELF_RELATIVE;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -581,7 +491,7 @@ RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PULONG BufferLength) PULONG BufferLength)
{ {
if (AbsSD->Control & SE_SELF_RELATIVE) if (AbsSD->Control & SE_SELF_RELATIVE)
@ -658,27 +568,13 @@ RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
} }
*SaclPresent = TRUE; *SaclPresent = TRUE;
if (SecurityDescriptor->Sacl == NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
{ NULL,
*Sacl = NULL; NULL,
} Sacl,
else NULL);
{
*Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Sacl = (PACL)((ULONG_PTR)*Sacl + (ULONG_PTR)SecurityDescriptor);
}
}
if (SecurityDescriptor->Control & SE_SACL_DEFAULTED) *SaclDefaulted = ((SecurityDescriptor->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE);
{
*SaclDefaulted = TRUE;
}
else
{
*SaclDefaulted = FALSE;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -726,7 +622,7 @@ RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
* @implemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD, RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR_RELATIVE RelSD,
PSECURITY_DESCRIPTOR AbsSD, PSECURITY_DESCRIPTOR AbsSD,
PDWORD AbsSDSize, PDWORD AbsSDSize,
PACL Dacl, PACL Dacl,
@ -747,10 +643,17 @@ RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
PACL pDacl; PACL pDacl;
PACL pSacl; PACL pSacl;
if (!(RelSD->Control & SE_SELF_RELATIVE)) if (RelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
return STATUS_BAD_DESCRIPTOR_FORMAT; {
return STATUS_UNKNOWN_REVISION;
}
RtlpQuerySecurityDescriptor (RelSD, if (!(RelSD->Control & SE_SELF_RELATIVE))
{
return STATUS_BAD_DESCRIPTOR_FORMAT;
}
RtlpQuerySecurityDescriptor ((PSECURITY_DESCRIPTOR)RelSD,
&pOwner, &pOwner,
&OwnerLength, &OwnerLength,
&pGroup, &pGroup,
@ -764,16 +667,18 @@ RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
GroupLength > *GroupSize || GroupLength > *GroupSize ||
DaclLength > *DaclSize || DaclLength > *DaclSize ||
SaclLength > *SaclSize) SaclLength > *SaclSize)
{
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
}
memmove (Owner, pOwner, OwnerLength); RtlCopyMemory (Owner, pOwner, OwnerLength);
memmove (Group, pGroup, GroupLength); RtlCopyMemory (Group, pGroup, GroupLength);
memmove (Dacl, pDacl, DaclLength); RtlCopyMemory (Dacl, pDacl, DaclLength);
memmove (Sacl, pSacl, SaclLength); RtlCopyMemory (Sacl, pSacl, SaclLength);
memmove (AbsSD, RelSD, sizeof (SECURITY_DESCRIPTOR)); AbsSD->Revision = RelSD->Revision;
AbsSD->Sbz1 = RelSD->Sbz1;
AbsSD->Control &= ~SE_SELF_RELATIVE; AbsSD->Control = RelSD->Control & ~SE_SELF_RELATIVE;
AbsSD->Owner = Owner; AbsSD->Owner = Owner;
AbsSD->Group = Group; AbsSD->Group = Group;
AbsSD->Dacl = Dacl; AbsSD->Dacl = Dacl;
@ -792,7 +697,7 @@ RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
* @unimplemented * @unimplemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor,
PULONG BufferSize) PULONG BufferSize)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
@ -804,18 +709,18 @@ RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
* @implemented * @implemented
*/ */
BOOLEAN STDCALL BOOLEAN STDCALL
RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput,
IN ULONG SecurityDescriptorLength, IN ULONG SecurityDescriptorLength,
IN SECURITY_INFORMATION RequiredInformation) IN SECURITY_INFORMATION RequiredInformation)
{ {
if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR) || if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
SecurityDescriptorInput->Revision != SECURITY_DESCRIPTOR_REVISION1 || SecurityDescriptorInput->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
!(SecurityDescriptorInput->Control & SE_SELF_RELATIVE)) !(SecurityDescriptorInput->Control & SE_SELF_RELATIVE))
{ {
return FALSE; return FALSE;
} }
if (SecurityDescriptorInput->Owner != NULL) if (SecurityDescriptorInput->Owner != 0)
{ {
PSID Owner = (PSID)((ULONG_PTR)SecurityDescriptorInput->Owner + (ULONG_PTR)SecurityDescriptorInput); PSID Owner = (PSID)((ULONG_PTR)SecurityDescriptorInput->Owner + (ULONG_PTR)SecurityDescriptorInput);
if (!RtlValidSid(Owner)) if (!RtlValidSid(Owner))
@ -828,7 +733,7 @@ RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInp
return FALSE; return FALSE;
} }
if (SecurityDescriptorInput->Group != NULL) if (SecurityDescriptorInput->Group != 0)
{ {
PSID Group = (PSID)((ULONG_PTR)SecurityDescriptorInput->Group + (ULONG_PTR)SecurityDescriptorInput); PSID Group = (PSID)((ULONG_PTR)SecurityDescriptorInput->Group + (ULONG_PTR)SecurityDescriptorInput);
if (!RtlValidSid(Group)) if (!RtlValidSid(Group))
@ -843,7 +748,7 @@ RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInp
if (SecurityDescriptorInput->Control & SE_DACL_PRESENT) if (SecurityDescriptorInput->Control & SE_DACL_PRESENT)
{ {
if (SecurityDescriptorInput->Dacl != NULL && if (SecurityDescriptorInput->Dacl != 0 &&
!RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Dacl + (ULONG_PTR)SecurityDescriptorInput))) !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Dacl + (ULONG_PTR)SecurityDescriptorInput)))
{ {
return FALSE; return FALSE;
@ -856,7 +761,7 @@ RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInp
if (SecurityDescriptorInput->Control & SE_SACL_PRESENT) if (SecurityDescriptorInput->Control & SE_SACL_PRESENT)
{ {
if (SecurityDescriptorInput->Sacl != NULL && if (SecurityDescriptorInput->Sacl != 0 &&
!RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Sacl + (ULONG_PTR)SecurityDescriptorInput))) !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Sacl + (ULONG_PTR)SecurityDescriptorInput)))
{ {
return FALSE; return FALSE;

View file

@ -126,7 +126,7 @@ SeCaptureSecurityDescriptor(
ULONG OwnerSAC = 0, GroupSAC = 0; ULONG OwnerSAC = 0, GroupSAC = 0;
ULONG OwnerSize = 0, GroupSize = 0; ULONG OwnerSize = 0, GroupSize = 0;
ULONG SaclSize = 0, DaclSize = 0; ULONG SaclSize = 0, DaclSize = 0;
ULONG DescriptorSize = sizeof(SECURITY_DESCRIPTOR); ULONG DescriptorSize = 0;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
if(OriginalSecurityDescriptor != NULL) if(OriginalSecurityDescriptor != NULL)
@ -135,12 +135,49 @@ SeCaptureSecurityDescriptor(
{ {
_SEH_TRY _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, ProbeForRead(OriginalSecurityDescriptor,
sizeof(SECURITY_DESCRIPTOR), DescriptorSize,
sizeof(ULONG)); sizeof(ULONG));
if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
{
Status = STATUS_UNKNOWN_REVISION;
_SEH_LEAVE;
}
/* make a copy on the stack */ /* make a copy on the stack */
DescriptorCopy = *OriginalSecurityDescriptor; 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)
{
PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_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 _SEH_HANDLE
{ {
@ -165,13 +202,33 @@ SeCaptureSecurityDescriptor(
} }
else else
{ {
if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
{
return STATUS_UNKNOWN_REVISION;
}
/* make a copy on the stack */ /* make a copy on the stack */
DescriptorCopy = *OriginalSecurityDescriptor; DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
} DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
if(DescriptorCopy.Revision != SECURITY_DESCRIPTOR_REVISION1) DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
{ sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
return STATUS_UNKNOWN_REVISION; if(DescriptorCopy.Control & SE_SELF_RELATIVE)
{
PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_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) if(DescriptorCopy.Control & SE_SELF_RELATIVE)
@ -377,10 +434,11 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL) IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
{ {
PSECURITY_DESCRIPTOR ObjectSd; PSECURITY_DESCRIPTOR ObjectSd;
PSID Owner = 0; PSECURITY_DESCRIPTOR_RELATIVE RelSD;
PSID Group = 0; PSID Owner = NULL;
PACL Dacl = 0; PSID Group = NULL;
PACL Sacl = 0; PACL Dacl = NULL;
PACL Sacl = NULL;
ULONG OwnerLength = 0; ULONG OwnerLength = 0;
ULONG GroupLength = 0; ULONG GroupLength = 0;
ULONG DaclLength = 0; ULONG DaclLength = 0;
@ -388,19 +446,20 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
ULONG Control = 0; ULONG Control = 0;
ULONG_PTR Current; ULONG_PTR Current;
ULONG SdLength; ULONG SdLength;
RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
if (*ObjectsSecurityDescriptor == NULL) if (*ObjectsSecurityDescriptor == NULL)
{ {
if (*Length < sizeof(SECURITY_DESCRIPTOR)) if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
{ {
*Length = sizeof(SECURITY_DESCRIPTOR); *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
*Length = sizeof(SECURITY_DESCRIPTOR); *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
RtlCreateSecurityDescriptor(SecurityDescriptor, RtlCreateSecurityDescriptorRelative(RelSD,
SECURITY_DESCRIPTOR_REVISION); SECURITY_DESCRIPTOR_REVISION);
SecurityDescriptor->Control |= SE_SELF_RELATIVE;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -447,26 +506,26 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
} }
SdLength = OwnerLength + GroupLength + DaclLength + SdLength = OwnerLength + GroupLength + DaclLength +
SaclLength + sizeof(SECURITY_DESCRIPTOR); SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
if (*Length < sizeof(SECURITY_DESCRIPTOR)) if (*Length < SdLength)
{ {
*Length = SdLength; *Length = SdLength;
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
/* Build the new security descrtiptor */ /* Build the new security descrtiptor */
RtlCreateSecurityDescriptor(SecurityDescriptor, RtlCreateSecurityDescriptorRelative(RelSD,
SECURITY_DESCRIPTOR_REVISION); SECURITY_DESCRIPTOR_REVISION);
SecurityDescriptor->Control = Control; RelSD->Control = Control;
Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR); Current = (ULONG_PTR)(RelSD + 1);
if (OwnerLength != 0) if (OwnerLength != 0)
{ {
RtlCopyMemory((PVOID)Current, RtlCopyMemory((PVOID)Current,
Owner, Owner,
OwnerLength); OwnerLength);
SecurityDescriptor->Owner = (PSID)(Current - (ULONG_PTR)SecurityDescriptor); RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
Current += OwnerLength; Current += OwnerLength;
} }
@ -475,7 +534,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
RtlCopyMemory((PVOID)Current, RtlCopyMemory((PVOID)Current,
Group, Group,
GroupLength); GroupLength);
SecurityDescriptor->Group = (PSID)(Current - (ULONG_PTR)SecurityDescriptor); RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
Current += GroupLength; Current += GroupLength;
} }
@ -484,7 +543,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
RtlCopyMemory((PVOID)Current, RtlCopyMemory((PVOID)Current,
Dacl, Dacl,
DaclLength); DaclLength);
SecurityDescriptor->Dacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor); RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
Current += DaclLength; Current += DaclLength;
} }
@ -493,7 +552,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
RtlCopyMemory((PVOID)Current, RtlCopyMemory((PVOID)Current,
Sacl, Sacl,
SaclLength); SaclLength);
SecurityDescriptor->Sacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor); RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
Current += SaclLength; Current += SaclLength;
} }

View file

@ -3347,9 +3347,9 @@ NTSYSAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
RtlAbsoluteToSelfRelativeSD ( RtlAbsoluteToSelfRelativeSD (
IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor,
IN PULONG BufferLength IN PULONG BufferLength
); );
NTSYSAPI NTSYSAPI
@ -3593,17 +3593,17 @@ NTSYSAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
RtlSelfRelativeToAbsoluteSD ( RtlSelfRelativeToAbsoluteSD (
IN PSECURITY_DESCRIPTOR SelfRelativeSD, IN PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSD,
OUT PSECURITY_DESCRIPTOR AbsoluteSD, OUT PSECURITY_DESCRIPTOR AbsoluteSD,
IN PULONG AbsoluteSDSize, IN PULONG AbsoluteSDSize,
IN PACL Dacl, IN PACL Dacl,
IN PULONG DaclSize, IN PULONG DaclSize,
IN PACL Sacl, IN PACL Sacl,
IN PULONG SaclSize, IN PULONG SaclSize,
IN PSID Owner, IN PSID Owner,
IN PULONG OwnerSize, IN PULONG OwnerSize,
IN PSID PrimaryGroup, IN PSID PrimaryGroup,
IN PULONG PrimaryGroupSize IN PULONG PrimaryGroupSize
); );
#endif /* (VER_PRODUCTBUILD >= 2195) */ #endif /* (VER_PRODUCTBUILD >= 2195) */

View file

@ -5223,7 +5223,7 @@ NTOSAPI
BOOLEAN BOOLEAN
DDKAPI DDKAPI
RtlValidRelativeSecurityDescriptor( RtlValidRelativeSecurityDescriptor(
IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput,
IN ULONG SecurityDescriptorLength, IN ULONG SecurityDescriptorLength,
IN SECURITY_INFORMATION RequiredInformation); IN SECURITY_INFORMATION RequiredInformation);

View file

@ -2118,6 +2118,15 @@ typedef struct _SECURITY_DESCRIPTOR {
PACL Sacl; PACL Sacl;
PACL Dacl; PACL Dacl;
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR; } SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
typedef struct _SECURITY_DESCRIPTOR_RELATIVE {
UCHAR Revision;
UCHAR Sbz1;
SECURITY_DESCRIPTOR_CONTROL Control;
ULONG Owner;
ULONG Group;
ULONG Sacl;
ULONG Dacl;
} SECURITY_DESCRIPTOR_RELATIVE, *PSECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
typedef enum _TOKEN_INFORMATION_CLASS { typedef enum _TOKEN_INFORMATION_CLASS {
TokenUser=1,TokenGroups,TokenPrivileges,TokenOwner, TokenUser=1,TokenGroups,TokenPrivileges,TokenOwner,
TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType, TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType,