preliminary comment out the self-modifying code for RtlPrefetchMemoryNonTemporal
[reactos.git] / reactos / ntoskrnl / se / acl.c
index cb7f1b6..2ed3541 100644 (file)
@@ -1,23 +1,21 @@
-/* $Id: acl.c,v 1.8 2002/09/07 15:13:06 chorns 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 <ntoskrnl.h>
-
-#define NDEBUG
 #include <internal/debug.h>
 
-
-#define TAG_ACL    TAG('A', 'C', 'L', 'T')
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SepInitDACLs)
+#endif
 
 
 /* GLOBALS ******************************************************************/
@@ -34,293 +32,342 @@ PACL SeUnrestrictedDacl = NULL;
 /* FUNCTIONS ****************************************************************/
 
 BOOLEAN
+INIT_FUNCTION
+NTAPI
 SepInitDACLs(VOID)
 {
-  ULONG AclLength2;
-  ULONG AclLength3;
-  ULONG AclLength4;
-
-  AclLength2 = sizeof(ACL) +
-              2 * (RtlLengthRequiredSid(1) + sizeof(ROS_ACE_HEADER));
-  AclLength3 = sizeof(ACL) +
-              3 * (RtlLengthRequiredSid(1) + sizeof(ROS_ACE_HEADER));
-  AclLength4 = sizeof(ACL) +
-              4 * (RtlLengthRequiredSid(1) + sizeof(ROS_ACE_HEADER));
+  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);
+
+  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);
 }
 
-
-BOOLEAN STDCALL
-RtlFirstFreeAce(PACL Acl,
-               PACE* Ace)
+NTSTATUS STDCALL
+SepCreateImpersonationTokenDacl(PTOKEN Token,
+                                PTOKEN PrimaryToken,
+                                PACL *Dacl)
 {
-   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;
+  PVOID TokenDacl;
 
+  PAGED_CODE();
 
-NTSTATUS
-RtlpAddKnownAce(PACL Acl,
-               ULONG Revision,
-               ACCESS_MASK AccessMask,
-               PSID Sid,
-               ULONG Type)
-{
-  PROS_ACE Ace;
+  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));
 
-  if (!RtlValidSid(Sid))
+  TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL);
+  if (TokenDacl == NULL)
     {
-      return(STATUS_INVALID_SID);
+      return STATUS_INSUFFICIENT_RESOURCES;
     }
-  if (Acl->AclRevision > 3 ||
-      Revision > 3)
-    {
-      return(STATUS_UNKNOWN_REVISION);
-    }
-  if (Revision < Acl->AclRevision)
-    {
-      Revision = Acl->AclRevision;
-    }
-  if (!RtlFirstFreeAce(Acl, (PACE*)&Ace))
-    {
-      return(STATUS_BUFFER_TOO_SMALL);
-    }
-  if (Ace == NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-  if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ROS_ACE)) >= 
-      ((PVOID)Acl + Acl->AclSize))
+
+  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_BUFFER_TOO_SMALL);
+      RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL,
+                             SeRestrictedCodeSid);
     }
-  Ace->Header.AceFlags = 0;
-  Ace->Header.AceType = Type;
-  Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ROS_ACE);
-  Ace->Header.AccessMask = AccessMask;
-  RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
-  Acl->AceCount++;
-  Acl->AclRevision = Revision;
-  return(STATUS_SUCCESS);
-}
-
+#endif
 
-NTSTATUS STDCALL
-RtlAddAccessAllowedAce(PACL Acl,
-                      ULONG Revision,
-                      ACCESS_MASK AccessMask,
-                      PSID Sid)
-{
-  return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
+  return STATUS_SUCCESS;
 }
 
-
-NTSTATUS STDCALL
-RtlAddAce(PACL Acl,
-         ULONG AclRevision,
-         ULONG StartingIndex,
-         PACE AceList,
-         ULONG AceListLength)
+NTSTATUS
+NTAPI
+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();
 
-NTSTATUS STDCALL
-RtlCreateAcl(PACL Acl,
-            ULONG AclSize,
-            ULONG AclRevision)
-{
-  if (AclSize < 8)
+  if(AccessMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(InputAcl,
+                   sizeof(ACL),
+                   sizeof(ULONG));
+      AclSize = InputAcl->AclSize;
+      ProbeForRead(InputAcl,
+                   AclSize,
+                   sizeof(ULONG));
+    }
+    _SEH_HANDLE
     {
-      return(STATUS_BUFFER_TOO_SMALL);
+      Status = _SEH_GetExceptionCode();
     }
-  if (AclRevision != 2 &&
-      AclRevision != 3)
+    _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)
     {
-      return(STATUS_UNKNOWN_REVISION);
+      RtlCopyMemory(NewAcl,
+                    InputAcl,
+                    AclSize);
+
+      *CapturedAcl = NewAcl;
     }
-  if (AclSize > 0xffff)
+    else
     {
-      return(STATUS_UNSUCCESSFUL);
+      Status = STATUS_INSUFFICIENT_RESOURCES;
     }
-  AclSize = AclSize & ~(0x3);
-  Acl->AclSize = AclSize;
-  Acl->AclRevision = AclRevision;
-  Acl->AceCount = 0;
-  Acl->Sbz1 = 0;
-  Acl->Sbz2 = 0;
-  return(STATUS_SUCCESS);
+  }
+
+  return Status;
+}
+
+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 */