2005-09-08 00:09:32 +00:00
|
|
|
/* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* PURPOSE: Security manager
|
|
|
|
* FILE: lib/rtl/acl.c
|
|
|
|
* PROGRAMER: David Welch <welch@cwcom.net>
|
2004-05-31 19:33:59 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2005-07-26 08:39:07 +00:00
|
|
|
#include <rtl.h>
|
2004-05-31 19:33:59 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlFirstFreeAce(
|
|
|
|
PACL Acl,
|
|
|
|
PACE* Ace)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Current;
|
|
|
|
ULONG_PTR AclEnd;
|
|
|
|
ULONG i;
|
|
|
|
PAGED_CODE_RTL();
|
|
|
|
|
|
|
|
Current = (PACE)(Acl + 1);
|
|
|
|
*Ace = NULL;
|
|
|
|
|
|
|
|
if (Acl->AceCount == 0)
|
|
|
|
{
|
|
|
|
*Ace = Current;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
AclEnd = (ULONG_PTR)Acl + Acl->AclSize;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ((ULONG_PTR)Current >= AclEnd)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (Current->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE &&
|
|
|
|
Acl->AclRevision < ACL_REVISION3)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize);
|
|
|
|
}
|
|
|
|
while (++i < Acl->AceCount);
|
|
|
|
|
|
|
|
if ((ULONG_PTR)Current < AclEnd)
|
|
|
|
{
|
|
|
|
*Ace = Current;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlGetAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG AceIndex,
|
|
|
|
PVOID *Ace)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
ULONG i;
|
|
|
|
PAGED_CODE_RTL();
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
|
|
|
Acl->AclRevision > MAX_ACL_REVISION ||
|
|
|
|
AceIndex >= Acl->AceCount)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
*Ace = (PVOID)((PACE)(Acl + 1));
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
for (i = 0; i < AceIndex; i++)
|
|
|
|
{
|
|
|
|
if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
*Ace = (PVOID)((PACE)((ULONG_PTR)(*Ace) + ((PACE)(*Ace))->Header.AceSize));
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
static
|
|
|
|
NTSTATUS
|
|
|
|
RtlpAddKnownAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG Revision,
|
|
|
|
ULONG Flags,
|
|
|
|
ACCESS_MASK AccessMask,
|
|
|
|
GUID *ObjectTypeGuid OPTIONAL,
|
|
|
|
GUID *InheritedObjectTypeGuid OPTIONAL,
|
|
|
|
PSID Sid,
|
2011-09-19 11:09:09 +00:00
|
|
|
UCHAR Type)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Ace;
|
|
|
|
PSID SidStart;
|
|
|
|
ULONG AceSize, InvalidFlags;
|
|
|
|
ULONG AceObjectFlags = 0;
|
|
|
|
PAGED_CODE_RTL();
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2006-05-10 09:32:23 +00:00
|
|
|
#if DBG
|
2011-09-18 15:10:05 +00:00
|
|
|
/* check if RtlpAddKnownAce was called incorrectly */
|
|
|
|
if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
|
|
|
|
{
|
|
|
|
ASSERT(Type == ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE ||
|
|
|
|
Type == ACCESS_ALLOWED_OBJECT_ACE_TYPE ||
|
|
|
|
Type == ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE ||
|
|
|
|
Type == ACCESS_DENIED_OBJECT_ACE_TYPE ||
|
|
|
|
Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE ||
|
|
|
|
Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT(Type != ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE &&
|
|
|
|
Type != ACCESS_ALLOWED_OBJECT_ACE_TYPE &&
|
|
|
|
Type != ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE &&
|
|
|
|
Type != ACCESS_DENIED_OBJECT_ACE_TYPE &&
|
|
|
|
Type != SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE &&
|
|
|
|
Type != SYSTEM_AUDIT_OBJECT_ACE_TYPE);
|
|
|
|
}
|
2006-05-10 09:32:23 +00:00
|
|
|
#endif
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (!RtlValidSid(Sid))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_SID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Type == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
|
|
|
|
{
|
|
|
|
static const SID_IDENTIFIER_AUTHORITY MandatoryLabelAuthority = {SECURITY_MANDATORY_LABEL_AUTHORITY};
|
|
|
|
|
|
|
|
/* The SID's identifier authority must be SECURITY_MANDATORY_LABEL_AUTHORITY! */
|
|
|
|
if (RtlCompareMemory(&((PISID)Sid)->IdentifierAuthority,
|
|
|
|
&MandatoryLabelAuthority,
|
|
|
|
sizeof(MandatoryLabelAuthority)) != sizeof(MandatoryLabelAuthority))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Acl->AclRevision > MAX_ACL_REVISION ||
|
|
|
|
Revision > MAX_ACL_REVISION)
|
|
|
|
{
|
|
|
|
return STATUS_UNKNOWN_REVISION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Revision < Acl->AclRevision)
|
|
|
|
{
|
|
|
|
Revision = Acl->AclRevision;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Validate the flags */
|
|
|
|
if (Type == SYSTEM_AUDIT_ACE_TYPE ||
|
|
|
|
Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE ||
|
|
|
|
Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE)
|
|
|
|
{
|
|
|
|
InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
|
2006-03-09 21:43:58 +00:00
|
|
|
SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG);
|
2011-09-18 15:10:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InvalidFlags != 0)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!RtlFirstFreeAce(Acl, &Ace))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_ACL;
|
|
|
|
}
|
|
|
|
if (Ace == NULL)
|
|
|
|
{
|
|
|
|
return STATUS_ALLOTTED_SPACE_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the size of the ACE */
|
|
|
|
AceSize = RtlLengthSid(Sid) + sizeof(ACE);
|
|
|
|
if (ObjectTypeGuid != NULL)
|
|
|
|
{
|
|
|
|
AceObjectFlags |= ACE_OBJECT_TYPE_PRESENT;
|
|
|
|
AceSize += sizeof(GUID);
|
|
|
|
}
|
|
|
|
if (InheritedObjectTypeGuid != NULL)
|
|
|
|
{
|
|
|
|
AceObjectFlags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
|
|
|
|
AceSize += sizeof(GUID);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (AceObjectFlags != 0)
|
|
|
|
{
|
|
|
|
/* Don't forget the ACE object flags
|
|
|
|
(corresponds to the Flags field in the *_OBJECT_ACE structures) */
|
|
|
|
AceSize += sizeof(ULONG);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ULONG_PTR)Ace + AceSize >
|
|
|
|
(ULONG_PTR)Acl + Acl->AclSize)
|
|
|
|
{
|
|
|
|
return STATUS_ALLOTTED_SPACE_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize the header and common fields */
|
2011-09-19 11:09:09 +00:00
|
|
|
Ace->Header.AceFlags = (BYTE)Flags;
|
2011-09-18 15:10:05 +00:00
|
|
|
Ace->Header.AceType = Type;
|
|
|
|
Ace->Header.AceSize = (WORD)AceSize;
|
|
|
|
Ace->AccessMask = AccessMask;
|
|
|
|
|
|
|
|
if (AceObjectFlags != 0)
|
|
|
|
{
|
|
|
|
/* Write the ACE flags to the ACE
|
|
|
|
(corresponds to the Flags field in the *_OBJECT_ACE structures) */
|
|
|
|
*(PULONG)(Ace + 1) = AceObjectFlags;
|
|
|
|
SidStart = (PSID)((ULONG_PTR)(Ace + 1) + sizeof(ULONG));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SidStart = (PSID)(Ace + 1);
|
|
|
|
|
|
|
|
/* copy the GUIDs */
|
|
|
|
if (ObjectTypeGuid != NULL)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(SidStart, ObjectTypeGuid, sizeof(GUID));
|
|
|
|
SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID));
|
|
|
|
}
|
|
|
|
if (InheritedObjectTypeGuid != NULL)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(SidStart, InheritedObjectTypeGuid, sizeof(GUID));
|
|
|
|
SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy the SID */
|
|
|
|
RtlCopySid(RtlLengthSid(Sid), SidStart, Sid);
|
|
|
|
Acl->AceCount++;
|
2011-09-19 11:09:09 +00:00
|
|
|
Acl->AclRevision = (BYTE)Revision;
|
2011-09-18 15:10:05 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessAllowedAce(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ACCESS_MASK AccessMask,
|
|
|
|
IN PSID Sid)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2004-05-31 19:33:59 +00:00
|
|
|
Revision,
|
|
|
|
0,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-05-31 19:33:59 +00:00
|
|
|
Sid,
|
|
|
|
ACCESS_ALLOWED_ACE_TYPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessAllowedAceEx(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN ACCESS_MASK AccessMask,
|
|
|
|
IN PSID Sid)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2004-05-31 19:33:59 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-05-31 19:33:59 +00:00
|
|
|
Sid,
|
|
|
|
ACCESS_ALLOWED_ACE_TYPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-10 09:32:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessAllowedObjectAce(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN ACCESS_MASK AccessMask,
|
|
|
|
IN GUID *ObjectTypeGuid OPTIONAL,
|
|
|
|
IN GUID *InheritedObjectTypeGuid OPTIONAL,
|
|
|
|
IN PSID Sid)
|
2006-05-10 09:32:23 +00:00
|
|
|
{
|
2011-09-19 11:09:09 +00:00
|
|
|
UCHAR Type;
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
/* make sure we call RtlpAddKnownAce correctly */
|
|
|
|
if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
|
|
|
|
Type = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
|
|
|
|
else
|
|
|
|
Type = ACCESS_ALLOWED_ACE_TYPE;
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2006-05-10 09:32:23 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
|
|
|
ObjectTypeGuid,
|
|
|
|
InheritedObjectTypeGuid,
|
|
|
|
Sid,
|
|
|
|
Type);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-31 19:33:59 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessDeniedAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG Revision,
|
|
|
|
ACCESS_MASK AccessMask,
|
|
|
|
PSID Sid)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2004-05-31 19:33:59 +00:00
|
|
|
Revision,
|
|
|
|
0,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-05-31 19:33:59 +00:00
|
|
|
Sid,
|
|
|
|
ACCESS_DENIED_ACE_TYPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessDeniedAceEx(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN ACCESS_MASK AccessMask,
|
|
|
|
IN PSID Sid)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2004-05-31 19:33:59 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-05-31 19:33:59 +00:00
|
|
|
Sid,
|
|
|
|
ACCESS_DENIED_ACE_TYPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-10 09:32:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAccessDeniedObjectAce(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN ACCESS_MASK AccessMask,
|
|
|
|
IN GUID *ObjectTypeGuid OPTIONAL,
|
|
|
|
IN GUID *InheritedObjectTypeGuid OPTIONAL,
|
|
|
|
IN PSID Sid)
|
2006-05-10 09:32:23 +00:00
|
|
|
{
|
2011-09-19 11:09:09 +00:00
|
|
|
UCHAR Type;
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
/* make sure we call RtlpAddKnownAce correctly */
|
|
|
|
if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
|
|
|
|
Type = ACCESS_DENIED_OBJECT_ACE_TYPE;
|
|
|
|
else
|
|
|
|
Type = ACCESS_DENIED_ACE_TYPE;
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2006-05-10 09:32:23 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
|
|
|
ObjectTypeGuid,
|
|
|
|
InheritedObjectTypeGuid,
|
|
|
|
Sid,
|
|
|
|
Type);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
RtlpAddData(
|
|
|
|
PVOID AceList,
|
|
|
|
ULONG AceListLength,
|
|
|
|
PVOID Ace,
|
|
|
|
ULONG Offset)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Offset > 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)Ace + AceListLength),
|
|
|
|
Ace,
|
|
|
|
Offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (AceListLength != 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(Ace, AceList, AceListLength);
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG AclRevision,
|
|
|
|
ULONG StartingIndex,
|
|
|
|
PVOID AceList,
|
|
|
|
ULONG AceListLength)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Ace;
|
|
|
|
PACE Current;
|
2011-09-20 17:33:51 +00:00
|
|
|
WORD NewAceCount;
|
2011-09-18 15:10:05 +00:00
|
|
|
ULONG Index;
|
|
|
|
PAGED_CODE_RTL();
|
|
|
|
|
2011-09-19 11:09:09 +00:00
|
|
|
/* Make sure, the ACL is valid */
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
|
|
|
Acl->AclRevision > MAX_ACL_REVISION ||
|
|
|
|
!RtlFirstFreeAce(Acl, &Ace))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-19 11:09:09 +00:00
|
|
|
/* Check if the ACL revision is smaller than the given one */
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision <= AclRevision)
|
|
|
|
{
|
2011-09-19 11:09:09 +00:00
|
|
|
/* Update the revision to the given one */
|
2011-09-18 15:10:05 +00:00
|
|
|
AclRevision = Acl->AclRevision;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (((ULONG_PTR)AceList + AceListLength) <= (ULONG_PTR)AceList)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Current = AceList, NewAceCount = 0;
|
|
|
|
(ULONG_PTR)Current < ((ULONG_PTR)AceList + AceListLength);
|
|
|
|
Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize),
|
|
|
|
++NewAceCount)
|
|
|
|
{
|
|
|
|
if (((PACE)AceList)->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE &&
|
|
|
|
AclRevision < ACL_REVISION3)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Ace == NULL ||
|
|
|
|
((ULONG_PTR)Ace + AceListLength) > ((ULONG_PTR)Acl + Acl->AclSize))
|
|
|
|
{
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Current = (PACE)(Acl + 1);
|
|
|
|
for (Index = 0; Index < StartingIndex && Index < Acl->AceCount; Index++)
|
|
|
|
{
|
|
|
|
Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlpAddData(AceList,
|
|
|
|
AceListLength,
|
|
|
|
Current,
|
|
|
|
(ULONG)((ULONG_PTR)Ace - (ULONG_PTR)Current));
|
2011-09-19 11:09:09 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
Acl->AceCount = Acl->AceCount + NewAceCount;
|
2011-09-20 17:33:51 +00:00
|
|
|
Acl->AclRevision = (BYTE)AclRevision;
|
2011-09-18 15:10:05 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAuditAccessAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG Revision,
|
|
|
|
ACCESS_MASK AccessMask,
|
|
|
|
PSID Sid,
|
|
|
|
BOOLEAN Success,
|
|
|
|
BOOLEAN Failure)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
ULONG Flags = 0;
|
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
|
|
|
|
if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2006-03-09 21:43:58 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2006-03-09 21:43:58 +00:00
|
|
|
Sid,
|
|
|
|
SYSTEM_AUDIT_ACE_TYPE);
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-15 08:15:49 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAuditAccessAceEx(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG Revision,
|
|
|
|
ULONG Flags,
|
|
|
|
ACCESS_MASK AccessMask,
|
|
|
|
PSID Sid,
|
|
|
|
BOOLEAN Success,
|
|
|
|
BOOLEAN Failure)
|
2004-07-15 08:15:49 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
|
|
|
|
if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
|
2006-03-09 21:43:58 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2006-03-09 21:43:58 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
2006-05-10 09:32:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2006-03-09 21:43:58 +00:00
|
|
|
Sid,
|
|
|
|
SYSTEM_AUDIT_ACE_TYPE);
|
2004-07-15 08:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-10 09:32:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddAuditAccessObjectAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG Revision,
|
|
|
|
ULONG Flags,
|
|
|
|
ACCESS_MASK AccessMask,
|
|
|
|
IN GUID *ObjectTypeGuid OPTIONAL,
|
|
|
|
IN GUID *InheritedObjectTypeGuid OPTIONAL,
|
|
|
|
PSID Sid,
|
|
|
|
BOOLEAN Success,
|
|
|
|
BOOLEAN Failure)
|
2006-05-10 09:32:23 +00:00
|
|
|
{
|
2011-09-19 11:09:09 +00:00
|
|
|
UCHAR Type;
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Success)
|
|
|
|
{
|
|
|
|
Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
|
|
|
|
}
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Failure)
|
|
|
|
{
|
|
|
|
Flags |= FAILED_ACCESS_ACE_FLAG;
|
|
|
|
}
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
/* make sure we call RtlpAddKnownAce correctly */
|
|
|
|
if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
|
|
|
|
Type = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
|
|
|
|
else
|
|
|
|
Type = SYSTEM_AUDIT_ACE_TYPE;
|
2006-05-10 09:32:23 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
2006-05-10 09:32:23 +00:00
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
AccessMask,
|
|
|
|
ObjectTypeGuid,
|
|
|
|
InheritedObjectTypeGuid,
|
|
|
|
Sid,
|
|
|
|
Type);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-15 16:52:25 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlAddMandatoryAce(
|
|
|
|
IN OUT PACL Acl,
|
|
|
|
IN ULONG Revision,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN ULONG MandatoryFlags,
|
2011-09-19 11:09:09 +00:00
|
|
|
IN UCHAR AceType,
|
2011-09-18 15:10:05 +00:00
|
|
|
IN PSID LabelSid)
|
2006-10-15 16:52:25 +00:00
|
|
|
{
|
|
|
|
if (MandatoryFlags & ~SYSTEM_MANDATORY_LABEL_VALID_MASK)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
if (AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlpAddKnownAce(Acl,
|
|
|
|
Revision,
|
|
|
|
Flags,
|
|
|
|
(ACCESS_MASK)MandatoryFlags,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
LabelSid,
|
|
|
|
AceType);
|
2006-10-15 16:52:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
RtlpDeleteData(
|
|
|
|
PVOID Ace,
|
|
|
|
ULONG AceSize,
|
|
|
|
ULONG Offset)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
if (AceSize < Offset)
|
|
|
|
{
|
|
|
|
RtlMoveMemory(Ace,
|
|
|
|
(PVOID)((ULONG_PTR)Ace + AceSize),
|
|
|
|
Offset - AceSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Offset - AceSize < Offset)
|
|
|
|
{
|
|
|
|
RtlZeroMemory((PVOID)((ULONG_PTR)Ace + Offset - AceSize), AceSize);
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlDeleteAce(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG AceIndex)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Ace;
|
|
|
|
PACE Current;
|
|
|
|
PAGED_CODE_RTL();
|
|
|
|
|
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
|
|
|
Acl->AclRevision > MAX_ACL_REVISION ||
|
|
|
|
Acl->AceCount <= AceIndex ||
|
|
|
|
!RtlFirstFreeAce(Acl, &Ace))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
Current = (PACE)(Acl + 1);
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
while(AceIndex--)
|
|
|
|
{
|
|
|
|
Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize);
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
RtlpDeleteData(Current,
|
|
|
|
Current->Header.AceSize,
|
|
|
|
(ULONG)((ULONG_PTR)Ace - (ULONG_PTR)Current));
|
|
|
|
Acl->AceCount--;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlCreateAcl(
|
|
|
|
PACL Acl,
|
|
|
|
ULONG AclSize,
|
|
|
|
ULONG AclRevision)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (AclSize < sizeof(ACL))
|
|
|
|
{
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (AclRevision < MIN_ACL_REVISION ||
|
|
|
|
AclRevision > MAX_ACL_REVISION ||
|
|
|
|
AclSize > 0xffff)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
AclSize = ROUND_UP(AclSize, 4);
|
2011-09-20 17:33:51 +00:00
|
|
|
Acl->AclSize = (WORD)AclSize;
|
|
|
|
Acl->AclRevision = (BYTE)AclRevision;
|
2011-09-18 15:10:05 +00:00
|
|
|
Acl->AceCount = 0;
|
|
|
|
Acl->Sbz1 = 0;
|
|
|
|
Acl->Sbz2 = 0;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlQueryInformationAcl(
|
|
|
|
PACL Acl,
|
|
|
|
PVOID Information,
|
|
|
|
ULONG InformationLength,
|
|
|
|
ACL_INFORMATION_CLASS InformationClass)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Ace;
|
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
2004-11-27 16:33:21 +00:00
|
|
|
Acl->AclRevision > MAX_ACL_REVISION)
|
2011-09-18 15:10:05 +00:00
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
switch (InformationClass)
|
|
|
|
{
|
|
|
|
case AclRevisionInformation:
|
|
|
|
{
|
2004-05-31 19:33:59 +00:00
|
|
|
PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
|
|
|
|
|
|
|
|
if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
Info->AclRevision = Acl->AclRevision;
|
2011-09-18 15:10:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
case AclSizeInformation:
|
|
|
|
{
|
2004-05-31 19:33:59 +00:00
|
|
|
PACL_SIZE_INFORMATION Info = (PACL_SIZE_INFORMATION)Information;
|
|
|
|
|
|
|
|
if (InformationLength < sizeof(ACL_SIZE_INFORMATION))
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!RtlFirstFreeAce(Acl, &Ace))
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Info->AceCount = Acl->AceCount;
|
|
|
|
if (Ace != NULL)
|
|
|
|
{
|
2005-06-30 21:38:39 +00:00
|
|
|
Info->AclBytesInUse = (DWORD)((ULONG_PTR)Ace - (ULONG_PTR)Acl);
|
2004-05-31 19:33:59 +00:00
|
|
|
Info->AclBytesFree = Acl->AclSize - Info->AclBytesInUse;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Info->AclBytesInUse = Acl->AclSize;
|
|
|
|
Info->AclBytesFree = 0;
|
|
|
|
}
|
2011-09-18 15:10:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
default:
|
|
|
|
return STATUS_INVALID_INFO_CLASS;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-10-19 17:03:38 +00:00
|
|
|
NTSTATUS NTAPI
|
2004-05-31 19:33:59 +00:00
|
|
|
RtlSetInformationAcl(PACL Acl,
|
|
|
|
PVOID Information,
|
|
|
|
ULONG InformationLength,
|
|
|
|
ACL_INFORMATION_CLASS InformationClass)
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
2004-11-27 16:33:21 +00:00
|
|
|
Acl->AclRevision > MAX_ACL_REVISION)
|
2011-09-18 15:10:05 +00:00
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
switch (InformationClass)
|
|
|
|
{
|
|
|
|
case AclRevisionInformation:
|
|
|
|
{
|
2004-05-31 19:33:59 +00:00
|
|
|
PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
|
|
|
|
|
|
|
|
if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Acl->AclRevision >= Info->AclRevision)
|
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 17:33:51 +00:00
|
|
|
Acl->AclRevision = (BYTE)Info->AclRevision;
|
2011-09-18 15:10:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
default:
|
|
|
|
return STATUS_INVALID_INFO_CLASS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2011-09-18 15:10:05 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlValidAcl(PACL Acl)
|
2004-05-31 19:33:59 +00:00
|
|
|
{
|
2011-09-18 15:10:05 +00:00
|
|
|
PACE Ace;
|
|
|
|
USHORT Size;
|
|
|
|
PAGED_CODE_RTL();
|
2005-05-09 01:41:02 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
Size = ROUND_UP(Acl->AclSize, 4);
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Acl->AclRevision < MIN_ACL_REVISION ||
|
|
|
|
Acl->AclRevision > MAX_ACL_REVISION)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
if (Size != Acl->AclSize)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-05-31 19:33:59 +00:00
|
|
|
|
2011-09-18 15:10:05 +00:00
|
|
|
return RtlFirstFreeAce(Acl, &Ace);
|
2004-05-31 19:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|