Add missing processor architecture cases
[reactos.git] / reactos / ntoskrnl / se / sd.c
index 47ec5ba..651defd 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/se/sd.c
  * PURPOSE:         Security manager
- * 
+ *
  * PROGRAMMERS:     David Welch <welch@cwcom.net>
  */
 
 #include <ntoskrnl.h>
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SepInitSDs)
+#endif
+
+
 /* GLOBALS ******************************************************************/
 
 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
@@ -24,12 +29,14 @@ PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
 
 /* FUNCTIONS ***************************************************************/
 
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
 SepInitSDs(VOID)
 {
   /* Create PublicDefaultSd */
-  SePublicDefaultSd = ExAllocatePool(NonPagedPool,
-                                    sizeof(SECURITY_DESCRIPTOR));
+  SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
+                                    sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SePublicDefaultSd == NULL)
     return FALSE;
 
@@ -41,8 +48,8 @@ SepInitSDs(VOID)
                               FALSE);
 
   /* Create PublicDefaultUnrestrictedSd */
-  SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool,
-                                                sizeof(SECURITY_DESCRIPTOR));
+  SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+                                                sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SePublicDefaultUnrestrictedSd == NULL)
     return FALSE;
 
@@ -54,8 +61,8 @@ SepInitSDs(VOID)
                               FALSE);
 
   /* Create PublicOpenSd */
-  SePublicOpenSd = ExAllocatePool(NonPagedPool,
-                                 sizeof(SECURITY_DESCRIPTOR));
+  SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
+                                 sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SePublicOpenSd == NULL)
     return FALSE;
 
@@ -67,8 +74,8 @@ SepInitSDs(VOID)
                               FALSE);
 
   /* Create PublicOpenUnrestrictedSd */
-  SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool,
-                                             sizeof(SECURITY_DESCRIPTOR));
+  SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+                                             sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SePublicOpenUnrestrictedSd == NULL)
     return FALSE;
 
@@ -80,8 +87,8 @@ SepInitSDs(VOID)
                               FALSE);
 
   /* Create SystemDefaultSd */
-  SeSystemDefaultSd = ExAllocatePool(NonPagedPool,
-                                    sizeof(SECURITY_DESCRIPTOR));
+  SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
+                                    sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SeSystemDefaultSd == NULL)
     return FALSE;
 
@@ -93,8 +100,8 @@ SepInitSDs(VOID)
                               FALSE);
 
   /* Create UnrestrictedSd */
-  SeUnrestrictedSd = ExAllocatePool(NonPagedPool,
-                                   sizeof(SECURITY_DESCRIPTOR));
+  SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
+                                   sizeof(SECURITY_DESCRIPTOR), TAG_SD);
   if (SeUnrestrictedSd == NULL)
     return FALSE;
 
@@ -108,31 +115,274 @@ SepInitSDs(VOID)
   return TRUE;
 }
 
