[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / se / semgr.c
index a7147c5..5e22e67 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/se/semgr.c
  * PROGRAMMERS:     No programmer listed.
  */
 
-/* INCLUDES *****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
 
-/* GLOBALS ******************************************************************/
+/* GLOBALS ********************************************************************/
 
 PSE_EXPORTS SeExports = NULL;
 SE_EXPORTS SepExports;
 
-static ERESOURCE SepSubjectContextLock;
-
-
-/* PROTOTYPES ***************************************************************/
+extern ULONG ExpInitializationPhase;
+extern ERESOURCE SepSubjectContextLock;
 
-static BOOLEAN SepInitExports(VOID);
+/* PRIVATE FUNCTIONS **********************************************************/
 
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, SeInit)
-#pragma alloc_text(INIT, SepInitExports)
-#endif
+static BOOLEAN INIT_FUNCTION
+SepInitExports(VOID)
+{
+    SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
+    SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
+    SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
+    SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
+    SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
+    SepExports.SeTcbPrivilege = SeTcbPrivilege;
+    SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
+    SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
+    SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
+    SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
+    SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
+    SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
+    SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
+    SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
+    SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
+    SepExports.SeBackupPrivilege = SeBackupPrivilege;
+    SepExports.SeRestorePrivilege = SeRestorePrivilege;
+    SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
+    SepExports.SeDebugPrivilege = SeDebugPrivilege;
+    SepExports.SeAuditPrivilege = SeAuditPrivilege;
+    SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
+    SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
+    SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
+
+    SepExports.SeNullSid = SeNullSid;
+    SepExports.SeWorldSid = SeWorldSid;
+    SepExports.SeLocalSid = SeLocalSid;
+    SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
+    SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
+    SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
+    SepExports.SeDialupSid = SeDialupSid;
+    SepExports.SeNetworkSid = SeNetworkSid;
+    SepExports.SeBatchSid = SeBatchSid;
+    SepExports.SeInteractiveSid = SeInteractiveSid;
+    SepExports.SeLocalSystemSid = SeLocalSystemSid;
+    SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
+    SepExports.SeAliasUsersSid = SeAliasUsersSid;
+    SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
+    SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
+    SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
+    SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
+    SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
+    SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
+    SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
+    SepExports.SeRestrictedSid = SeRestrictedSid;
+    SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
+
+    SepExports.SeUndockPrivilege = SeUndockPrivilege;
+    SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
+    SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
+
+    SeExports = &SepExports;
+    return TRUE;
+}
 
-/* FUNCTIONS ****************************************************************/
 
-BOOLEAN 
-INIT_FUNCTION
+BOOLEAN
 NTAPI
-SeInit(VOID)
+SepInitializationPhase0(VOID)
 {
-    DPRINT1("FIXME: SeAccessCheck has been HACKED to always grant access!\n");
-    DPRINT1("FIXME: Please fix all the code that doesn't get proper rights!\n");
-
-  SepInitLuid();
-
-  if (!SepInitSecurityIDs())
-    return FALSE;
-
-  if (!SepInitDACLs())
-    return FALSE;
-
-  if (!SepInitSDs())
-    return FALSE;
-
-  SepInitPrivileges();
-
-  if (!SepInitExports())
-    return FALSE;
-
-  /* Initialize the subject context lock */
-  ExInitializeResource(&SepSubjectContextLock);
+    PAGED_CODE();
 
-  /* Initialize token objects */
-  SepInitializeTokenImplementation();
+    ExpInitLuid();
+    if (!SepInitSecurityIDs()) return FALSE;
+    if (!SepInitDACLs()) return FALSE;
+    if (!SepInitSDs()) return FALSE;
+    SepInitPrivileges();
+    if (!SepInitExports()) return FALSE;
+
+    /* Initialize the subject context lock */
+    ExInitializeResource(&SepSubjectContextLock);
+
+    /* Initialize token objects */
+    SepInitializeTokenImplementation();
+
+    /* Clear impersonation info for the idle thread */
+    PsGetCurrentThread()->ImpersonationInfo = NULL;
+    PspClearCrossThreadFlag(PsGetCurrentThread(),
+                            CT_ACTIVE_IMPERSONATION_INFO_BIT);
+
+    /* Initialize the boot token */
+    ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
+    ObInitializeFastReference(&PsGetCurrentProcess()->Token,
+                              SepCreateSystemProcessToken());
+    return TRUE;
+}
 
-  /* Clear impersonation info for the idle thread */
-  PsGetCurrentThread()->ImpersonationInfo = NULL;
-  PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT);
+BOOLEAN
+NTAPI
+SepInitializationPhase1(VOID)
+{
+    NTSTATUS Status;
+    PAGED_CODE();
 
-  /* Initailize the boot token */
-  ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
-  ObInitializeFastReference(&PsGetCurrentProcess()->Token,
-      SepCreateSystemProcessToken());
-  return TRUE;
+    /* Insert the system token into the tree */
+    Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
+                                    ~MAX_FAST_REFS),
+                            NULL,
+                            0,
+                            0,
+                            NULL,
+                            NULL);
+    ASSERT(NT_SUCCESS(Status));
+
+    /* FIXME: TODO \\ Security directory */
+    return TRUE;
 }
 
 BOOLEAN
 NTAPI
-SeInitSRM(VOID)
+SeInitSystem(VOID)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING Name;
-  HANDLE DirectoryHandle;
-  HANDLE EventHandle;
-  NTSTATUS Status;
-
-  /* Create '\Security' directory */
-  RtlInitUnicodeString(&Name,
-                      L"\\Security");
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_PERMANENT,
-                            0,
-                            NULL);
-  Status = ZwCreateDirectoryObject(&DirectoryHandle,
-                                  DIRECTORY_ALL_ACCESS,
-                                  &ObjectAttributes);
-  if (!NT_SUCCESS(Status))
+    /* Check the initialization phase */
+    switch (ExpInitializationPhase)
     {
-      DPRINT1("Failed to create 'Security' directory!\n");
-      return FALSE;
-    }
-
-  /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
-  RtlInitUnicodeString(&Name,
-                      L"\\LSA_AUTHENTICATION_INITALIZED");
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &Name,
-                            OBJ_PERMANENT,
-                            DirectoryHandle,
-                            SePublicDefaultSd);
-  Status = ZwCreateEvent(&EventHandle,
-                        EVENT_ALL_ACCESS,
-                        &ObjectAttributes,
-                        SynchronizationEvent,
-                        FALSE);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
-      NtClose(DirectoryHandle);
-      return FALSE;
-    }
+        case 0:
 
