reactos/reactos/ntoskrnl/se/acl.c
2003-07-11 01:23:16 +00:00

362 lines
7.1 KiB
C

/* $Id: acl.c,v 1.12 2003/07/11 01:23:16 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Security manager
* FILE: kernel/se/acl.c
* PROGRAMER: David Welch <welch@cwcom.net>
* REVISION HISTORY:
* 26/07/98: Added stubs for security functions
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/se.h>
#include <internal/debug.h>
#define TAG_ACL TAG('A', 'C', 'L', 'T')
/* GLOBALS ******************************************************************/
PACL EXPORTED SePublicDefaultDacl = NULL;
PACL EXPORTED SeSystemDefaultDacl = NULL;
PACL SePublicDefaultUnrestrictedDacl = NULL;
PACL SePublicOpenDacl = NULL;
PACL SePublicOpenUnrestrictedDacl = NULL;
PACL SeUnrestrictedDacl = NULL;
/* FUNCTIONS ****************************************************************/
BOOLEAN
SepInitDACLs(VOID)
{
ULONG AclLength2;
ULONG AclLength3;
ULONG AclLength4;
AclLength2 = sizeof(ACL) +
2 * (RtlLengthRequiredSid(1) + sizeof(ACE));
AclLength3 = sizeof(ACL) +
3 * (RtlLengthRequiredSid(1) + sizeof(ACE));
AclLength4 = sizeof(ACL) +
4 * (RtlLengthRequiredSid(1) + sizeof(ACE));
/* create PublicDefaultDacl */
SePublicDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
AclLength2,
TAG_ACL);
if (SePublicDefaultDacl == NULL)
return(FALSE);
RtlCreateAcl(SePublicDefaultDacl,
AclLength2,
2);
RtlAddAccessAllowedAce(SePublicDefaultDacl,
2,
GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicDefaultDacl,
2,
GENERIC_ALL,
SeLocalSystemSid);
/* create PublicDefaultUnrestrictedDacl */
SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
AclLength4,
TAG_ACL);
if (SePublicDefaultUnrestrictedDacl == NULL)
return(FALSE);
RtlCreateAcl(SePublicDefaultUnrestrictedDacl,
AclLength4,
2);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
4,
GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
4,
GENERIC_ALL,
SeLocalSystemSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
4,
GENERIC_ALL,
SeAliasAdminsSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
4,
GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ,
SeRestrictedCodeSid);
/* create PublicOpenDacl */
SePublicOpenDacl = ExAllocatePoolWithTag(NonPagedPool,
AclLength3,
TAG_ACL);
if (SePublicOpenDacl == NULL)
return(FALSE);
RtlCreateAcl(SePublicOpenDacl,
AclLength3,
3);
RtlAddAccessAllowedAce(SePublicOpenDacl,
2,
GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicOpenDacl,
2,
GENERIC_ALL,
SeLocalSystemSid);
RtlAddAccessAllowedAce(SePublicOpenDacl,
2,
GENERIC_ALL,
SeAliasAdminsSid);
return(TRUE);
}
BOOLEAN STDCALL
RtlFirstFreeAce(PACL Acl,
PACE* Ace)
{
PACE Current;
PVOID AclEnd;
ULONG i;
Current = (PACE)(Acl + 1);
*Ace = NULL;
i = 0;
if (Acl->AceCount == 0)
{
*Ace = Current;
return(TRUE);
}
AclEnd = Acl->AclSize + (PVOID)Acl;
do
{
if ((PVOID)Current >= AclEnd)
{
return(FALSE);
}
if (Current->Header.AceType == 4)
{
if (Acl->AclRevision < 3)
{
return(FALSE);
}
}
Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
i++;
}
while (i < Acl->AceCount);
if ((PVOID)Current < AclEnd)
{
*Ace = Current;
}
return(TRUE);
}
NTSTATUS
RtlpAddKnownAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid,
ULONG Type)
{
PACE Ace;
if (!RtlValidSid(Sid))
{
return(STATUS_INVALID_SID);
}
if (Acl->AclRevision > 3 ||
Revision > 3)
{
return(STATUS_UNKNOWN_REVISION);
}
if (Revision < Acl->AclRevision)
{
Revision = Acl->AclRevision;
}
if (!RtlFirstFreeAce(Acl, &Ace))
{
return(STATUS_BUFFER_TOO_SMALL);
}
if (Ace == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
((PVOID)Acl + Acl->AclSize))
{
return(STATUS_BUFFER_TOO_SMALL);
}
Ace->Header.AceFlags = 0;
Ace->Header.AceType = Type;
Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
Ace->AccessMask = AccessMask;
RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
Acl->AceCount++;
Acl->AclRevision = Revision;
return(STATUS_SUCCESS);
}
/*
* @implemented
*/
NTSTATUS STDCALL
RtlAddAccessAllowedAce(PACL Acl,
ULONG Revision,
ACCESS_MASK AccessMask,
PSID Sid)
{
return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
}
/*
* @implemented
*/
NTSTATUS STDCALL
RtlAddAce(PACL Acl,
ULONG AclRevision,
ULONG StartingIndex,
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);
}
/*
* @implemented
*/
NTSTATUS STDCALL
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);
}
BOOLEAN STDCALL
RtlValidAcl(PACL Acl)
{
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 */