+NTSTATUS
+STDCALL
+SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
+                             PISECURITY_DESCRIPTOR SecurityDescriptor,
+                             PULONG BufferLength)
+{
+  ULONG_PTR Current;
+  ULONG SidSize;
+  ULONG SdSize;
+  NTSTATUS Status;
+
+  DPRINT("SeSetWorldSecurityDescriptor() called\n");
+
+  if (SecurityInformation == 0)
+    {
+      return STATUS_ACCESS_DENIED;
+    }
+
+  SidSize = RtlLengthSid(SeWorldSid);
+  SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
+
+  if (*BufferLength < SdSize)
+    {
+      *BufferLength = SdSize;
+      return STATUS_BUFFER_TOO_SMALL;
+    }
+
+  *BufferLength = SdSize;
+
+  Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
+           SECURITY_DESCRIPTOR_REVISION);
+  if (!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  SecurityDescriptor->Control |= SE_SELF_RELATIVE;
+  Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
+
+  if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+    {
+      RtlCopyMemory((PVOID)Current,
+      SeWorldSid,
+      SidSize);
+      SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+      Current += SidSize;
+    }
+
+  if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+    {
+      RtlCopyMemory((PVOID)Current,
+      SeWorldSid,
+      SidSize);
+      SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+      Current += SidSize;
+    }
+
+  if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    {
+      SecurityDescriptor->Control |= SE_DACL_PRESENT;
+    }
+
+  if (SecurityInformation & SACL_SECURITY_INFORMATION)
+    {
+      SecurityDescriptor->Control |= SE_SACL_PRESENT;
+    }
+
+  return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN POOL_TYPE PoolType,
+                                   IN BOOLEAN CaptureIfKernel,
+                                   OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+                                   OUT PBOOLEAN Present)
+{
+  PSECURITY_QUALITY_OF_SERVICE CapturedQos;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  PAGED_CODE();
+
+  ASSERT(CapturedSecurityQualityOfService);
+  ASSERT(Present);
+
+  if(ObjectAttributes != NULL)
+  {
+    if(AccessMode != KernelMode)
+    {
+      SECURITY_QUALITY_OF_SERVICE SafeQos;
+
+      _SEH_TRY
+      {
+        ProbeForRead(ObjectAttributes,
+                     sizeof(ObjectAttributes),
+                     sizeof(ULONG));
+        if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+        {
+          if(ObjectAttributes->SecurityQualityOfService != NULL)
+          {
+            ProbeForRead(ObjectAttributes->SecurityQualityOfService,
+                         sizeof(SECURITY_QUALITY_OF_SERVICE),
+                         sizeof(ULONG));
+
+            if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+               sizeof(SECURITY_QUALITY_OF_SERVICE))
+            {
+              /* don't allocate memory here because ExAllocate should bugcheck
+                 the system if it's buggy, SEH would catch that! So make a local
+                 copy of the qos structure.*/
+              RtlCopyMemory(&SafeQos,
+                            ObjectAttributes->SecurityQualityOfService,
+                            sizeof(SECURITY_QUALITY_OF_SERVICE));
+              *Present = TRUE;
+            }
+            else
+            {
+              Status = STATUS_INVALID_PARAMETER;
+            }
+          }
+          else
+          {
+            *CapturedSecurityQualityOfService = NULL;
+            *Present = FALSE;
+          }
+        }
+        else
+        {
+          Status = STATUS_INVALID_PARAMETER;
+        }
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if(NT_SUCCESS(Status))
+      {
+        if(*Present)
+        {
+          CapturedQos = ExAllocatePool(PoolType,
+                                       sizeof(SECURITY_QUALITY_OF_SERVICE));
+          if(CapturedQos != NULL)
+          {
+            RtlCopyMemory(CapturedQos,
+                          &SafeQos,
+                          sizeof(SECURITY_QUALITY_OF_SERVICE));
+            *CapturedSecurityQualityOfService = CapturedQos;
+          }
+          else
+          {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+          }
+        }
+        else
+        {
+          *CapturedSecurityQualityOfService = NULL;
+        }
+      }
+    }
+    else
+    {
+      if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+      {
+        if(CaptureIfKernel)
+        {
+          if(ObjectAttributes->SecurityQualityOfService != NULL)
+          {
+            if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+               sizeof(SECURITY_QUALITY_OF_SERVICE))
+            {
+              CapturedQos = ExAllocatePool(PoolType,
+                                           sizeof(SECURITY_QUALITY_OF_SERVICE));
+              if(CapturedQos != NULL)
+              {
+                RtlCopyMemory(CapturedQos,
+                              ObjectAttributes->SecurityQualityOfService,
+                              sizeof(SECURITY_QUALITY_OF_SERVICE));
+                *CapturedSecurityQualityOfService = CapturedQos;
+                *Present = TRUE;
+              }
+              else
+              {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+              }
+            }
+            else
+            {
+              Status = STATUS_INVALID_PARAMETER;
+            }
+          }
+          else
+          {
+            *CapturedSecurityQualityOfService = NULL;
+            *Present = FALSE;
+          }
+        }
+        else
+        {
+          *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
+          *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
+        }
+      }
+      else
+      {
+        Status = STATUS_INVALID_PARAMETER;
+      }
+    }
+  }
+  else
+  {
+    *CapturedSecurityQualityOfService = NULL;
+    *Present = FALSE;
+  }
+
+  return Status;
+}
+
+
+VOID
+NTAPI
+SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN BOOLEAN CaptureIfKernel)
+{
+  PAGED_CODE();
+
+  if(CapturedSecurityQualityOfService != NULL &&
+     (AccessMode != KernelMode ||
+      (AccessMode == KernelMode && CaptureIfKernel)))
+  {
+    ExFreePool(CapturedSecurityQualityOfService);
+  }
+}
+
+
 /*
  * @implemented
  */
 NTSTATUS
 STDCALL
 SeCaptureSecurityDescriptor(
-       IN PSECURITY_DESCRIPTOR OriginalSecurityDescriptor,
+       IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
        IN KPROCESSOR_MODE CurrentMode,
        IN POOL_TYPE PoolType,
        IN BOOLEAN CaptureIfKernel,
        OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
        )
 {
+  PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
   SECURITY_DESCRIPTOR DescriptorCopy;
-  PSECURITY_DESCRIPTOR NewDescriptor;
+  PISECURITY_DESCRIPTOR NewDescriptor;
   ULONG OwnerSAC = 0, GroupSAC = 0;
   ULONG OwnerSize = 0, GroupSize = 0;
   ULONG SaclSize = 0, DaclSize = 0;
   ULONG DescriptorSize = 0;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   if(OriginalSecurityDescriptor != NULL)
   {
     if(CurrentMode != KernelMode)
     {
+      RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
+
       _SEH_TRY
       {
         /* first only probe and copy until the control field of the descriptor
@@ -149,7 +399,7 @@ SeCaptureSecurityDescriptor(
           Status = STATUS_UNKNOWN_REVISION;
           _SEH_LEAVE;
         }
-        
+
         /* make a copy on the stack */
         DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
         DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
@@ -164,8 +414,8 @@ SeCaptureSecurityDescriptor(
                      sizeof(ULONG));
         if(DescriptorCopy.Control & SE_SELF_RELATIVE)
         {
-          PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
-          
+          PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+
           DescriptorCopy.Owner = (PSID)RelSD->Owner;
           DescriptorCopy.Group = (PSID)RelSD->Group;
           DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
@@ -184,7 +434,7 @@ SeCaptureSecurityDescriptor(
         Status = _SEH_GetExceptionCode();
       }
       _SEH_END;
-      
+
       if(!NT_SUCCESS(Status))
       {
         return Status;
@@ -196,7 +446,7 @@ SeCaptureSecurityDescriptor(
       {
         return STATUS_UNKNOWN_REVISION;
       }
-      
+
       *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
       return STATUS_SUCCESS;
     }
@@ -206,7 +456,7 @@ SeCaptureSecurityDescriptor(
       {
         return STATUS_UNKNOWN_REVISION;
       }
-      
+
       /* make a copy on the stack */
       DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
       DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
@@ -215,7 +465,7 @@ SeCaptureSecurityDescriptor(
                         sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
       if(DescriptorCopy.Control & SE_SELF_RELATIVE)
       {
-        PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+        PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
 
         DescriptorCopy.Owner = (PSID)RelSD->Owner;
         DescriptorCopy.Group = (PSID)RelSD->Group;
@@ -230,7 +480,7 @@ SeCaptureSecurityDescriptor(
         DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
       }
     }
-    
+
     if(DescriptorCopy.Control & SE_SELF_RELATIVE)
     {
       /* in case we're dealing with a self-relative descriptor, do a basic convert
@@ -254,7 +504,7 @@ SeCaptureSecurityDescriptor(
         DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
       }
     }
-    
+
     /* determine the size of the SIDs */
 #define DetermineSIDSize(SidType)                                              \
     do {                                                                       \
@@ -300,10 +550,10 @@ SeCaptureSecurityDescriptor(
       }                                                                        \
     }                                                                          \
     } while(0)
-    
+
     DetermineSIDSize(Owner);
     DetermineSIDSize(Group);
-    
+
     /* determine the size of the ACLs */
 #define DetermineACLSize(AclType, AclFlag)                                     \
     do {                                                                       \
@@ -352,10 +602,10 @@ SeCaptureSecurityDescriptor(
       DescriptorCopy.AclType = NULL;                                           \
     }                                                                          \
     } while(0)
-    
+
     DetermineACLSize(Sacl, SACL);
     DetermineACLSize(Dacl, DACL);
-    
+
     /* allocate enough memory to store a complete copy of a self-relative
        security descriptor */
     NewDescriptor = ExAllocatePool(PoolType,
@@ -363,11 +613,12 @@ SeCaptureSecurityDescriptor(
     if(NewDescriptor != NULL)
     {
       ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
-      
+
+      RtlZeroMemory(NewDescriptor, DescriptorSize);
       NewDescriptor->Revision = DescriptorCopy.Revision;
       NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
       NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
-      
+
       _SEH_TRY
       {
         /* setup the offsets and copy the SIDs and ACLs to the new
@@ -385,7 +636,7 @@ SeCaptureSecurityDescriptor(
           Offset += ROUND_UP(Type##Size, sizeof(ULONG));                       \
         }                                                                      \
         } while(0)
-        
+
         CopySIDOrACL(Owner);
         CopySIDOrACL(Group);
         CopySIDOrACL(Sacl);
@@ -396,7 +647,7 @@ SeCaptureSecurityDescriptor(
         Status = _SEH_GetExceptionCode();
       }
       _SEH_END;
-      
+
       if(NT_SUCCESS(Status))
       {
         /* we're finally done! copy the pointer to the captured descriptor to
@@ -420,7 +671,7 @@ SeCaptureSecurityDescriptor(
     /* nothing to do... */
     *CapturedSecurityDescriptor = NULL;
   }
-  
+
   return Status;
 }
 
@@ -433,8 +684,8 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
                              IN OUT PULONG Length,
                              IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
 {
-  PSECURITY_DESCRIPTOR ObjectSd;
-  PSECURITY_DESCRIPTOR_RELATIVE RelSD;
+  PISECURITY_DESCRIPTOR ObjectSd;
+  PISECURITY_DESCRIPTOR_RELATIVE RelSD;
   PSID Owner = NULL;
   PSID Group = NULL;
   PACL Dacl = NULL;
@@ -446,8 +697,8 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
   ULONG Control = 0;
   ULONG_PTR Current;
   ULONG SdLength;
-  
-  RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
+
+  RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
 
   if (*ObjectsSecurityDescriptor == NULL)
     {
@@ -572,11 +823,13 @@ SeReleaseSecurityDescriptor(
        IN BOOLEAN CaptureIfKernelMode
        )
 {
+  PAGED_CODE();
+
   /* WARNING! You need to call this function with the same value for CurrentMode
               and CaptureIfKernelMode that you previously passed to
               SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
   if(CapturedSecurityDescriptor != NULL &&
-     (CurrentMode == UserMode ||
+     (CurrentMode != KernelMode ||
       (CurrentMode == KernelMode && CaptureIfKernelMode)))
   {
     /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
@@ -626,11 +879,12 @@ SeSetSecurityDescriptorInfoEx(
  */
 BOOLEAN STDCALL
 SeValidSecurityDescriptor(IN ULONG Length,
-                         IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+                         IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
 {
   ULONG SdLength;
   PISID Sid;
   PACL Acl;
+  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
 
   if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
     {