-  ZwClose(EventHandle);
-  ZwClose(DirectoryHandle);
+            /* Do Phase 0 */
+            return SepInitializationPhase0();
 
-  /* FIXME: Create SRM port and listener thread */
+        case 1:
 
-  return TRUE;
-}
-
-
-static BOOLEAN INIT_FUNCTION
-SepInitExports(VOID)
-{
-  SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
-  SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
-  SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
-  SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
-  SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
-  SepExports.SeTcbPrivilege = SeTcbPrivilege;
-  SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
-  SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
-  SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
-  SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
-  SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
-  SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
-  SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
-  SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
-  SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
-  SepExports.SeBackupPrivilege = SeBackupPrivilege;
-  SepExports.SeRestorePrivilege = SeRestorePrivilege;
-  SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
-  SepExports.SeDebugPrivilege = SeDebugPrivilege;
-  SepExports.SeAuditPrivilege = SeAuditPrivilege;
-  SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
-  SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
-  SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
-
-  SepExports.SeNullSid = SeNullSid;
-  SepExports.SeWorldSid = SeWorldSid;
-  SepExports.SeLocalSid = SeLocalSid;
-  SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
-  SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
-  SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
-  SepExports.SeDialupSid = SeDialupSid;
-  SepExports.SeNetworkSid = SeNetworkSid;
-  SepExports.SeBatchSid = SeBatchSid;
-  SepExports.SeInteractiveSid = SeInteractiveSid;
-  SepExports.SeLocalSystemSid = SeLocalSystemSid;
-  SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
-  SepExports.SeAliasUsersSid = SeAliasUsersSid;
-  SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
-  SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
-  SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
-  SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
-  SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
-  SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
-  SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
-  SepExports.SeRestrictedSid = SeRestrictedSid;
-  SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
-
-  SepExports.SeUndockPrivilege = SeUndockPrivilege;
-  SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
-  SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
-  
-  SeExports = &SepExports;
-  return TRUE;
-}
+            /* Do Phase 1 */
+            return SepInitializationPhase1();
 
+        default:
 
-VOID SepReferenceLogonSession(PLUID AuthenticationId)
-{
-   UNIMPLEMENTED;
+            /* Don't know any other phase! Bugcheck! */
+            KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
+                         0,
+                         ExpInitializationPhase,
+                         0,
+                         0);
+            return FALSE;
+    }
 }
 
-VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
+BOOLEAN
+NTAPI
+SeInitSRM(VOID)
 {
-   UNIMPLEMENTED;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING Name;
+    HANDLE DirectoryHandle;
+    HANDLE EventHandle;
+    NTSTATUS Status;
+
+    /* Create '\Security' directory */
+    RtlInitUnicodeString(&Name,
+                         L"\\Security");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_PERMANENT,
+                               0,
+                               NULL);
+    Status = ZwCreateDirectoryObject(&DirectoryHandle,
+                                     DIRECTORY_ALL_ACCESS,
+                                     &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create 'Security' directory!\n");
+        return FALSE;
+    }
+
+    /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
+    RtlInitUnicodeString(&Name,
+                         L"\\LSA_AUTHENTICATION_INITALIZED");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_PERMANENT,
+                               DirectoryHandle,
+                               SePublicDefaultSd);
+    Status = ZwCreateEvent(&EventHandle,
+                           EVENT_ALL_ACCESS,
+                           &ObjectAttributes,
+                           SynchronizationEvent,
+                           FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
+        NtClose(DirectoryHandle);
+        return FALSE;
+    }
+
+    ZwClose(EventHandle);
+    ZwClose(DirectoryHandle);
+
+    /* FIXME: Create SRM port and listener thread */
+
+    return TRUE;
 }
 
 NTSTATUS
