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; USHORT Sbz2;
} ACL, *PACL; } 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 USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
typedef struct _SECURITY_DESCRIPTOR_CONTEXT typedef struct _SECURITY_DESCRIPTOR_CONTEXT
@ -315,12 +333,6 @@ typedef struct _PRIVILEGE_SET
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
} PRIVILEGE_SET, *PPRIVILEGE_SET, *LPPRIVILEGE_SET; } PRIVILEGE_SET, *PPRIVILEGE_SET, *LPPRIVILEGE_SET;
typedef enum _ACL_INFORMATION_CLASS
{
AclRevisionInformation = 1,
AclSizeInformation
} ACL_INFORMATION_CLASS;
typedef struct _SECURITY_ATTRIBUTES typedef struct _SECURITY_ATTRIBUTES
{ {
DWORD nLength; DWORD nLength;

View file

@ -83,16 +83,6 @@ typedef struct tagACCESSTIMEOUT {
DWORD iTimeOutMSec; DWORD iTimeOutMSec;
} ACCESSTIMEOUT; } 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 { typedef struct _ACTION_HEADER {
ULONG transport_id; ULONG transport_id;
USHORT action_code; 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,7 +33,7 @@ RtlFirstFreeAce(PACL Acl,
*Ace = Current; *Ace = Current;
return(TRUE); return(TRUE);
} }
AclEnd = Acl->AclSize + Acl; AclEnd = Acl->AclSize + (PVOID)Acl;
do do
{ {
if ((PVOID)Current >= AclEnd) if ((PVOID)Current >= AclEnd)
@ -52,11 +52,10 @@ RtlFirstFreeAce(PACL Acl,
} }
while (i < Acl->AceCount); while (i < Acl->AceCount);
if ((PVOID)Current >= AclEnd) if ((PVOID)Current < AclEnd)
{ {
return(FALSE); *Ace = Current;
} }
*Ace = Current;
return(TRUE); return(TRUE);
} }
@ -68,14 +67,13 @@ RtlGetAce(PACL Acl,
PACE *Ace) PACE *Ace)
{ {
ULONG i; ULONG i;
PACE p = (PACE)(Acl + 1);
*Ace = NULL; *Ace = (PACE)(Acl + 1);
if (Acl->AclRevision != 2 && if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3) Acl->AclRevision != 3)
{ {
return(STATUS_UNKNOWN_REVISION); return(STATUS_INVALID_PARAMETER);
} }
if (AceIndex >= Acl->AceCount) if (AceIndex >= Acl->AceCount)
@ -85,16 +83,23 @@ RtlGetAce(PACL Acl,
for (i = 0; i < AceIndex; i++) 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); return(STATUS_SUCCESS);
} }
NTSTATUS static NTSTATUS
RtlpAddKnownAce(PACL Acl, RtlpAddKnownAce(PACL Acl,
ULONG Revision, ULONG Revision,
ACCESS_MASK AccessMask, ACCESS_MASK AccessMask,
@ -118,16 +123,16 @@ RtlpAddKnownAce(PACL Acl,
} }
if (!RtlFirstFreeAce(Acl, &Ace)) if (!RtlFirstFreeAce(Acl, &Ace))
{ {
return(STATUS_BUFFER_TOO_SMALL); return(STATUS_INVALID_ACL);
} }
if (Ace == NULL) if (Ace == NULL)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_ALLOTTED_SPACE_EXCEEDED);
} }
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
((PVOID)Acl + Acl->AclSize)) ((PVOID)Acl + Acl->AclSize))
{ {
return(STATUS_BUFFER_TOO_SMALL); return(STATUS_ALLOTTED_SPACE_EXCEEDED);
} }
Ace->Header.AceFlags = 0; Ace->Header.AceFlags = 0;
Ace->Header.AceType = Type; 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 NTSTATUS STDCALL
RtlAddAce(PACL Acl, RtlAddAce(PACL Acl,
ULONG AclRevision, ULONG AclRevision,
@ -167,63 +194,74 @@ RtlAddAce(PACL Acl,
PACE AceList, PACE AceList,
ULONG AceListLength) ULONG AceListLength)
{ {
PACE Ace; PACE Ace;
ULONG i; ULONG i;
PACE Current; PACE Current;
ULONG j; ULONG j;
if (Acl->AclRevision != 2 && if (Acl->AclRevision != 2 &&
Acl->AclRevision != 3) Acl->AclRevision != 3)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_INVALID_PARAMETER);
} }
if (!RtlFirstFreeAce(Acl,&Ace))
{ if (!RtlFirstFreeAce(Acl,&Ace))
return(STATUS_UNSUCCESSFUL); {
} return(STATUS_INVALID_PARAMETER);
if (Acl->AclRevision <= AclRevision) }
{
AclRevision = Acl->AclRevision; if (Acl->AclRevision <= AclRevision)
} {
if (((PVOID)AceList + AceListLength) <= (PVOID)AceList) AclRevision = Acl->AclRevision;
{ }
return(STATUS_UNSUCCESSFUL);
} if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
i = 0; {
Current = (PACE)(Acl + 1); return(STATUS_INVALID_PARAMETER);
while ((PVOID)Current < ((PVOID)AceList + AceListLength)) }
{
if (AceList->Header.AceType == 4 && i = 0;
AclRevision < 3) Current = (PACE)(Acl + 1);
{ while ((PVOID)Current < ((PVOID)AceList + AceListLength))
return(STATUS_UNSUCCESSFUL); {
} if (AceList->Header.AceType == 4 &&
Current = (PACE)((PVOID)Current + Current->Header.AceSize); AclRevision < 3)
} {
if (Ace == NULL) return(STATUS_INVALID_PARAMETER);
{ }
return(STATUS_UNSUCCESSFUL); Current = (PACE)((PVOID)Current + Current->Header.AceSize);
} }
if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
{ if (Ace == NULL)
return(STATUS_UNSUCCESSFUL); {
} return(STATUS_BUFFER_TOO_SMALL);
if (StartingIndex != 0) }
{
if (Acl->AceCount > 0) if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
{ {
Current = (PACE)(Acl + 1); return(STATUS_BUFFER_TOO_SMALL);
for (j = 0; j < StartingIndex; j++) }
{
Current = (PACE)((PVOID)Current + Current->Header.AceSize); if (StartingIndex != 0)
} {
} if (Acl->AceCount > 0)
} {
/* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */ Current = (PACE)(Acl + 1);
memcpy(Current, AceList, AceListLength); for (j = 0; j < StartingIndex; j++)
Acl->AceCount = Acl->AceCount + i; {
Acl->AclRevision = AclRevision; Current = (PACE)((PVOID)Current + Current->Header.AceSize);
return(TRUE); }
}
}
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 Success,
BOOLEAN Failure) BOOLEAN Failure)
{ {
UNIMPLEMENTED; PACE Ace;
return STATUS_UNSUCCESSFUL; 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, RtlDeleteAce(PACL Acl,
ULONG AceIndex) ULONG AceIndex)
{ {
UNIMPLEMENTED; PACE Ace;
return STATUS_UNSUCCESSFUL; 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 AclSize,
ULONG AclRevision) ULONG AclRevision)
{ {
if (AclSize < 8) if (AclSize < 8)
{ {
return(STATUS_BUFFER_TOO_SMALL); return(STATUS_BUFFER_TOO_SMALL);
} }
if (AclRevision != 2 &&
AclRevision != 3) if (AclRevision != 2 &&
{ AclRevision != 3)
return(STATUS_UNKNOWN_REVISION); {
} return(STATUS_INVALID_PARAMETER);
if (AclSize > 0xffff) }
{
return(STATUS_UNSUCCESSFUL); if (AclSize > 0xffff)
} {
AclSize = AclSize & ~(0x3); return(STATUS_INVALID_PARAMETER);
Acl->AclSize = AclSize; }
Acl->AclRevision = AclRevision;
Acl->AceCount = 0; AclSize = AclSize & ~(0x3);
Acl->Sbz1 = 0; Acl->AclSize = AclSize;
Acl->Sbz2 = 0; Acl->AclRevision = AclRevision;
return(STATUS_SUCCESS); Acl->AceCount = 0;
Acl->Sbz1 = 0;
Acl->Sbz2 = 0;
return(STATUS_SUCCESS);
} }
@ -283,8 +429,61 @@ RtlQueryInformationAcl(PACL Acl,
ULONG InformationLength, ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass) ACL_INFORMATION_CLASS InformationClass)
{ {
UNIMPLEMENTED; PACE Ace;
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);
}
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, ULONG InformationLength,
ACL_INFORMATION_CLASS InformationClass) ACL_INFORMATION_CLASS InformationClass)
{ {
UNIMPLEMENTED; if (Acl->AclRevision != 2 &&
return STATUS_UNSUCCESSFUL; 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 BOOLEAN STDCALL
RtlValidAcl(PACL Acl) RtlValidAcl(PACL Acl)
{ {
UNIMPLEMENTED; PACE Ace;
return FALSE; 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 */ /* 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -21,33 +21,35 @@ NTSTATUS STDCALL
RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
ULONG Revision) ULONG Revision)
{ {
if (Revision != 1) if (Revision != 1)
{ {
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
SecurityDescriptor->Revision = 1;
SecurityDescriptor->Sbz1 = 0; SecurityDescriptor->Revision = 1;
SecurityDescriptor->Control = 0; SecurityDescriptor->Sbz1 = 0;
SecurityDescriptor->Owner = NULL; SecurityDescriptor->Control = 0;
SecurityDescriptor->Group = NULL; SecurityDescriptor->Owner = NULL;
SecurityDescriptor->Sacl = NULL; SecurityDescriptor->Group = NULL;
SecurityDescriptor->Dacl = NULL; SecurityDescriptor->Sacl = NULL;
return(STATUS_SUCCESS); SecurityDescriptor->Dacl = NULL;
return(STATUS_SUCCESS);
} }
ULONG STDCALL ULONG STDCALL
RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{ {
PSID Owner; PSID Owner;
PSID Group; PSID Group;
ULONG Length; ULONG Length;
PACL Dacl; PACL Dacl;
PACL Sacl; PACL Sacl;
Length = sizeof(SECURITY_DESCRIPTOR); Length = sizeof(SECURITY_DESCRIPTOR);
if (SecurityDescriptor->Owner != NULL) if (SecurityDescriptor->Owner != NULL)
{ {
Owner = SecurityDescriptor->Owner; Owner = SecurityDescriptor->Owner;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{ {
@ -56,9 +58,10 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
} }
Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) *
sizeof(ULONG) + 3) & 0xfc); sizeof(ULONG) + 3) & 0xfc);
} }
if (SecurityDescriptor->Group != NULL)
{ if (SecurityDescriptor->Group != NULL)
{
Group = SecurityDescriptor->Group; Group = SecurityDescriptor->Group;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{ {
@ -66,30 +69,34 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
} }
Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) * Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) *
sizeof(ULONG) + 3) & 0xfc); 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; Dacl = SecurityDescriptor->Dacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{ {
Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor); Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor);
} }
Length = Length + ((Dacl->AclSize + 3) & 0xfc); 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; Sacl = SecurityDescriptor->Sacl;
if (SecurityDescriptor->Control & SE_SELF_RELATIVE) if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
{ {
Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor); Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor);
} }
Length = Length + ((Sacl->AclSize + 3) & 0xfc); Length = Length + ((Sacl->AclSize + 3) & 0xfc);
} }
return(Length);
return(Length);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PBOOLEAN DaclPresent, PBOOLEAN DaclPresent,
@ -133,6 +140,7 @@ RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
BOOLEAN DaclPresent, BOOLEAN DaclPresent,
@ -162,12 +170,76 @@ RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
BOOLEAN STDCALL BOOLEAN STDCALL
RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) 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 NTSTATUS STDCALL
RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID Owner, PSID Owner,
@ -284,43 +356,219 @@ RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
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 = 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 NTSTATUS STDCALL
RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR RelSD,
PULONG BufferLength) 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 NTSTATUS STDCALL
RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
PSECURITY_DESCRIPTOR RelSD, PSECURITY_DESCRIPTOR RelSD,
PULONG BufferLength PULONG BufferLength
) )
{ {
if (AbsSD->Control & SE_SELF_RELATIVE) if (AbsSD->Control & SE_SELF_RELATIVE)
{ {
return(STATUS_BAD_DESCRIPTOR_FORMAT); return(STATUS_BAD_DESCRIPTOR_FORMAT);
} }
return(RtlMakeSelfRelativeSD (AbsSD, RelSD, BufferLength)); return(RtlMakeSelfRelativeSD(AbsSD, RelSD, BufferLength));
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PSECURITY_DESCRIPTOR_CONTROL Control, PSECURITY_DESCRIPTOR_CONTROL Control,
PULONG Revision) PULONG Revision)
{ {
*Revision = SecurityDescriptor->Revision; *Revision = SecurityDescriptor->Revision;
if (SecurityDescriptor->Revision != 1) if (SecurityDescriptor->Revision != 1)
return(STATUS_UNKNOWN_REVISION); {
return(STATUS_UNKNOWN_REVISION);
}
*Control = SecurityDescriptor->Control; *Control = SecurityDescriptor->Control;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
PBOOLEAN SaclPresent, PBOOLEAN SaclPresent,