-/* $Id: acl.c,v 1.14 2003/12/30 18:52:06 fireball Exp $
+/* $Id$
*
- * 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
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/se/acl.c
+ * PURPOSE: Security manager
+ *
+ * PROGRAMMERS: David Welch <welch@cwcom.net>
*/
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/se.h>
-
+#include <ntoskrnl.h>
#include <internal/debug.h>
-#define TAG_ACL TAG('A', 'C', 'L', 'T')
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SepInitDACLs)
+#endif
/* GLOBALS ******************************************************************/
-PACL EXPORTED SePublicDefaultDacl = NULL;
-PACL EXPORTED SeSystemDefaultDacl = NULL;
+PACL SePublicDefaultDacl = NULL;
+PACL SeSystemDefaultDacl = NULL;
PACL SePublicDefaultUnrestrictedDacl = NULL;
PACL SePublicOpenDacl = NULL;
/* FUNCTIONS ****************************************************************/
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
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));
+ ULONG AclLength;
/* create PublicDefaultDacl */
- SePublicDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength2,
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid));
+
+ SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
TAG_ACL);
if (SePublicDefaultDacl == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateAcl(SePublicDefaultDacl,
- AclLength2,
- 2);
+ AclLength,
+ ACL_REVISION);
RtlAddAccessAllowedAce(SePublicDefaultDacl,
- 2,
+ ACL_REVISION,
GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicDefaultDacl,
- 2,
+ ACL_REVISION,
GENERIC_ALL,
SeLocalSystemSid);
/* create PublicDefaultUnrestrictedDacl */
- SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength4,
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
+
+ SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
TAG_ACL);
if (SePublicDefaultUnrestrictedDacl == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateAcl(SePublicDefaultUnrestrictedDacl,
- AclLength4,
- 2);
+ AclLength,
+ ACL_REVISION);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
- 4,
+ ACL_REVISION,
GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
- 4,
+ ACL_REVISION,
GENERIC_ALL,
SeLocalSystemSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
- 4,
+ ACL_REVISION,
GENERIC_ALL,
SeAliasAdminsSid);
RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
- 4,
- GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
SeRestrictedCodeSid);
/* create PublicOpenDacl */
- SePublicOpenDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength3,
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
+
+ SePublicOpenDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
TAG_ACL);
if (SePublicOpenDacl == NULL)
- return(FALSE);
+ return FALSE;
RtlCreateAcl(SePublicOpenDacl,
- AclLength3,
- 3);
+ AclLength,
+ ACL_REVISION);
RtlAddAccessAllowedAce(SePublicOpenDacl,
- 2,
+ ACL_REVISION,
GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
SeWorldSid);
RtlAddAccessAllowedAce(SePublicOpenDacl,
- 2,
+ ACL_REVISION,
GENERIC_ALL,
SeLocalSystemSid);
RtlAddAccessAllowedAce(SePublicOpenDacl,
- 2,
+ ACL_REVISION,
GENERIC_ALL,
SeAliasAdminsSid);
+ /* create PublicOpenUnrestrictedDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
+
+ SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
+ TAG_ACL);
+ if (SePublicOpenUnrestrictedDacl == NULL)
+ return FALSE;
+
+ RtlCreateAcl(SePublicOpenUnrestrictedDacl,
+ AclLength,
+ ACL_REVISION);
+
+ RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeWorldSid);
- return(TRUE);
-}
+ RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeLocalSystemSid);
+ RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeAliasAdminsSid);
-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);
- }
+ RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ SeRestrictedCodeSid);
- AclEnd = Acl->AclSize + (char*)Acl;
- do
- {
- if ((PVOID)Current >= AclEnd)
- {
- return(FALSE);
- }
-
- if (Current->Header.AceType == 4)
- {
- if (Acl->AclRevision < 3)
- {
- return(FALSE);
- }
- }
- Current = (PACE)((char*)Current + (ULONG)Current->Header.AceSize);
- i++;
- }
- while (i < Acl->AceCount);
+ /* create SystemDefaultDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
- if ((PVOID)Current < AclEnd)
- {
- *Ace = Current;
- }
+ SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
+ TAG_ACL);
+ if (SeSystemDefaultDacl == NULL)
+ return FALSE;
- return(TRUE);
-}
+ RtlCreateAcl(SeSystemDefaultDacl,
+ AclLength,
+ ACL_REVISION);
+ RtlAddAccessAllowedAce(SeSystemDefaultDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeLocalSystemSid);
-NTSTATUS
-RtlpAddKnownAce(PACL Acl,
- ULONG Revision,
- ACCESS_MASK AccessMask,
- PSID Sid,
- ULONG Type)
-{
- PACE Ace;
+ RtlAddAccessAllowedAce(SeSystemDefaultDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
+ SeAliasAdminsSid);
- 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 (((char*)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
- ((char*)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);
-}
+ /* create UnrestrictedDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
+ SeUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool,
+ AclLength,
+ TAG_ACL);
+ if (SeUnrestrictedDacl == NULL)
+ return FALSE;
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlAddAccessAllowedAce(PACL Acl,
- ULONG Revision,
- ACCESS_MASK AccessMask,
- PSID Sid)
-{
- return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
-}
+ RtlCreateAcl(SeUnrestrictedDacl,
+ AclLength,
+ ACL_REVISION);
+ RtlAddAccessAllowedAce(SeUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeWorldSid);
-/*
- * @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)((char*)AceList + AceListLength) <= (PVOID)AceList)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- i = 0;
- Current = (PACE)(Acl + 1);
- while ((char*)Current < ((char*)AceList + AceListLength))
- {
- if (AceList->Header.AceType == 4 &&
- AclRevision < 3)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- Current = (PACE)((char*)Current + Current->Header.AceSize);
- }
- if (Ace == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (((char*)Ace + AceListLength) >= ((char*)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)((char*)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);
-}
+ RtlAddAccessAllowedAce(SeUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ SeRestrictedCodeSid);
+ return(TRUE);
+}
-/*
- * @implemented
- */
NTSTATUS STDCALL
-RtlCreateAcl(PACL Acl,
- ULONG AclSize,
- ULONG AclRevision)
+SepCreateImpersonationTokenDacl(PTOKEN Token,
+ PTOKEN PrimaryToken,
+ PACL *Dacl)
{
- if (AclSize < 8)
- {
- return(STATUS_BUFFER_TOO_SMALL);
- }
- if (AclRevision != 2 &&
- AclRevision != 3)
+ ULONG AclLength;
+ PVOID TokenDacl;
+
+ PAGED_CODE();
+
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) +
+ (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid));
+
+ TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL);
+ if (TokenDacl == NULL)
{
- return(STATUS_UNKNOWN_REVISION);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- if (AclSize > 0xffff)
+
+ RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION);
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ Token->UserAndGroups->Sid);
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ PrimaryToken->UserAndGroups->Sid);
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ SeAliasAdminsSid);
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ SeLocalSystemSid);
+
+ /* FIXME */
+#if 0
+ if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL)
{
- return(STATUS_UNSUCCESSFUL);
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ SeRestrictedCodeSid);
}
- AclSize = AclSize & ~(0x3);
- Acl->AclSize = AclSize;
- Acl->AclRevision = AclRevision;
- Acl->AceCount = 0;
- Acl->Sbz1 = 0;
- Acl->Sbz2 = 0;
- return(STATUS_SUCCESS);
-}
+#endif
+ return STATUS_SUCCESS;
+}
-BOOLEAN STDCALL
-RtlValidAcl(PACL Acl)
+NTSTATUS
+NTAPI
+SepCaptureAcl(IN PACL InputAcl,
+ IN KPROCESSOR_MODE AccessMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PACL *CapturedAcl)
{
- PACE Ace;
- USHORT Size;
+ PACL NewAcl;
+ ULONG AclSize = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
- Size = (Acl->AclSize + 3) & ~3;
+ if(AccessMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(InputAcl,
+ sizeof(ACL),
+ sizeof(ULONG));
+ AclSize = InputAcl->AclSize;
+ ProbeForRead(InputAcl,
+ AclSize,
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
- if (Acl->AclRevision != 2 &&
- Acl->AclRevision != 3)
+ if(NT_SUCCESS(Status))
{
- return(FALSE);
+ NewAcl = ExAllocatePool(PoolType,
+ AclSize);
+ if(NewAcl != NULL)
+ {
+ _SEH_TRY
+ {
+ RtlCopyMemory(NewAcl,
+ InputAcl,
+ AclSize);
+
+ *CapturedAcl = NewAcl;
+ }
+ _SEH_HANDLE
+ {
+ ExFreePool(NewAcl);
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
}
+ }
+ else if(!CaptureIfKernel)
+ {
+ *CapturedAcl = InputAcl;
+ }
+ else
+ {
+ AclSize = InputAcl->AclSize;
+
+ NewAcl = ExAllocatePool(PoolType,
+ AclSize);
+
+ if(NewAcl != NULL)
+ {
+ RtlCopyMemory(NewAcl,
+ InputAcl,
+ AclSize);
- if (Size != Acl->AclSize)
+ *CapturedAcl = NewAcl;
+ }
+ else
{
- return(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
}
+ }
+
+ return Status;
+}
- return(RtlFirstFreeAce(Acl, &Ace));
+VOID
+NTAPI
+SepReleaseAcl(IN PACL CapturedAcl,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel)
+{
+ PAGED_CODE();
+
+ if(CapturedAcl != NULL &&
+ (AccessMode != KernelMode ||
+ (AccessMode == KernelMode && CaptureIfKernel)))
+ {
+ ExFreePool(CapturedAcl);
+ }
}
/* EOF */