-STDCALL
-SeDefaultObjectMethod(PVOID Object,
-                      SECURITY_OPERATION_CODE OperationType,
-                      SECURITY_INFORMATION SecurityInformation,
-                      PSECURITY_DESCRIPTOR _SecurityDescriptor,
-                      PULONG ReturnLength,
-                      PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
-                      POOL_TYPE PoolType,
-                      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;
-
-    if (OperationType == SetSecurityDescriptor)
-    {
-        ObjectSd = Header->SecurityDescriptor;
-
-      /* 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;
-       }
-
-      /* 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;
-       }
-
-      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);
-    }
-
-
-    return STATUS_SUCCESS;
-}
-
-VOID
 NTAPI
-SeCaptureSubjectContextEx(IN PETHREAD Thread,
-                          IN PEPROCESS Process,
-                          OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
+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)
 {
-    BOOLEAN CopyOnOpen, EffectiveOnly;
     PAGED_CODE();
 
-    /* Save the unique ID */
-    SubjectContext->ProcessAuditId = Process->UniqueProcessId;
-
-    /* Check if we have a thread */
-    if (!Thread)
+    /* Select the operation type */
+    switch (OperationType)
     {
-        /* We don't, so no token */
-        SubjectContext->ClientToken = NULL;
-    }
-    else
-    {
-        /* Get the impersonation token */
-        SubjectContext->ClientToken =
-            PsReferenceImpersonationToken(Thread,
-                                          &CopyOnOpen,
-                                          &EffectiveOnly,
-                                          &SubjectContext->ImpersonationLevel);
-    }
-
-    /* Get the primary token */
-    SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
-}
+            /* Setting a new descriptor */
+        case SetSecurityDescriptor:
 
-/*
- * @implemented
- */
-VOID
-NTAPI
-SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
-{
-    /* Call the internal API */
-    SeCaptureSubjectContextEx(PsGetCurrentThread(),
-                              PsGetCurrentProcess(),
-                              SubjectContext);
-}
+            /* Sanity check */
+            ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
 
+            /* Set the information */
+            return ObSetSecurityDescriptorInfo(Object,
+                                               SecurityInformation,
+                                               SecurityDescriptor,
+                                               OldSecurityDescriptor,
+                                               PoolType,
+                                               GenericMapping);
 
-/*
- * @implemented
- */
-VOID STDCALL
-SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
-{
-  PAGED_CODE();
+        case QuerySecurityDescriptor:
 
-  KeEnterCriticalRegion();
-  ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
-}
+            /* Query the information */
+            return ObQuerySecurityDescriptorInfo(Object,
+                                                 SecurityInformation,
+                                                 SecurityDescriptor,
+                                                 ReturnLength,
+                                                 OldSecurityDescriptor);
 
+        case DeleteSecurityDescriptor:
 
-/*
- * @implemented
- */
-VOID STDCALL
-SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
-{
-  PAGED_CODE();
+            /* De-assign it */
+            return ObDeassignSecurity(OldSecurityDescriptor);
 
-  ExReleaseResourceLite(&SepSubjectContextLock);
-  KeLeaveCriticalRegion();
-}
+        case AssignSecurityDescriptor:
 
+            /* Assign it */
+            ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
+            return STATUS_SUCCESS;
 
-/*
- * @implemented
- */
-VOID STDCALL
-SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
-{
-  PAGED_CODE();
+        default:
 
-  if (SubjectContext->PrimaryToken != NULL)
-    {
-      ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken);
+            /* Bug check */
+            KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
     }
 
-  if (SubjectContext->ClientToken != NULL)
-    {
-      ObDereferenceObject(SubjectContext->ClientToken);
-    }
+    /* Should never reach here */
+    ASSERT(FALSE);
+    return STATUS_SUCCESS;
 }
 
+ULONG SidInTokenCalls = 0;
 
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
+static BOOLEAN
+SepSidInToken(PACCESS_TOKEN _Token,
+              PSID Sid)
 {
-  PAGED_CODE();
+    ULONG i;
+    PTOKEN Token = (PTOKEN)_Token;
 
-  if (*SecurityDescriptor != NULL)
+    PAGED_CODE();
+
+    SidInTokenCalls++;
+    if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls);
+    
+    if (Token->UserAndGroupCount == 0)
     {
-      ExFreePool(*SecurityDescriptor);
-      *SecurityDescriptor = NULL;
+        return FALSE;
     }
 
-  return STATUS_SUCCESS;
-}
+    for (i=0; i<Token->UserAndGroupCount; i++)
+    {
+        if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
+        {
+            if ((i == 0)|| (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED))
+            {
+                return TRUE;
+            }
 
+            return FALSE;
+        }
+    }
 
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
-                  IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
-                  OUT PSECURITY_DESCRIPTOR *NewDescriptor,
-                  IN GUID *ObjectType OPTIONAL,
-                  IN BOOLEAN IsDirectoryObject,
-                  IN ULONG AutoInheritFlags,
-                  IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
-                  IN PGENERIC_MAPPING GenericMapping,
-                  IN POOL_TYPE PoolType)
-{
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    return FALSE;
 }
 
-
-/*
- * FUNCTION: Creates a security descriptor for a new object.
- * ARGUMENTS:
- *         ParentDescriptor =
- *         ExplicitDescriptor =
- *         NewDescriptor =
- *         IsDirectoryObject =
- *         SubjectContext =
- *         GeneralMapping =
- *         PoolType =
- * RETURNS: Status
- *
- * @implemented
- */
-NTSTATUS STDCALL
-SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
-                PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL,
-                PSECURITY_DESCRIPTOR *NewDescriptor,
-                BOOLEAN IsDirectoryObject,
-                PSECURITY_SUBJECT_CONTEXT SubjectContext,
-                PGENERIC_MAPPING GenericMapping,
-                POOL_TYPE PoolType)
+static BOOLEAN
+SepTokenIsOwner(PACCESS_TOKEN Token,
+                PSECURITY_DESCRIPTOR SecurityDescriptor)
 {
-  PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
-  PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
-  PISECURITY_DESCRIPTOR Descriptor;
-  PTOKEN Token;
-  ULONG OwnerLength = 0;
-  ULONG GroupLength = 0;
-  ULONG DaclLength = 0;
-  ULONG SaclLength = 0;
-  ULONG Length = 0;
-  ULONG Control = 0;
-  ULONG_PTR Current;
-  PSID Owner = NULL;
-  PSID Group = NULL;
-  PACL Dacl = NULL;
-  PACL Sacl = NULL;
-
-  PAGED_CODE();
-
-  /* Lock subject context */
-  SeLockSubjectContext(SubjectContext);
-
-  if (SubjectContext->ClientToken != NULL)
-    {
-      Token = SubjectContext->ClientToken;
-    }
-  else
-    {
-      Token = SubjectContext->PrimaryToken;
-    }
-
+    NTSTATUS Status;
+    PSID Sid = NULL;
+    BOOLEAN Defaulted;
 
-  /* Inherit the Owner SID */
-  if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
+    Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
+                                           &Sid,
+                                           &Defaulted);
+    if (!NT_SUCCESS(Status))
     {
-      DPRINT("Use explicit owner sid!\n");
-      Owner = ExplicitDescriptor->Owner;
-      
-      if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
-       {
-         Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
-
-       }
+        DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
+        return FALSE;
     }
-  else
+
+    if (Sid == NULL)
     {
-      if (Token != NULL)
-       {
-         DPRINT("Use token owner sid!\n");
-         Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
-       }
-      else
-       {
-         DPRINT("Use default owner sid!\n");
-         Owner = SeLocalSystemSid;
-       }
-
-      Control |= SE_OWNER_DEFAULTED;
+        DPRINT1("Owner Sid is NULL\n");
+        return FALSE;
     }
 
