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);
if (SecurityDescriptor->Owner != NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
&Owner,
&Group,
&Sacl,
&Dacl);
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,68 +268,27 @@ 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;
} }
if (SecurityDescriptor->Owner != NULL) RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
{ &Owner,
PSID Owner = SecurityDescriptor->Owner; &Group,
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) &Sacl,
{ &Dacl);
Owner = (PSID)((ULONG_PTR)Owner + (ULONG_PTR)SecurityDescriptor);
}
if (!RtlValidSid(Owner)) if ((Owner != NULL && !RtlValidSid(Owner)) ||
(Group != NULL && !RtlValidSid(Group)) ||
(Sacl != NULL && !RtlValidAcl(Sacl)) ||
(Dacl != NULL && !RtlValidAcl(Dacl)))
{ {
return FALSE; 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,141 +391,24 @@ 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;
@ -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,15 +202,35 @@ SeCaptureSecurityDescriptor(
} }
else else
{ {
/* make a copy on the stack */ if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
DescriptorCopy = *OriginalSecurityDescriptor;
}
if(DescriptorCopy.Revision != SECURITY_DESCRIPTOR_REVISION1)
{ {
return STATUS_UNKNOWN_REVISION; return STATUS_UNKNOWN_REVISION;
} }
/* make a copy on the stack */
DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
{
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)
{ {
/* in case we're dealing with a self-relative descriptor, do a basic convert /* in case we're dealing with a self-relative descriptor, do a basic convert
@ -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;
@ -389,18 +447,19 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
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

@ -3348,7 +3348,7 @@ 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
); );
@ -3593,7 +3593,7 @@ 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,

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,