The default object security method should not directly call Se* routines on the Secur...
authorAleksey Bragin <aleksey@reactos.org>
Mon, 31 Mar 2008 20:07:02 +0000 (20:07 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Mon, 31 Mar 2008 20:07:02 +0000 (20:07 +0000)
Additionally, the code for the "Set" operation should actually go in SeSetSecurityDescriptorInfo API, which was unimplemented. By simply copying the code over, this API is now implemented, and the routine works as expected.
Also, the default method was not handling "delete" requests, but was ignoring them, resulting in memory leaks and never-dereferenced descriptors.
Thanks to Alex for finding these bugs. Alex also says SeSetSecurityDescriptorInfo should call the Rtl package (RtlSetObjectSecurity) but we don't implement those functions yet.

svn path=/trunk/; revision=32799

reactos/ntoskrnl/include/internal/ob.h
reactos/ntoskrnl/ob/obsecure.c
reactos/ntoskrnl/se/sd.c
reactos/ntoskrnl/se/semgr.c

index c6402d4..a155da2 100644 (file)
@@ -374,12 +374,6 @@ ObpAddSecurityDescriptor(
     OUT PSECURITY_DESCRIPTOR *DestinationSD
 );
 
-NTSTATUS
-NTAPI
-ObpRemoveSecurityDescriptor(
-    IN PSECURITY_DESCRIPTOR SecurityDescriptor
-);
-
 PSECURITY_DESCRIPTOR
 NTAPI
 ObpReferenceCachedSecurityDescriptor(
@@ -438,6 +432,44 @@ ObpCheckObjectReference(
     OUT PNTSTATUS AccessStatus
 );
 
+//
+// Default Object Security Callback Routines
+//
+NTSTATUS
+NTAPI
+ObAssignObjectSecurityDescriptor(
+    IN PVOID Object,
+    IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
+    IN POOL_TYPE PoolType
+);
+
+NTSTATUS
+NTAPI
+ObDeassignSecurity(
+    IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor
+);
+
+NTSTATUS
+NTAPI
+ObQuerySecurityDescriptorInfo(
+    IN PVOID Object,
+    IN PSECURITY_INFORMATION SecurityInformation,
+    OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+    IN OUT PULONG Length,
+    IN PSECURITY_DESCRIPTOR *OutputSecurityDescriptor
+);
+
+NTSTATUS
+NTAPI
+ObSetSecurityDescriptorInfo(
+    IN PVOID Object,
+    IN PSECURITY_INFORMATION SecurityInformation,
+    IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+    IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
+    IN POOL_TYPE PoolType,
+    IN PGENERIC_MAPPING GenericMapping
+);
+
 //
 // Executive Fast Referencing Functions
 //
index 41a9eea..5f63577 100644 (file)
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
+NTSTATUS
+NTAPI
+ObAssignObjectSecurityDescriptor(IN PVOID Object,
+                                 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
+                                 IN POOL_TYPE PoolType)
+{
+    POBJECT_HEADER ObjectHeader;
+    NTSTATUS Status;
+    PSECURITY_DESCRIPTOR NewSd;
+    PAGED_CODE();
+    
+    /* Get the object header */
+    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+    if (!SecurityDescriptor)
+    {
+        /* Nothing to assign */
+        ObjectHeader->SecurityDescriptor = NULL;
+        return STATUS_SUCCESS;
+    }
+    
+    /* Add it to our internal cache */
+    Status = ObpAddSecurityDescriptor(SecurityDescriptor, &NewSd);
+    if (NT_SUCCESS(Status))
+    {
+        /* Free the old copy */
+        ExFreePool(SecurityDescriptor);
+        
+        /* Set the new pointer */
+        ASSERT(NewSd);
+        ObjectHeader->SecurityDescriptor = NewSd;
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
+{
+    /* Dereference it */
+    ObpDereferenceCachedSecurityDescriptor(*SecurityDescriptor);
+    
+    /* Don't free again later */
+    *SecurityDescriptor = NULL;
+    
+    /* All done */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ObQuerySecurityDescriptorInfo(IN PVOID Object,
+                              IN PSECURITY_INFORMATION SecurityInformation,
+                              OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+                              IN OUT PULONG Length,
+                              IN PSECURITY_DESCRIPTOR *OutputSecurityDescriptor)
+{
+    POBJECT_HEADER ObjectHeader;
+    NTSTATUS Status;
+    PSECURITY_DESCRIPTOR ObjectSd;
+    PAGED_CODE();
+    
+    /* Get the object header */
+    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+    
+    /* Get the SD */
+    ObjectSd = ObpReferenceCachedSecurityDescriptor(ObjectHeader->SecurityDescriptor);
+    
+    /* Query the information */
+    Status = SeQuerySecurityDescriptorInfo(SecurityInformation,
+                                           SecurityDescriptor,
+                                           Length,
+                                           &ObjectSd);
+
+    /* Check if we have an object SD and dereference it, if so */
+    if (ObjectSd) ObpDereferenceCachedSecurityDescriptor(ObjectSd);
+    
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+ObSetSecurityDescriptorInfo(IN PVOID Object,
+                            IN PSECURITY_INFORMATION SecurityInformation,
+                            IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+                            IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
+                            IN POOL_TYPE PoolType,
+                            IN PGENERIC_MAPPING GenericMapping)
+{
+    NTSTATUS Status;
+    POBJECT_HEADER ObjectHeader;
+    PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
+    PAGED_CODE();
+    
+    /* Get the object header */
+    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+    while (TRUE)
+    {
+        /* Reference the old descriptor */
+        OldDescriptor = ObpReferenceCachedSecurityDescriptor(ObjectHeader->SecurityDescriptor);
+        NewDescriptor = OldDescriptor;
+        
+        /* Set the SD information */
+        Status = SeSetSecurityDescriptorInfo(Object,
+                                             SecurityInformation,
+                                             SecurityDescriptor,
+                                             &NewDescriptor,
+                                             PoolType,
+                                             GenericMapping);
+        if (NT_SUCCESS(Status))
+        {
+            /* Now add this to the cache */
+            Status = ObpAddSecurityDescriptor(NewDescriptor, &CachedDescriptor);
+            
+            /* Let go of our uncached copy */
+            ExFreePool(NewDescriptor);
+            
+            /* Check for success */
+            if (NT_SUCCESS(Status))
+            {
+                /* Dereference the old one */
+                ASSERT(OldDescriptor == ObjectHeader->SecurityDescriptor);
+                
+                /* Now set this as the new descriptor */
+                ObjectHeader->SecurityDescriptor = CachedDescriptor;
+                
+                /* And dereference the old one */
+                ObpDereferenceCachedSecurityDescriptor(OldDescriptor);
+                break;
+            }
+            else
+            {
+                /* We failed, dereference the old one */
+                ObpDereferenceCachedSecurityDescriptor(OldDescriptor);
+                break;
+            }
+        }
+        else
+        {
+            /* We failed, dereference the old one */
+            if (OldDescriptor) ObpDereferenceCachedSecurityDescriptor(OldDescriptor);
+            break;
+        }
+    }
+    
+    /* Return status */
+    return Status;
+}
+
 BOOLEAN
 NTAPI
 ObCheckCreateObjectAccess(IN PVOID Object,
index 4389d68..31d2a6a 100644 (file)
@@ -882,18 +882,190 @@ SeReleaseSecurityDescriptor(
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS STDCALL
 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
-                           IN PSECURITY_INFORMATION SecurityInformation,
-                           IN PSECURITY_DESCRIPTOR SecurityDescriptor,
-                           IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
-                           IN POOL_TYPE PoolType,
-                           IN PGENERIC_MAPPING GenericMapping)
+                            IN PSECURITY_INFORMATION _SecurityInformation,
+                            IN PSECURITY_DESCRIPTOR _SecurityDescriptor,
+                            IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
+                            IN POOL_TYPE PoolType,
+                            IN PGENERIC_MAPPING GenericMapping)
 {
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    PISECURITY_DESCRIPTOR ObjectSd;
+    PISECURITY_DESCRIPTOR NewSd;
+    PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    PSID Owner = 0;
+    PSID Group = 0;
+    PACL Dacl = 0;
+    PACL Sacl = 0;
+    ULONG OwnerLength = 0;
+    ULONG GroupLength = 0;
+    ULONG DaclLength = 0;
+    ULONG SaclLength = 0;
+    ULONG Control = 0;
+    ULONG_PTR Current;
+    SECURITY_INFORMATION SecurityInformation;
+    
+    
+    ObjectSd = *ObjectsSecurityDescriptor;
+    SecurityInformation = *_SecurityInformation;
+    
+    /* Get owner and owner size */
+    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+    {
+        if (SecurityDescriptor->Owner != NULL)
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
+                               (ULONG_PTR)SecurityDescriptor);
+            else
+                Owner = (PSID)SecurityDescriptor->Owner;
+            OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+        }
+        Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
+    }
+    else
+    {
+        if (ObjectSd->Owner != NULL)
+        {
+            Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
+            OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+        }
+        Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
+    }
+    
+    /* Get group and group size */
+    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+    {
+        if (SecurityDescriptor->Group != NULL)
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
+                               (ULONG_PTR)SecurityDescriptor);
+            else
+                Group = (PSID)SecurityDescriptor->Group;
+            GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+        }
+        Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
+    }
+    else
+    {
+        if (ObjectSd->Group != NULL)
+        {
+            Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
+            GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+        }
+        Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
+    }
+    
+    /* Get DACL and DACL size */
+    if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    {
+        if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
+            (SecurityDescriptor->Dacl != NULL))
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
+                              (ULONG_PTR)SecurityDescriptor);
+            else
+                Dacl = (PACL)SecurityDescriptor->Dacl;
+            
+            DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
+        }
+        Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
+    }
+    else
+    {
+        if ((ObjectSd->Control & SE_DACL_PRESENT) &&
+            (ObjectSd->Dacl != NULL))
+        {
+            Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
+            DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
+        }
+        Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
+    }
+    
+    /* Get SACL and SACL size */
+    if (SecurityInformation & SACL_SECURITY_INFORMATION)
+    {
+        if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
+            (SecurityDescriptor->Sacl != NULL))
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
+                              (ULONG_PTR)SecurityDescriptor);
+            else
+                Sacl = (PACL)SecurityDescriptor->Sacl;
+            SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
+        }
+        Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+    }
+    else
+    {
+        if ((ObjectSd->Control & SE_SACL_PRESENT) &&
+            (ObjectSd->Sacl != NULL))
+        {
+            Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
+            SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
+        }
+        Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+    }
+    
+    NewSd = ExAllocatePool(NonPagedPool,
+                           sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
+                           DaclLength + SaclLength);
+    if (NewSd == NULL)
+    {
+        ObDereferenceObject(Object);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    
+    RtlCreateSecurityDescriptor(NewSd,
+                                SECURITY_DESCRIPTOR_REVISION1);
+    /* We always build a self-relative descriptor */
+    NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE;
+    
+    Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
+    
+    if (OwnerLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Owner,
+                      OwnerLength);
+        NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
+        Current += OwnerLength;
+    }
+    
+    if (GroupLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Group,
+                      GroupLength);
+        NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
+        Current += GroupLength;
+    }
+    
+    if (DaclLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Dacl,
+                      DaclLength);
+        NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        Current += DaclLength;
+    }
+    
+    if (SaclLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Sacl,
+                      SaclLength);
+        NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        Current += SaclLength;
+    }    
+    
+    *ObjectsSecurityDescriptor = NewSd;
+    return STATUS_SUCCESS;
 }
 
 /*
index 68e1a7e..137851d 100644 (file)
@@ -233,222 +233,63 @@ VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
 }
 
 NTSTATUS
-STDCALL
-SeDefaultObjectMethod(PVOID Object,
-                      SECURITY_OPERATION_CODE OperationType,
-                      PSECURITY_INFORMATION _SecurityInformation,
-                      PSECURITY_DESCRIPTOR _SecurityDescriptor,
-                      PULONG ReturnLength,
-                      PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
-                      POOL_TYPE PoolType,
-                      PGENERIC_MAPPING GenericMapping)
+NTAPI
+SeDefaultObjectMethod(IN PVOID Object,
+                      IN SECURITY_OPERATION_CODE OperationType,
+                      IN PSECURITY_INFORMATION SecurityInformation,
+                      IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+                      IN OUT PULONG ReturnLength OPTIONAL,
+                      IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                      IN POOL_TYPE PoolType,
+                      IN PGENERIC_MAPPING GenericMapping)
 {
-  PISECURITY_DESCRIPTOR ObjectSd;
-  PISECURITY_DESCRIPTOR NewSd;
-  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
-  POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Object);
-  PSID Owner = 0;
-  PSID Group = 0;
-  PACL Dacl = 0;
-  PACL Sacl = 0;
-  ULONG OwnerLength = 0;
-  ULONG GroupLength = 0;
-  ULONG DaclLength = 0;
-  ULONG SaclLength = 0;
-  ULONG Control = 0;
-  ULONG_PTR Current;
-  NTSTATUS Status;
-  SECURITY_INFORMATION SecurityInformation;
-
-    if (OperationType == SetSecurityDescriptor)
-    {
-        ObjectSd = Header->SecurityDescriptor;
-        SecurityInformation = *_SecurityInformation;
-
-      /* Get owner and owner size */
-      if (SecurityInformation & OWNER_SECURITY_INFORMATION)
-        {
-          if (SecurityDescriptor->Owner != NULL)
-            {
-                if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
-                    Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
-                                   (ULONG_PTR)SecurityDescriptor);
-                else
-                    Owner = (PSID)SecurityDescriptor->Owner;
-                OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
-            }
-          Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
-        }
-      else
-        {
-          if (ObjectSd->Owner != NULL)
-          {
-              Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
-              OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
-          }
-          Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
-        }
-
-      /* Get group and group size */
-      if (SecurityInformation & GROUP_SECURITY_INFORMATION)
-        {
-          if (SecurityDescriptor->Group != NULL)
-            {
-                if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
-                    Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
-                                   (ULONG_PTR)SecurityDescriptor);
-                else
-                    Group = (PSID)SecurityDescriptor->Group;
-                GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-            }
-          Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
-        }
-      else
-        {
-          if (ObjectSd->Group != NULL)
-            {
-              Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
-              GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-            }
-          Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
-        }
-
-      /* Get DACL and DACL size */
-      if (SecurityInformation & DACL_SECURITY_INFORMATION)
-        {
-          if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
-              (SecurityDescriptor->Dacl != NULL))
-            {
-                if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
-                    Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
-                                  (ULONG_PTR)SecurityDescriptor);
-                else
-                    Dacl = (PACL)SecurityDescriptor->Dacl;
+    PAGED_CODE();
 