-  OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+    return SepSidInToken(Token, Sid);
+}
 
+VOID NTAPI
+SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
+                          OUT PACCESS_MASK DesiredAccess)
+{
+    *DesiredAccess = 0;
 
-  /* Inherit the Group SID */
-  if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
+    if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
+                               GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
     {
-      DPRINT("Use explicit group sid!\n");
-      Group = ExplicitDescriptor->Group;
-      if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
-       {
-         Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
-       }
+        *DesiredAccess |= READ_CONTROL;
     }
-  else
+    if (SecurityInformation & SACL_SECURITY_INFORMATION)
     {
-      if (Token != NULL)
-       {
-         DPRINT("Use token group sid!\n");
-         Group = Token->PrimaryGroup;
-       }
-      else
-       {
-         DPRINT("Use default group sid!\n");
-         Group = SeLocalSystemSid;
-       }
-
-      Control |= SE_OWNER_DEFAULTED;
+        *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
     }
+}
 
-  GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-
+VOID NTAPI
+SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
+                        OUT PACCESS_MASK DesiredAccess)
+{
+    *DesiredAccess = 0;
 
-  /* Inherit the DACL */
-  if (ExplicitDescriptor != NULL &&
-      (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
-      !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
+    if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
     {
-      DPRINT("Use explicit DACL!\n");
-      Dacl = ExplicitDescriptor->Dacl;
-      if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
-       {
-         Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
-       }
-
-      Control |= SE_DACL_PRESENT;
+        *DesiredAccess |= WRITE_OWNER;
     }
-  else if (ParentDescriptor != NULL &&
-          (ParentDescriptor->Control & SE_DACL_PRESENT))
+    if (SecurityInformation & DACL_SECURITY_INFORMATION)
     {
-      DPRINT("Use parent DACL!\n");
-      /* FIXME: Inherit */
-      Dacl = ParentDescriptor->Dacl;
-      if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
-       {
-         Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor);
-       }
-      Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+        *DesiredAccess |= WRITE_DAC;
     }
-  else if (Token != NULL && Token->DefaultDacl != NULL)
+    if (SecurityInformation & SACL_SECURITY_INFORMATION)
     {
-      DPRINT("Use token default DACL!\n");
-      /* FIXME: Inherit */
-      Dacl = Token->DefaultDacl;
-      Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+        *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
     }
-  else
-    {
-      DPRINT("Use NULL DACL!\n");
-      Dacl = NULL;
-      Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+}
+
+BOOLEAN NTAPI
+SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+               IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
+               IN ACCESS_MASK DesiredAccess,
+               IN ACCESS_MASK PreviouslyGrantedAccess,
+               OUT PPRIVILEGE_SET* Privileges,
+               IN PGENERIC_MAPPING GenericMapping,
+               IN KPROCESSOR_MODE AccessMode,
+               OUT PACCESS_MASK GrantedAccess,
+               OUT PNTSTATUS AccessStatus)
+{
+    LUID_AND_ATTRIBUTES Privilege;
+    ACCESS_MASK CurrentAccess, AccessMask;
+    PACCESS_TOKEN Token;
+    ULONG i;
+    PACL Dacl;
+    BOOLEAN Present;
+    BOOLEAN Defaulted;
+    PACE CurrentAce;
+    PSID Sid;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    /* Check for no access desired */
+    if (!DesiredAccess)
+    {
+        /* Check if we had no previous access */
+        if (!PreviouslyGrantedAccess)
+        {
+            /* Then there's nothing to give */
+            *AccessStatus = STATUS_ACCESS_DENIED;
+            return FALSE;
+        }
+
+        /* Return the previous access only */
+        *GrantedAccess = PreviouslyGrantedAccess;
+        *AccessStatus = STATUS_SUCCESS;
+        *Privileges = NULL;
+        return TRUE;
     }
 
-  DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
+    /* Map given accesses */
+    RtlMapGenericMask(&DesiredAccess, GenericMapping);
+    if (PreviouslyGrantedAccess)
+        RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping);
 
 
-  /* Inherit the SACL */
-  if (ExplicitDescriptor != NULL &&
-      (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
-      !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
-    {
-      DPRINT("Use explicit SACL!\n");
-      Sacl = ExplicitDescriptor->Sacl;
-      if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
-       {
-         Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
-       }
-
-      Control |= SE_SACL_PRESENT;
-    }
-  else if (ParentDescriptor != NULL &&
-          (ParentDescriptor->Control & SE_SACL_PRESENT))
-    {
-      DPRINT("Use parent SACL!\n");
-      /* FIXME: Inherit */
-      Sacl = ParentDescriptor->Sacl;
-      if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
-       {
-         Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor);
-       }
-      Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
-    }
 
-  SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
+    CurrentAccess = PreviouslyGrantedAccess;
 
 
-  /* Allocate and initialize the new security descriptor */
-  Length = sizeof(SECURITY_DESCRIPTOR) +
-      OwnerLength + GroupLength + DaclLength + SaclLength;
 
-  DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
-        sizeof(SECURITY_DESCRIPTOR),
-        OwnerLength,
-        GroupLength,
-        DaclLength,
-        SaclLength);
+    Token = SubjectSecurityContext->ClientToken ?
+    SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
 
-  Descriptor = ExAllocatePool(PagedPool,
-                             Length);
-  if (Descriptor == NULL)
+    /* Get the DACL */
+    Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
+                                          &Present,
+                                          &Dacl,
+                                          &Defaulted);
+    if (!NT_SUCCESS(Status))
     {
-      DPRINT1("ExAlloctePool() failed\n");
-      /* FIXME: Unlock subject context */
-      return STATUS_INSUFFICIENT_RESOURCES;
+        *AccessStatus = Status;
+        return FALSE;
     }
 
