preliminary comment out the self-modifying code for RtlPrefetchMemoryNonTemporal
[reactos.git] / reactos / ntoskrnl / se / acl.c
index b0e7569..2ed3541 100644 (file)
-/* $Id: acl.c,v 1.2 1999/12/26 17:22:19 ea 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 <ntoskrnl.h>
 #include <internal/debug.h>
 
-/* FUNCTIONS ***************************************************************/
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SepInitDACLs)
+#endif
+
+
+/* GLOBALS ******************************************************************/
+
+PACL SePublicDefaultDacl = NULL;
+PACL SeSystemDefaultDacl = NULL;
+
+PACL SePublicDefaultUnrestrictedDacl = NULL;
+PACL SePublicOpenDacl = NULL;
+PACL SePublicOpenUnrestrictedDacl = NULL;
+PACL SeUnrestrictedDacl = NULL;
+
+
+/* FUNCTIONS ****************************************************************/
 
-BOOLEAN RtlFirstFreeAce(PACL Acl, PACE* Ace)
+BOOLEAN
+INIT_FUNCTION
+NTAPI
+SepInitDACLs(VOID)
 {
-   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);
+  ULONG AclLength;
+
+  /* create PublicDefaultDacl */
+  AclLength = sizeof(ACL) +
+             (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
+             (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid));
+
+  SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool,
+                                             AclLength,
+                                             TAG_ACL);
+  if (SePublicDefaultDacl == NULL)
+    return FALSE;
+
+  RtlCreateAcl(SePublicDefaultDacl,
+              AclLength,
+              ACL_REVISION);
+
+  RtlAddAccessAllowedAce(SePublicDefaultDacl,
+                        ACL_REVISION,
+                        GENERIC_EXECUTE,
+                        SeWorldSid);
+
+  RtlAddAccessAllowedAce(SePublicDefaultDacl,
+                        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(PagedPool,
+                                                         AclLength,
+                                                         TAG_ACL);
+  if (SePublicDefaultUnrestrictedDacl == NULL)
+    return FALSE;
+
+  RtlCreateAcl(SePublicDefaultUnrestrictedDacl,
+              AclLength,
+              ACL_REVISION);
+
+  RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_EXECUTE,
+                        SeWorldSid);
+
+  RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_ALL,
+                        SeLocalSystemSid);
+
+  RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_ALL,
+                        SeAliasAdminsSid);
+
+  RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl,
+                        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(PagedPool,
+                                          AclLength,
+                                          TAG_ACL);
+  if (SePublicOpenDacl == NULL)
+    return FALSE;
+
+  RtlCreateAcl(SePublicOpenDacl,
+              AclLength,
+              ACL_REVISION);
+
+  RtlAddAccessAllowedAce(SePublicOpenDacl,
+                        ACL_REVISION,
+                        GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
+                        SeWorldSid);
+
+  RtlAddAccessAllowedAce(SePublicOpenDacl,
+                        ACL_REVISION,
+                        GENERIC_ALL,
+                        SeLocalSystemSid);
+
+  RtlAddAccessAllowedAce(SePublicOpenDacl,
+                        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);
+
+  RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_ALL,
+                        SeLocalSystemSid);
+
+  RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_ALL,
+                        SeAliasAdminsSid);
+
+  RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl,
+                        ACL_REVISION,
+                        GENERIC_READ | GENERIC_EXECUTE,
+                        SeRestrictedCodeSid);
+
+  /* create SystemDefaultDacl */
+  AclLength = sizeof(ACL) +
+             (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
+             (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
+
+  SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool,
+                                             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(PagedPool,
+                                            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 RtlpAddKnownAce(PACL Acl,
-                        ULONG Revision,
-                        ACCESS_MASK AccessMask,
-                        PSID Sid,
-                        ULONG Type)
+NTSTATUS STDCALL
+SepCreateImpersonationTokenDacl(PTOKEN Token,
+                                PTOKEN PrimaryToken,
+                                PACL *Dacl)
 {
-   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), Sid, (PSID)Ace + 1);
-   Acl->AceCount++;
-   Acl->AclRevision = Revision;
-   return(STATUS_SUCCESS);
+  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 RtlAddAccessAllowedAce(PACL Acl,
-                               ULONG Revision,
-                               ACCESS_MASK AccessMask,
-                               PSID Sid)
+NTSTATUS
+NTAPI
+SepCaptureAcl(IN PACL InputAcl,
+              IN KPROCESSOR_MODE AccessMode,
+              IN POOL_TYPE PoolType,
+              IN BOOLEAN CaptureIfKernel,
+              OUT PACL *CapturedAcl)
 {
-   return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
-}
+  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);
 
-NTSTATUS RtlAddAcl(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);
+          *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 RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
+
+VOID
+NTAPI
+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 != KernelMode ||
+      (AccessMode == KernelMode && CaptureIfKernel)))
+  {
+    ExFreePool(CapturedAcl);
+  }
+}
 
 /* EOF */