-              DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
-            }
-          Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
-        }
-      else
-        {
-          if ((ObjectSd->Control & SE_DACL_PRESENT) &&
-              (ObjectSd->Dacl != NULL))
-            {
-              Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
-              DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
-            }
-          Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
-        }
+    /* Select the operation type */
+    switch (OperationType)
+     {
+        /* Setting a new descriptor */
+        case SetSecurityDescriptor:
 
-      /* Get SACL and SACL size */
-      if (SecurityInformation & SACL_SECURITY_INFORMATION)
-        {
-          if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
-              (SecurityDescriptor->Sacl != NULL))
-            {
-                if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
-                    Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
-                                  (ULONG_PTR)SecurityDescriptor);
-                else
-                    Sacl = (PACL)SecurityDescriptor->Sacl;
-                SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
-            }
-          Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
-        }
-      else
-        {
-          if ((ObjectSd->Control & SE_SACL_PRESENT) &&
-              (ObjectSd->Sacl != NULL))
-            {
-              Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
-              SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
-            }
-          Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
-        }
+            /* Sanity check */
+            ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
 
-      NewSd = ExAllocatePool(NonPagedPool,
-                             sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
-                             DaclLength + SaclLength);
-      if (NewSd == NULL)
-        {
-          ObDereferenceObject(Object);
-          return STATUS_INSUFFICIENT_RESOURCES;
-        }
+            /* Set the information */
+            return ObSetSecurityDescriptorInfo(Object,
+                                               SecurityInformation,
+                                               SecurityDescriptor,
+                                               OldSecurityDescriptor,
+                                               PoolType,
+                                               GenericMapping);
 