-  RtlZeroMemory( Descriptor, Length );
-  RtlCreateSecurityDescriptor(Descriptor,
-                             SECURITY_DESCRIPTOR_REVISION);
-
-  Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE;
+    /* RULE 1: Grant desired access if the object is unprotected */
+    if (Present == FALSE || Dacl == NULL)
+    {
+        if (DesiredAccess & MAXIMUM_ALLOWED)
+        {
+            *GrantedAccess = GenericMapping->GenericAll;
+            *GrantedAccess |= (DesiredAccess & ~MAXIMUM_ALLOWED);
+        }
+        else
+        {
+            *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
+        }
+        
+        *AccessStatus = STATUS_SUCCESS;
+        return TRUE;
+    }
 
-  Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
+    CurrentAccess = PreviouslyGrantedAccess;
 
-  if (SaclLength != 0)
+    /* RULE 2: Check token for 'take ownership' privilege */
+    if (DesiredAccess & WRITE_OWNER)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Sacl,
-                   SaclLength);
-      Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
-      Current += SaclLength;
+        Privilege.Luid = SeTakeOwnershipPrivilege;
+        Privilege.Attributes = SE_PRIVILEGE_ENABLED;
+
+        if (SepPrivilegeCheck(Token,
+                              &Privilege,
+                              1,
+                              PRIVILEGE_SET_ALL_NECESSARY,
+                              AccessMode))
+        {
+            CurrentAccess |= WRITE_OWNER;
+            if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == 
+                (CurrentAccess & ~VALID_INHERIT_FLAGS))
+            {
+                *GrantedAccess = CurrentAccess;
+                *AccessStatus = STATUS_SUCCESS;
+                return TRUE;
+            }
+        }
     }
 
-  if (DaclLength != 0)
+    /* Deny access if the DACL is empty */
+    if (Dacl->AceCount == 0)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Dacl,
-                   DaclLength);
-      Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
-      Current += DaclLength;
+        *GrantedAccess = 0;
+        *AccessStatus = STATUS_ACCESS_DENIED;
+        return FALSE;
     }
 
-  if (OwnerLength != 0)
+    /* Fail if DACL is absent */
+    if (Present == FALSE)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Owner,
-                   OwnerLength);
-      Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
-      Current += OwnerLength;
-      DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
+        *GrantedAccess = 0;
+        *AccessStatus = STATUS_ACCESS_DENIED;
+        return FALSE;
     }
-  else
-      DPRINT("Owner of %x is zero length\n", Descriptor);
 
-  if (GroupLength != 0)
+    /* RULE 4: Grant rights according to the DACL */
+    CurrentAce = (PACE)(Dacl + 1);
+    for (i = 0; i < Dacl->AceCount; i++)
     {
-      memmove((PVOID)Current,
-              Group,
-              GroupLength);
-      Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
-    }
+        Sid = (PSID)(CurrentAce + 1);
+        if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
+        {
+            if (SepSidInToken(Token, Sid))
+            {
+                *GrantedAccess = 0;
+                *AccessStatus = STATUS_ACCESS_DENIED;
+                return FALSE;
+            }
+        }
 
-  /* Unlock subject context */
-  SeUnlockSubjectContext(SubjectContext);
+        else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+        {
+            if (SepSidInToken(Token, Sid))
+            {
+                AccessMask = CurrentAce->AccessMask;
+                RtlMapGenericMask(&AccessMask, GenericMapping);
+                CurrentAccess |= AccessMask;
+            }
+        }
+        else
+        {
+            DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType);
+        }
+        CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
+    }
 
-  *NewDescriptor = Descriptor;
+    DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
+           CurrentAccess, DesiredAccess);
 
-  DPRINT("Descrptor %x\n", Descriptor);
-  ASSERT(RtlLengthSecurityDescriptor(Descriptor));
+    *GrantedAccess = CurrentAccess & DesiredAccess;
 
-  return STATUS_SUCCESS;
+    if (DesiredAccess & MAXIMUM_ALLOWED)
+    {
+        *GrantedAccess = CurrentAccess;
+        *AccessStatus = STATUS_SUCCESS;
+        return TRUE;
+    }
+    else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == 
+             (DesiredAccess & ~VALID_INHERIT_FLAGS))
+    {
+        *AccessStatus = STATUS_SUCCESS;
+        return TRUE;
+    }
+    else
+    {
+        DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n",
+                *GrantedAccess, DesiredAccess, GenericMapping);
+        //*AccessStatus = STATUS_ACCESS_DENIED;
+        //return FALSE;
+        *AccessStatus = STATUS_SUCCESS;
+        return TRUE;
+    }
 }
 
-
-static BOOLEAN
-SepSidInToken(PACCESS_TOKEN _Token,
-             PSID Sid)
+static PSID
+SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
 {
-  ULONG i;
-  PTOKEN Token = (PTOKEN)_Token;
+    PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    PSID Owner;
 
-  PAGED_CODE();
+    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+        Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
+                       (ULONG_PTR)SecurityDescriptor);
+    else
+        Owner = (PSID)SecurityDescriptor->Owner;
 
-  if (Token->UserAndGroupCount == 0)
-  {
-    return FALSE;
-  }
+    return Owner;
+}
 
-  for (i=0; i<Token->UserAndGroupCount; i++)
-  {
-    if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
-    {
-      if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
-      {
-        return TRUE;
-      }
+static PSID
+SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
+{
+    PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    PSID Group;
 
-      return FALSE;
-    }
-  }
+    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+        Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
+                       (ULONG_PTR)SecurityDescriptor);
+    else
+        Group = (PSID)SecurityDescriptor->Group;
 
-  return FALSE;
+    return Group;
 }
 
 
