-/* $Id: acl.c,v 1.5 2002/02/20 20:15:38 ekohl 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')
/* FUNCTIONS ****************************************************************/
-BOOLEAN
+BOOLEAN INIT_FUNCTION
SepInitDACLs(VOID)
{
- ULONG AclLength2;
- ULONG AclLength3;
- ULONG AclLength4;
-
- AclLength2 = sizeof(ACL) +
- 2 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
- AclLength3 = sizeof(ACL) +
- 3 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
- AclLength4 = sizeof(ACL) +
- 4 * (RtlLengthRequiredSid(1) + sizeof(ACE_HEADER));
+ ULONG AclLength;
/* create PublicDefaultDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid));
+
SePublicDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength2,
+ 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 */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
+
SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength4,
+ 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 */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
+
SePublicOpenDacl = ExAllocatePoolWithTag(NonPagedPool,
- AclLength3,
+ 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(NonPagedPool,
+ 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);
- }
- AclEnd = Acl->AclSize + 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)
- {
- return(FALSE);
- }
- *Ace = Current;
- return(TRUE);
-}
+ RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ SeRestrictedCodeSid);
-NTSTATUS RtlpAddKnownAce(PACL Acl,
- ULONG Revision,
- ACCESS_MASK AccessMask,
- PSID Sid,
- ULONG Type)
-{
- PACE Ace;
-
- if (!RtlValidSid(Sid))
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (Acl->AclRevision > 3 ||
- Revision > 3)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (Revision < Acl->AclRevision)
- {
- Revision = Acl->AclRevision;
- }
- if (!RtlFirstFreeAce(Acl, &Ace))
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (Ace == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
- ((PVOID)Acl + Acl->AclSize))
- {
- return(STATUS_UNSUCCESSFUL);
- }
- Ace->Header.AceFlags = 0;
- Ace->Header.AceType = Type;
- 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);
+ /* create SystemDefaultDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
+
+ SeSystemDefaultDacl = ExAllocatePoolWithTag(NonPagedPool,
+ AclLength,
+ TAG_ACL);
+ if (SeSystemDefaultDacl == NULL)
+ return FALSE;
+
+ RtlCreateAcl(SeSystemDefaultDacl,
+ AclLength,
+ ACL_REVISION);
+
+ RtlAddAccessAllowedAce(SeSystemDefaultDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeLocalSystemSid);
+
+ RtlAddAccessAllowedAce(SeSystemDefaultDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
+ SeAliasAdminsSid);
+
+ /* create UnrestrictedDacl */
+ AclLength = sizeof(ACL) +
+ (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+ (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
+
+ SeUnrestrictedDacl = ExAllocatePoolWithTag(NonPagedPool,
+ AclLength,
+ TAG_ACL);
+ if (SeUnrestrictedDacl == NULL)
+ return FALSE;
+
+ RtlCreateAcl(SeUnrestrictedDacl,
+ AclLength,
+ ACL_REVISION);
+
+ RtlAddAccessAllowedAce(SeUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeWorldSid);
+
+ RtlAddAccessAllowedAce(SeUnrestrictedDacl,
+ ACL_REVISION,
+ GENERIC_READ | GENERIC_EXECUTE,
+ SeRestrictedCodeSid);
+
+ return(TRUE);
}
-NTSTATUS STDCALL
-RtlAddAccessAllowedAce(PACL Acl,
- ULONG Revision,
- ACCESS_MASK AccessMask,
- PSID Sid)
+NTSTATUS STDCALL
+SepCreateImpersonationTokenDacl(PTOKEN Token,
+ PTOKEN PrimaryToken,
+ PACL *Dacl)
{
- return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
+ 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_INSUFFICIENT_RESOURCES;
+ }
+
+ 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)
+ {
+ RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+ SeRestrictedCodeSid);
+ }
+#endif
+
+ return STATUS_SUCCESS;
}
-NTSTATUS STDCALL
-RtlAddAce(PACL Acl,
- ULONG AclRevision,
- ULONG StartingIndex,
- PACE AceList,
- ULONG AceListLength)
+NTSTATUS
+SepCaptureAcl(IN PACL InputAcl,
+ IN KPROCESSOR_MODE AccessMode,
+ IN POOL_TYPE PoolType,
+ IN BOOLEAN CaptureIfKernel,
+ OUT PACL *CapturedAcl)
{
- 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);
+ PACL NewAcl;
+ ULONG AclSize = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ 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(NT_SUCCESS(Status))
+ {
+ 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);
+
+ *CapturedAcl = NewAcl;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ return Status;
}
-
-NTSTATUS STDCALL
-RtlCreateAcl(PACL Acl,
- ULONG AclSize,
- ULONG AclRevision)
+VOID
+SepReleaseAcl(IN PACL CapturedAcl,
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN CaptureIfKernel)
{
- if (AclSize < 8)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (AclRevision != 2 ||
- AclRevision != 3)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- 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);
+ PAGED_CODE();
+
+ if(CapturedAcl != NULL &&
+ (AccessMode == UserMode ||
+ (AccessMode == KernelMode && CaptureIfKernel)))
+ {
+ ExFreePool(CapturedAcl);
+ }
}
/* EOF */