-      RtlCreateSecurityDescriptor(NewSd,
-                                  SECURITY_DESCRIPTOR_REVISION1);
-      /* We always build a self-relative descriptor */
-      NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE;
+        case QuerySecurityDescriptor:
 
-      Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
+            /* Query the information */
+            return ObQuerySecurityDescriptorInfo(Object,
+                                                 SecurityInformation,
+                                                 SecurityDescriptor,
+                                                 ReturnLength,
+                                                 OldSecurityDescriptor);
 
-      if (OwnerLength != 0)
-        {
-          RtlCopyMemory((PVOID)Current,
-                        Owner,
-                        OwnerLength);
-          NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
-          Current += OwnerLength;
-        }
+        case DeleteSecurityDescriptor:
 
-      if (GroupLength != 0)
-        {
-          RtlCopyMemory((PVOID)Current,
-                        Group,
-                        GroupLength);
-          NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
-          Current += GroupLength;
-        }
+            /* De-assign it */
+            return ObDeassignSecurity(OldSecurityDescriptor);
 
-      if (DaclLength != 0)
-        {
-          RtlCopyMemory((PVOID)Current,
-                        Dacl,
-                        DaclLength);
-          NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
-          Current += DaclLength;
-        }
+        case AssignSecurityDescriptor:
 