+/* PUBLIC FUNCTIONS ***********************************************************/
+
 /*
- * FUNCTION: Determines whether the requested access rights can be granted
- * to an object protected by a security descriptor and an object owner
- * ARGUMENTS:
- *      SecurityDescriptor = Security descriptor protecting the object
- *      SubjectSecurityContext = Subject's captured security context
- *      SubjectContextLocked = Indicates the user's subject context is locked
- *      DesiredAccess = Access rights the caller is trying to acquire
- *      PreviouslyGrantedAccess = Specified the access rights already granted
- *      Privileges = ?
- *      GenericMapping = Generic mapping associated with the object
- *      AccessMode = Access mode used for the check
- *      GrantedAccess (OUT) = On return specifies the access granted
- *      AccessStatus (OUT) = Status indicating why access was denied
- * RETURNS: If access was granted, returns TRUE
- *
  * @implemented
  */
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
-             IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
-             IN BOOLEAN SubjectContextLocked,
-             IN ACCESS_MASK DesiredAccess,
-             IN ACCESS_MASK PreviouslyGrantedAccess,
-             OUT PPRIVILEGE_SET* Privileges,
-             IN PGENERIC_MAPPING GenericMapping,
-             IN KPROCESSOR_MODE AccessMode,
-             OUT PACCESS_MASK GrantedAccess,
-             OUT PNTSTATUS AccessStatus)
+              IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
+              IN BOOLEAN SubjectContextLocked,
+              IN ACCESS_MASK DesiredAccess,
+              IN ACCESS_MASK PreviouslyGrantedAccess,
+              OUT PPRIVILEGE_SET* Privileges,
+              IN PGENERIC_MAPPING GenericMapping,
+              IN KPROCESSOR_MODE AccessMode,
+              OUT PACCESS_MASK GrantedAccess,
+              OUT PNTSTATUS AccessStatus)
 {
-  LUID_AND_ATTRIBUTES Privilege;
-  ACCESS_MASK CurrentAccess;
-  PACCESS_TOKEN Token;
-  ULONG i;
-  PACL Dacl;
-  BOOLEAN Present;
-  BOOLEAN Defaulted;
-  PACE CurrentAce;
-  PSID Sid;
-  NTSTATUS Status;
-
-  PAGED_CODE();
-
-  /* Check if we didn't get an SD */
-  if (!SecurityDescriptor)
-  {
-      /* Automatic failure */
-      *AccessStatus = STATUS_ACCESS_DENIED;
-      return FALSE;
-  }
-
-  CurrentAccess = PreviouslyGrantedAccess;
-
-  if (SubjectContextLocked == FALSE)
-    {
-      SeLockSubjectContext(SubjectSecurityContext);
-    }
+    BOOLEAN ret;
 
-  Token = SubjectSecurityContext->ClientToken ?
-           SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
-
-  /* Get the DACL */
-  Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
-                                       &Present,
-                                       &Dacl,
-                                       &Defaulted);
-  if (!NT_SUCCESS(Status))
-    {
-      if (SubjectContextLocked == FALSE)
-       {
-         SeUnlockSubjectContext(SubjectSecurityContext);
-       }
+    PAGED_CODE();
 
-      *AccessStatus = Status;
-      return FALSE;
+    /* Check if this is kernel mode */
+    if (AccessMode == KernelMode)
+    {
+        /* Check if kernel wants everything */
+        if (DesiredAccess & MAXIMUM_ALLOWED)
+        {
+            /* Give it */
+            *GrantedAccess = GenericMapping->GenericAll;
+            *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
+            *GrantedAccess |= PreviouslyGrantedAccess;
+        }
+        else
+        {
+            /* Give the desired and previous access */
+            *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
+        }
+
+        /* Success */
+        *AccessStatus = STATUS_SUCCESS;
+        return TRUE;
     }
 
-  /* RULE 1: Grant desired access if the object is unprotected */
-  if (Present == TRUE && Dacl == NULL)
+    /* Check if we didn't get an SD */
+    if (!SecurityDescriptor)
     {
-      if (SubjectContextLocked == FALSE)
-       {
-         SeUnlockSubjectContext(SubjectSecurityContext);
-       }
-
-      *GrantedAccess = DesiredAccess;
-      *AccessStatus = STATUS_SUCCESS;
-      return TRUE;
+        /* Automatic failure */
+        *AccessStatus = STATUS_ACCESS_DENIED;
+        return FALSE;
     }
 
-  CurrentAccess = PreviouslyGrantedAccess;
-
-  /* RULE 2: Check token for 'take ownership' privilege */
-  Privilege.Luid = SeTakeOwnershipPrivilege;
-  Privilege.Attributes = SE_PRIVILEGE_ENABLED;
-
-  if (SepPrivilegeCheck(Token,
-                       &Privilege,
-                       1,
-                       PRIVILEGE_SET_ALL_NECESSARY,
-                       AccessMode))
+    /* Check for invalid impersonation */
+    if ((SubjectSecurityContext->ClientToken) &&
+        (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation))
     {
-      CurrentAccess |= WRITE_OWNER;
-      if (DesiredAccess == CurrentAccess)
-       {
-         if (SubjectContextLocked == FALSE)
-           {
-             SeUnlockSubjectContext(SubjectSecurityContext);
-           }
-
-         *GrantedAccess = CurrentAccess;
-         *AccessStatus = STATUS_SUCCESS;
-         return TRUE;
-       }
+        *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL;
+        return FALSE;
     }
 
-  /* RULE 3: Check whether the token is the owner */
-  Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
-                                        &Sid,
-                                        &Defaulted);
-  if (!NT_SUCCESS(Status))
+    /* Acquire the lock if needed */
+    if (!SubjectContextLocked)
+        SeLockSubjectContext(SubjectSecurityContext);
+
+    /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
+    if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED))
     {
-      DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
-      if (SubjectContextLocked == FALSE)
-       {
-         SeUnlockSubjectContext(SubjectSecurityContext);
-       }
+         PACCESS_TOKEN Token = SubjectSecurityContext->ClientToken ?
+             SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
 
-      *AccessStatus = Status;
-      return FALSE;
-   }
+        if (SepTokenIsOwner(Token,
+                            SecurityDescriptor))
+        {
+            if (DesiredAccess & MAXIMUM_ALLOWED)
+                PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
+            else
+                PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
 
-  if (Sid && SepSidInToken(Token, Sid))
-    {
-      CurrentAccess |= (READ_CONTROL | WRITE_DAC);
-      if (DesiredAccess == CurrentAccess)
-       {
-         if (SubjectContextLocked == FALSE)
-           {
-             SeUnlockSubjectContext(SubjectSecurityContext);
-           }
-
-         *GrantedAccess = CurrentAccess;
-         *AccessStatus = STATUS_SUCCESS;
-         return TRUE;
-       }
+            DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
+        }
     }
 
