Implemented and fixed several ACL and SD functions.

Patch by Alexandru Matei.

svn path=/trunk/; revision=3330
This commit is contained in:
Eric Kohl 2002-08-13 20:41:22 +00:00
parent ce083074cf
commit 54865265f0
4 changed files with 657 additions and 164 deletions

View file

@ -206,6 +206,24 @@ typedef struct _ACL
USHORT Sbz2;
} ACL, *PACL;
typedef struct _ACL_REVISION_INFORMATION
{
ULONG AclRevision;
} ACL_REVISION_INFORMATION, *PACL_REVISION_INFORMATION;
typedef struct _ACL_SIZE_INFORMATION
{
ULONG AceCount;
ULONG AclBytesInUse;
ULONG AclBytesFree;
} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
typedef enum _ACL_INFORMATION_CLASS
{
AclRevisionInformation = 1,
AclSizeInformation
} ACL_INFORMATION_CLASS;
typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
typedef struct _SECURITY_DESCRIPTOR_CONTEXT
@ -315,12 +333,6 @@ typedef struct _PRIVILEGE_SET
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
} PRIVILEGE_SET, *PPRIVILEGE_SET, *LPPRIVILEGE_SET;
typedef enum _ACL_INFORMATION_CLASS
{
AclRevisionInformation = 1,
AclSizeInformation
} ACL_INFORMATION_CLASS;
typedef struct _SECURITY_ATTRIBUTES
{
DWORD nLength;

View file

@ -83,16 +83,6 @@ typedef struct tagACCESSTIMEOUT {
DWORD iTimeOutMSec;
} ACCESSTIMEOUT;
typedef struct _ACL_REVISION_INFORMATION {
DWORD AclRevision;
} ACL_REVISION_INFORMATION;
typedef struct _ACL_SIZE_INFORMATION {
DWORD AceCount;
DWORD AclBytesInUse;
DWORD AclBytesFree;
} ACL_SIZE_INFORMATION;
typedef struct _ACTION_HEADER {
ULONG transport_id;
USHORT action_code;

View file

@ -1,4 +1,4 @@
/* $Id: acl.c,v 1.5 2002/06/15 10:08:46 ekohl Exp $
/* $Id: acl.c,v 1.6 2002/08/13 20:41:22 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -33,7 +33,7 @@ RtlFirstFreeAce(PACL Acl,
*Ace = Current;
return(TRUE);
}
AclEnd = Acl->AclSize + Acl;
AclEnd = Acl->AclSize + (PVOID)Acl;
do
{
if ((PVOID)Current >= AclEnd)
@ -52,11 +52,10 @@ RtlFirstFreeAce(PACL Acl,
}
while (i < Acl->AceCount);
if ((PVOID)Current >= AclEnd)
if ((PVOID)Current < AclEnd)
{
return(FALSE);
*Ace = Current;
}
*Ace = Current;
return(TRUE);
}
@ -68,14 +67,13 @@ RtlGetAce(PACL Acl,
PACE *Ace)
{
ULONG i;
PACE p = (PACE)(Acl + 1);
*Ace = NULL;
*Ace = (PACE)(Acl + 1);
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_UNKNOWN_REVISION);
return(STATUS_INVALID_PARAMETER);
}
if (AceIndex >= Acl->AceCount)
@ -85,16 +83,23 @@ RtlGetAce(PACL Acl,
for (i = 0; i < AceIndex; i++)
{
p = (PACE)((PVOID)p + (ULONG)p->Header.AceSize);
if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize)
{
return(STATUS_INVALID_PARAMETER);
}
*Ace = (PACE)((PVOID)(*Ace) + (ULONG)(*Ace)->Header.AceSize);
}
*Ace = p;
if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize)
{
return(STATUS_INVALID_PARAMETER);
}
return(STATUS_SUCCESS);
}
NTSTATUS
static NTSTATUS
RtlpAddKnownAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
@ -118,16 +123,16 @@ RtlpAddKnownAce(PACL Acl,
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_BUFFER_TOO_SMALL);
return(STATUS_INVALID_ACL);
}
if (Ace == NULL)
{
return(STATUS_UNSUCCESSFUL);
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
}
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
((PVOID)Acl + Acl->AclSize))
{
return(STATUS_BUFFER_TOO_SMALL);
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
}
Ace->Header.AceFlags = 0;
Ace->Header.AceType = Type;
@ -160,6 +165,28 @@ RtlAddAccessDeniedAce(PACL Acl,
}
static VOID
RtlpAddData(PVOID AceList,
ULONG AceListLength,
PVOID Ace,
ULONG Offset)
{
if (Offset > 0)
{
memcpy((PUCHAR)Ace + AceListLength,
Ace,
Offset);
}
if (AceListLength != 0)
{
memcpy(Ace,
AceList,
AceListLength);
}
}
NTSTATUS STDCALL
RtlAddAce(PACL Acl,
ULONG AclRevision,
@ -167,63 +194,74 @@ RtlAddAce(PACL Acl,
PACE AceList,
ULONG AceListLength)
{
PACE Ace;
ULONG i;
PACE Current;
ULONG j;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_UNSUCCESSFUL);
}
if (!RtlFirstFreeAce(Acl,&Ace))
{
return(STATUS_UNSUCCESSFUL);
}
if (Acl->AclRevision <= AclRevision)
{
AclRevision = Acl->AclRevision;
}
if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
{
return(STATUS_UNSUCCESSFUL);
}
i = 0;
Current = (PACE)(Acl + 1);
while ((PVOID)Current < ((PVOID)AceList + AceListLength))
{
if (AceList->Header.AceType == 4 &&
AclRevision < 3)
{
return(STATUS_UNSUCCESSFUL);
}
Current = (PACE)((PVOID)Current + Current->Header.AceSize);
}
if (Ace == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
{
return(STATUS_UNSUCCESSFUL);
}
if (StartingIndex != 0)
{
if (Acl->AceCount > 0)
{
Current = (PACE)(Acl + 1);
for (j = 0; j < StartingIndex; j++)
{
Current = (PACE)((PVOID)Current + Current->Header.AceSize);
}
}
}
/* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */
memcpy(Current, AceList, AceListLength);
Acl->AceCount = Acl->AceCount + i;
Acl->AclRevision = AclRevision;
return(TRUE);
PACE Ace;
ULONG i;
PACE Current;
ULONG j;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_INVALID_PARAMETER);
}
if (!RtlFirstFreeAce(Acl,&Ace))
{
return(STATUS_INVALID_PARAMETER);
}
if (Acl->AclRevision <= AclRevision)
{
AclRevision = Acl->AclRevision;
}
if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
{
return(STATUS_INVALID_PARAMETER);
}
i = 0;
Current = (PACE)(Acl + 1);
while ((PVOID)Current < ((PVOID)AceList + AceListLength))
{
if (AceList->Header.AceType == 4 &&
AclRevision < 3)
{
return(STATUS_INVALID_PARAMETER);
}
Current = (PACE)((PVOID)Current + Current->Header.AceSize);
}
if (Ace == NULL)
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (StartingIndex != 0)
{
if (Acl->AceCount > 0)
{
Current = (PACE)(Acl + 1);
for (j = 0; j < StartingIndex; j++)
{
Current = (PACE)((PVOID)Current + Current->Header.AceSize);
}
}
}
RtlpAddData(AceList,
AceListLength,
Current,
(ULONG)Ace - (ULONG)Current);
Acl->AceCount = Acl->AceCount + i;
Acl->AclRevision = AclRevision;
return(STATUS_SUCCESS);
}
@ -235,8 +273,82 @@ RtlAddAuditAccessAce(PACL Acl,
BOOLEAN Success,
BOOLEAN Failure)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
PACE Ace;
ULONG Flags = 0;
if (Success != FALSE)
{
Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
}
if (Failure != FALSE)
{
Flags |= FAILED_ACCESS_ACE_FLAG;
}
if (!RtlValidSid(Sid))
{
return(STATUS_INVALID_SID);
}
if (Acl->AclRevision > 3 ||
Revision > 3)
{
return(STATUS_REVISION_MISMATCH);
}
if (Revision < Acl->AclRevision)
{
Revision = Acl->AclRevision;
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_INVALID_ACL);
}
if (Ace == NULL)
{
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
}
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= ((PVOID)Acl + Acl->AclSize))
{
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
}
Ace->Header.AceFlags = Flags;
Ace->Header.AceType = 2;
Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
Ace->Header.AccessMask = AccessMask;
RtlCopySid(RtlLengthSid(Sid),
(PSID)(Ace + 1),
Sid);
Acl->AceCount++;
Acl->AclRevision = Revision;
return(STATUS_SUCCESS);
}
static VOID
RtlpDeleteData(PVOID Ace,
ULONG AceSize,
ULONG Offset)
{
if (AceSize < Offset)
{
memcpy(Ace,
(PUCHAR)Ace + AceSize,
Offset - AceSize);
}
if (Offset - AceSize < Offset)
{
memset((PUCHAR)Ace + Offset - AceSize,
0,
AceSize);
}
}
@ -244,8 +356,38 @@ NTSTATUS STDCALL
RtlDeleteAce(PACL Acl,
ULONG AceIndex)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
PACE Ace;
PACE Current;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_INVALID_PARAMETER);
}
if (Acl->AceCount <= AceIndex)
{
return(STATUS_INVALID_PARAMETER);
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_INVALID_PARAMETER);
}
Current = (PACE)(Acl + 1);
while(AceIndex--)
{
Current = (PACE)((PVOID)Current + Current->Header.AceSize);
}
RtlpDeleteData(Current,
Current->Header.AceSize,
Ace - Current);
Acl->AceCount++;
return(STATUS_SUCCESS);
}
@ -254,26 +396,30 @@ RtlCreateAcl(PACL Acl,
ULONG AclSize,
ULONG AclRevision)
{
if (AclSize < 8)
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (AclRevision != 2 &&
AclRevision != 3)
{
return(STATUS_UNKNOWN_REVISION);
}
if (AclSize > 0xffff)
{
return(STATUS_UNSUCCESSFUL);
}
AclSize = AclSize & ~(0x3);
Acl->AclSize = AclSize;
Acl->AclRevision = AclRevision;
Acl->AceCount = 0;
Acl->Sbz1 = 0;
Acl->Sbz2 = 0;
return(STATUS_SUCCESS);
if (AclSize < 8)
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (AclRevision != 2 &&
AclRevision != 3)
{
return(STATUS_INVALID_PARAMETER);
}
if (AclSize > 0xffff)
{
return(STATUS_INVALID_PARAMETER);
}
AclSize = AclSize & ~(0x3);
Acl->AclSize = AclSize;
Acl->AclRevision = AclRevision;
Acl->AceCount = 0;
Acl->Sbz1 = 0;
Acl->Sbz2 = 0;
return(STATUS_SUCCESS);
}
@ -283,8 +429,61 @@ RtlQueryInformationAcl(PACL Acl,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
PACE Ace;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_INVALID_PARAMETER);
}
switch (InformationClass)
{
case AclRevisionInformation:
{
PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
{
return(STATUS_BUFFER_TOO_SMALL);
}
Info->AclRevision = Acl->AclRevision;
}
break;
case AclSizeInformation:
{
PACL_SIZE_INFORMATION Info = (PACL_SIZE_INFORMATION)Information;
if (InformationLength < sizeof(ACL_SIZE_INFORMATION))
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_INVALID_PARAMETER);
}
Info->AceCount = Acl->AceCount;
if (Ace != NULL)
{
Info->AclBytesInUse = (PVOID)Ace - (PVOID)Acl;
Info->AclBytesFree = Acl->AclSize - Info->AclBytesInUse;
}
else
{
Info->AclBytesInUse = Acl->AclSize;
Info->AclBytesFree = 0;
}
}
break;
default:
return(STATUS_INVALID_INFO_CLASS);
}
return(STATUS_SUCCESS);
}
@ -294,16 +493,60 @@ RtlSetInformationAcl(PACL Acl,
ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(STATUS_INVALID_PARAMETER);
}
switch (InformationClass)
{
case AclRevisionInformation:
{
PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (Acl->AclRevision >= Info->AclRevision)
{
return(STATUS_INVALID_PARAMETER);
}
Acl->AclRevision = Info->AclRevision;
}
break;
default:
return(STATUS_INVALID_INFO_CLASS);
}
return(STATUS_SUCCESS);
}
BOOLEAN STDCALL
RtlValidAcl(PACL Acl)
{
UNIMPLEMENTED;
return FALSE;
PACE Ace;
USHORT Size;
Size = (Acl->AclSize + 3) & ~3;
if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3)
{
return(FALSE);
}
if (Size != Acl->AclSize)
{
return(FALSE);
}
return(RtlFirstFreeAce(Acl, &Ace));
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: sd.c,v 1.6 2001/12/04 20:47:54 ekohl Exp $
/* $Id: sd.c,v 1.7 2002/08/13 20:41:22 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -21,33 +21,35 @@ NTSTATUS STDCALL
RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG Revision)
{
if (Revision != 1)
{
return(STATUS_UNSUCCESSFUL);
}
SecurityDescriptor->Revision = 1;
SecurityDescriptor->Sbz1 = 0;
SecurityDescriptor->Control = 0;
SecurityDescriptor->Owner = NULL;
SecurityDescriptor->Group = NULL;
SecurityDescriptor->Sacl = NULL;
SecurityDescriptor->Dacl = NULL;
return(STATUS_SUCCESS);
if (Revision != 1)
{
return(STATUS_UNSUCCESSFUL);
}
SecurityDescriptor->Revision = 1;
SecurityDescriptor->Sbz1 = 0;
SecurityDescriptor->Control = 0;
SecurityDescriptor->Owner = NULL;
SecurityDescriptor->Group = NULL;
SecurityDescriptor->Sacl = NULL;
SecurityDescriptor->Dacl = NULL;
return(STATUS_SUCCESS);
}
ULONG STDCALL
RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PSID Owner;
PSID Group;
ULONG Length;
PACL Dacl;
PACL Sacl;
PSID Owner;
PSID Group;
ULONG Length;
PACL Dacl;
PACL Sacl;
Length = sizeof(SECURITY_DESCRIPTOR);
Length = sizeof(SECURITY_DESCRIPTOR);
if (SecurityDescriptor->Owner != NULL)
{
if (SecurityDescriptor->Owner != NULL)
{
Owner = SecurityDescriptor->Owner;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
@ -56,9 +58,10 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
}
Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) *
sizeof(ULONG) + 3) & 0xfc);
}
if (SecurityDescriptor->Group != NULL)
{
}
if (SecurityDescriptor->Group != NULL)
{
Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
@ -66,30 +69,34 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
}
Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) *
sizeof(ULONG) + 3) & 0xfc);
}
if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
SecurityDescriptor->Dacl != NULL)
{
}
if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
SecurityDescriptor->Dacl != NULL)
{
Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor);
}
Length = Length + ((Dacl->AclSize + 3) & 0xfc);
}
if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
SecurityDescriptor->Sacl != NULL)
{
}
if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
SecurityDescriptor->Sacl != NULL)
{
Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor);
}
Length = Length + ((Sacl->AclSize + 3) & 0xfc);
}
return(Length);
}
return(Length);
}
NTSTATUS STDCALL
RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PBOOLEAN DaclPresent,
@ -133,6 +140,7 @@ RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
BOOLEAN DaclPresent,
@ -162,12 +170,76 @@ RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return(STATUS_SUCCESS);
}
BOOLEAN STDCALL
RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{
UNIMPLEMENTED;
PSID Owner;
PSID Group;
PACL Sacl;
PACL Dacl;
if (SecurityDescriptor->Revision != 1)
{
return(FALSE);
}
Owner = SecurityDescriptor->Owner;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor);
}
if (!RtlValidSid(Owner))
{
return(FALSE);
}
Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
}
if (!RtlValidSid(Group))
{
return(FALSE);
}
if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
SecurityDescriptor->Dacl != NULL)
{
Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor);
}
if (!RtlValidAcl(Dacl))
{
return(FALSE);
}
}
if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
SecurityDescriptor->Sacl != NULL)
{
Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor);
}
if (!RtlValidAcl(Sacl))
{
return(FALSE);
}
}
return(TRUE);
}
NTSTATUS STDCALL
RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID Owner,
@ -284,43 +356,219 @@ RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
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 = NULL;
}
else
{
*Owner = SecurityDescriptor->Owner;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor);
}
}
if (*Owner != NULL)
{
*OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3;
}
else
{
*OwnerLength = 0;
}
if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
SecurityDescriptor->Dacl != NULL)
{
*Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor);
}
}
else
{
*Dacl = NULL;
}
if (*Dacl != NULL)
{
*DaclLength = ((*Dacl)->AclSize + 3) & ~3;
}
else
{
*DaclLength = 0;
}
if (SecurityDescriptor->Group != NULL)
{
*Group = NULL;
}
else
{
*Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor);
}
}
if (*Group != NULL)
{
*GroupLength = (RtlLengthSid(*Group) + 3) & ~3;
}
else
{
*GroupLength = 0;
}
if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
SecurityDescriptor->Sacl != NULL)
{
*Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{
*Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor);
}
}
else
{
*Sacl = NULL;
}
if (*Sacl != NULL)
{
*SaclLength = ((*Sacl)->AclSize + 3) & ~3;
}
}
NTSTATUS STDCALL
RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD,
PULONG BufferLength)
{
UNIMPLEMENTED;
PSID Owner;
PSID Group;
PACL Sacl;
PACL Dacl;
ULONG OwnerLength;
ULONG GroupLength;
ULONG SaclLength;
ULONG DaclLength;
ULONG TotalLength;
ULONG Current;
RtlpQuerySecurityDescriptor(AbsSD,
&Owner,
&OwnerLength,
&Group,
&GroupLength,
&Dacl,
&DaclLength,
&Sacl,
&SaclLength);
TotalLength = OwnerLength + GroupLength + SaclLength + DaclLength + sizeof(SECURITY_DESCRIPTOR);
if (*BufferLength < TotalLength)
{
return(STATUS_BUFFER_TOO_SMALL);
}
RtlZeroMemory(RelSD,
TotalLength);
memmove(RelSD,
AbsSD,
sizeof(SECURITY_DESCRIPTOR));
Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR);
if (SaclLength != 0)
{
memmove((PVOID)Current,
Sacl,
SaclLength);
RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD);
Current += SaclLength;
}
if (DaclLength != 0)
{
memmove((PVOID)Current,
Dacl,
DaclLength);
RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD);
Current += DaclLength;
}
if (OwnerLength != 0)
{
memmove((PVOID)Current,
Owner,
OwnerLength);
RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD);
Current += OwnerLength;
}
if (GroupLength != 0)
{
memmove((PVOID)Current,
Group,
GroupLength);
RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD);
}
RelSD->Control |= SE_SELF_RELATIVE;
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD,
PULONG BufferLength
)
{
if (AbsSD->Control & SE_SELF_RELATIVE)
{
return(STATUS_BAD_DESCRIPTOR_FORMAT);
}
if (AbsSD->Control & SE_SELF_RELATIVE)
{
return(STATUS_BAD_DESCRIPTOR_FORMAT);
}
return(RtlMakeSelfRelativeSD (AbsSD, RelSD, BufferLength));
return(RtlMakeSelfRelativeSD(AbsSD, RelSD, BufferLength));
}
NTSTATUS STDCALL
RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PSECURITY_DESCRIPTOR_CONTROL Control,
PULONG Revision)
{
*Revision = SecurityDescriptor->Revision;
*Revision = SecurityDescriptor->Revision;
if (SecurityDescriptor->Revision != 1)
return(STATUS_UNKNOWN_REVISION);
if (SecurityDescriptor->Revision != 1)
{
return(STATUS_UNKNOWN_REVISION);
}
*Control = SecurityDescriptor->Control;
*Control = SecurityDescriptor->Control;
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PBOOLEAN SaclPresent,