-      if (SaclLength != 0)
-        {
-          RtlCopyMemory((PVOID)Current,
-                        Sacl,
-                        SaclLength);
-          NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
-          Current += SaclLength;
-        }
+            /* Assign it */
+            ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
+            return STATUS_SUCCESS;
 
-      /* Add the new SD */
-      Status = ObpAddSecurityDescriptor(NewSd,
-                                        &Header->SecurityDescriptor);
-      if (NT_SUCCESS(Status))
-        {
-          /* Remove the old security descriptor */
-          ObpRemoveSecurityDescriptor(ObjectSd);
-        }
-      else
-        {
-          /* Restore the old security descriptor */
-          Header->SecurityDescriptor = ObjectSd;
-        }
+        default:
 
-      ExFreePool(NewSd);
-    }
-    else if (OperationType == QuerySecurityDescriptor)
-    {
-        Status = SeQuerySecurityDescriptorInfo(_SecurityInformation,
-                                               SecurityDescriptor,
-                                               ReturnLength,
-                                               &Header->SecurityDescriptor);
-    }
-    else if (OperationType == AssignSecurityDescriptor)
-    {
-      /* Assign the security descriptor to the object header */
-      Status = ObpAddSecurityDescriptor(SecurityDescriptor,
-                                        &Header->SecurityDescriptor);
+            /* Bug check */
+            KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
     }
 
-
+    /* Should never reach here */
+    ASSERT(FALSE);
     return STATUS_SUCCESS;
 }