-  /* Fail if DACL is absent */
-  if (Present == FALSE)
+    if (DesiredAccess == 0)
     {
-      if (SubjectContextLocked == FALSE)
-       {
-         SeUnlockSubjectContext(SubjectSecurityContext);
-       }
-
-      *GrantedAccess = 0;
-      *AccessStatus = STATUS_ACCESS_DENIED;
-      return FALSE;
+        *GrantedAccess = PreviouslyGrantedAccess;
+        *AccessStatus = STATUS_SUCCESS;
+        ret = TRUE;
     }
-
-  /* RULE 4: Grant rights according to the DACL */
-  CurrentAce = (PACE)(Dacl + 1);
-  for (i = 0; i < Dacl->AceCount; i++)
+    else
     {
-      Sid = (PSID)(CurrentAce + 1);
-      if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
-       {
-         if (SepSidInToken(Token, Sid))
-           {
-             if (SubjectContextLocked == FALSE)
-               {
-                 SeUnlockSubjectContext(SubjectSecurityContext);
-               }
-
-             *GrantedAccess = 0;
-             *AccessStatus = STATUS_ACCESS_DENIED;
-             return FALSE;
-           }
-       }
-
-      else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
-       {
-         if (SepSidInToken(Token, Sid))
-           {
-             CurrentAccess |= CurrentAce->AccessMask;
-           }
-       }
-       else
-         DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType);
-       CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
+        /* Call the internal function */
+        ret = SepAccessCheck(SecurityDescriptor,
+                             SubjectSecurityContext,
+                             DesiredAccess,
+                             PreviouslyGrantedAccess,
+                             Privileges,
+                             GenericMapping,
+                             AccessMode,
+                             GrantedAccess,
+                             AccessStatus);
     }
 
-  if (SubjectContextLocked == FALSE)
-    {
-      SeUnlockSubjectContext(SubjectSecurityContext);
-    }
+    /* Release the lock if needed */
+    if (!SubjectContextLocked)
+        SeUnlockSubjectContext(SubjectSecurityContext);
+
+    return ret;
+}
 
-  DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
-         CurrentAccess, DesiredAccess);
+/* SYSTEM CALLS ***************************************************************/
 
-  *GrantedAccess = CurrentAccess & DesiredAccess;
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+              IN HANDLE TokenHandle,
+              IN ACCESS_MASK DesiredAccess,
+              IN PGENERIC_MAPPING GenericMapping,
+              OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
+              IN OUT PULONG PrivilegeSetLength,
+              OUT PACCESS_MASK GrantedAccess,
+              OUT PNTSTATUS AccessStatus)
+{
+    PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL;
+    SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    ACCESS_MASK PreviouslyGrantedAccess = 0;
+    PTOKEN Token;
+    NTSTATUS Status;
+    PAGED_CODE();
 
-  if (*GrantedAccess == DesiredAccess)
+    /* Check if this is kernel mode */
+    if (PreviousMode == KernelMode)
     {
-      *AccessStatus = STATUS_SUCCESS;
-      return TRUE;
+        /* Check if kernel wants everything */
+        if (DesiredAccess & MAXIMUM_ALLOWED)
+        {
+            /* Give it */
+            *GrantedAccess = GenericMapping->GenericAll;
+            *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
+        }
+        else
+        {
+            /* Just give the desired access */
+            *GrantedAccess = DesiredAccess;
+        }
+
+        /* Success */
+        *AccessStatus = STATUS_SUCCESS;
+        return STATUS_SUCCESS;
     }
-  else
+
+    /* Protect probe in SEH */
+    _SEH2_TRY
     {
-      *AccessStatus = STATUS_ACCESS_DENIED;
-      DPRINT("FIX caller rights (granted 0x%lx, desired 0x%lx)!\n",
-        *GrantedAccess, DesiredAccess);
-      return TRUE; /* FIXME: should be FALSE */
+        /* Probe all pointers */
+        ProbeForRead(GenericMapping, sizeof(GENERIC_MAPPING), sizeof(ULONG));
+        ProbeForRead(PrivilegeSetLength, sizeof(ULONG), sizeof(ULONG));
+        ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG));
+        ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
+        ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
     }
-}
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END;
 
+    /* Check for unmapped access rights */
+    if (DesiredAccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL))
+        return STATUS_GENERIC_NOT_MAPPED;
 
-NTSTATUS STDCALL
-NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
-             IN HANDLE TokenHandle,
-             IN ACCESS_MASK DesiredAccess,
-             IN PGENERIC_MAPPING GenericMapping,
-             OUT PPRIVILEGE_SET PrivilegeSet,
-             OUT PULONG ReturnLength,
-             OUT PACCESS_MASK GrantedAccess,
-             OUT PNTSTATUS AccessStatus)
-{
-  SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = {0};
-  KPROCESSOR_MODE PreviousMode;
-  PTOKEN Token;
-  NTSTATUS Status;
+    /* Reference the token */
+    Status = ObReferenceObjectByHandle(TokenHandle,
+                                       TOKEN_QUERY,
+                                       SepTokenObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Token,
+                                       NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Failed to reference token (Status %lx)\n", Status);
+        return Status;
+    }
 
-  PAGED_CODE();
+    /* Check token type */
+    if (Token->TokenType != TokenImpersonation)
+    {
+        DPRINT("No impersonation token\n");
+        ObDereferenceObject(Token);
+        return STATUS_NO_IMPERSONATION_TOKEN;
+    }
 
-  DPRINT("NtAccessCheck() called\n");
+    /* Check the impersonation level */
+    if (Token->ImpersonationLevel < SecurityIdentification)
+    {
+        DPRINT("Impersonation level < SecurityIdentification\n");
+        ObDereferenceObject(Token);
+        return STATUS_BAD_IMPERSONATION_LEVEL;
+    }
 
-  PreviousMode = KeGetPreviousMode();
-  if (PreviousMode == KernelMode)
+    /* Capture the security descriptor */
+    Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
+                                         PreviousMode,
+                                         PagedPool,
+                                         FALSE,
+                                         &CapturedSecurityDescriptor);
+    if (!NT_SUCCESS(Status))
     {
-      *GrantedAccess = DesiredAccess;
-      *AccessStatus = STATUS_SUCCESS;
-      return STATUS_SUCCESS;
+        DPRINT("Failed to capture the Security Descriptor\n");
+        ObDereferenceObject(Token);
+        return Status;
     }
 
-  Status = ObReferenceObjectByHandle(TokenHandle,
-                                    TOKEN_QUERY,
-                                    SepTokenObjectType,
-                                    PreviousMode,
-                                    (PVOID*)&Token,
-                                    NULL);
-  if (!NT_SUCCESS(Status))
+    /* Check the captured security descriptor */
+    if (CapturedSecurityDescriptor == NULL)
     {
-      DPRINT1("Failed to reference token (Status %lx)\n", Status);
-      return Status;
+        DPRINT("Security Descriptor is NULL\n");
+        ObDereferenceObject(Token);
+        return STATUS_INVALID_SECURITY_DESCR;
     }
 
-  /* Check token type */
-  if (Token->TokenType != TokenImpersonation)
+    /* Check security descriptor for valid owner and group */
+    if (SepGetSDOwner(SecurityDescriptor) == NULL ||  // FIXME: use CapturedSecurityDescriptor
+        SepGetSDGroup(SecurityDescriptor) == NULL)    // FIXME: use CapturedSecurityDescriptor
     {
-      DPRINT1("No impersonation token\n");
-      ObDereferenceObject(Token);
-      return STATUS_ACCESS_VIOLATION;
+        DPRINT("Security Descriptor does not have a valid group or owner\n");
+        SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
+                                    PreviousMode,
+                                    FALSE);
+        ObDereferenceObject(Token);
+        return STATUS_INVALID_SECURITY_DESCR;
     }
 
-  /* Check impersonation level */
-  if (Token->ImpersonationLevel < SecurityAnonymous)
+    /* Set up the subject context, and lock it */
+    SubjectSecurityContext.ClientToken = Token;
+    SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
+    SubjectSecurityContext.PrimaryToken = NULL;
+    SubjectSecurityContext.ProcessAuditId = NULL;
+    SeLockSubjectContext(&SubjectSecurityContext);
+
+    /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
+    if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED))
     {
-      DPRINT1("Invalid impersonation level\n");
-      ObDereferenceObject(Token);
-      return STATUS_ACCESS_VIOLATION;
+        if (SepTokenIsOwner(Token, SecurityDescriptor)) // FIXME: use CapturedSecurityDescriptor
+        {
+            if (DesiredAccess & MAXIMUM_ALLOWED)
+                PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL);
+            else
+                PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL));
+
+            DesiredAccess &= ~(WRITE_DAC | READ_CONTROL);
+        }
     }
 
-  SubjectSecurityContext.ClientToken = Token;
-  SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
-
-  /* Lock subject context */
-  SeLockSubjectContext(&SubjectSecurityContext);
-
-  if (SeAccessCheck(SecurityDescriptor,
-                   &SubjectSecurityContext,
-                   TRUE,
-                   DesiredAccess,
-                   0,
-                   &PrivilegeSet,
-                   GenericMapping,
-                   PreviousMode,
-                   GrantedAccess,
-                   AccessStatus))
+    if (DesiredAccess == 0)
     {
-      Status = *AccessStatus;
+        *GrantedAccess = PreviouslyGrantedAccess;
+        *AccessStatus = STATUS_SUCCESS;
     }
-  else
+    else
     {
-      Status = STATUS_ACCESS_DENIED;
+        /* Now perform the access check */
+        SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
+                       &SubjectSecurityContext,
+                       DesiredAccess,
+                       PreviouslyGrantedAccess,
+                       &PrivilegeSet, //FIXME
+                       GenericMapping,
+                       PreviousMode,
+                       GrantedAccess,
+                       AccessStatus);
     }
 
-  /* Unlock subject context */
-  SeUnlockSubjectContext(&SubjectSecurityContext);
+    /* Unlock subject context */
+    SeUnlockSubjectContext(&SubjectSecurityContext);
 
-  ObDereferenceObject(Token);
+    /* Release the captured security descriptor */
+    SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
+                                PreviousMode,
+                                FALSE);
 
-  DPRINT("NtAccessCheck() done\n");
+    /* Dereference the token */
+    ObDereferenceObject(Token);
 
-  return Status;
+    /* Check succeeded */
+    return STATUS_SUCCESS;
 }
 
+
 NTSTATUS
 NTAPI
 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
@@ -1255,37 +989,4 @@ NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemN
     return STATUS_NOT_IMPLEMENTED;
 }
 
-VOID STDCALL
-SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
-                          OUT PACCESS_MASK DesiredAccess)
-{
-    if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
-                               GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
-    {
-        *DesiredAccess |= READ_CONTROL;
-    }
-    if (SecurityInformation & SACL_SECURITY_INFORMATION)
-    {
-        *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
-    }
-}
-
-VOID STDCALL
-SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
-                        OUT PACCESS_MASK DesiredAccess)
-{
-    if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
-    {
-        *DesiredAccess |= WRITE_OWNER;
-    }
-    if (SecurityInformation & DACL_SECURITY_INFORMATION)
-    {
-        *DesiredAccess |= WRITE_DAC;
-    }
-    if (SecurityInformation & SACL_SECURITY_INFORMATION)
-    {
-        *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
-    }
-}
-
 /* EOF */