-/* $Id: semgr.c,v 1.32 2004/07/13 16:59:35 ekohl Exp $
+/* $Id: semgr.c,v 1.43 2004/09/08 11:39:59 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/ps.h>
-#include <internal/se.h>
-
+#include <ntoskrnl.h>
+#define NDEBUG
#include <internal/debug.h>
#define TAG_SXPT TAG('S', 'X', 'P', 'T')
VOID STDCALL
SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- PEPROCESS Process;
+ PETHREAD Thread;
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
- Process = PsGetCurrentThread ()->ThreadsProcess;
-
- SubjectContext->ProcessAuditId = Process;
- SubjectContext->ClientToken =
- PsReferenceImpersonationToken (PsGetCurrentThread(),
- &CopyOnOpen,
- &EffectiveOnly,
- &SubjectContext->ImpersonationLevel);
- SubjectContext->PrimaryToken = PsReferencePrimaryToken (Process);
+ Thread = PsGetCurrentThread();
+ if (Thread == NULL)
+ {
+ SubjectContext->ProcessAuditId = 0;
+ SubjectContext->PrimaryToken = NULL;
+ SubjectContext->ClientToken = NULL;
+ SubjectContext->ImpersonationLevel = 0;
+ }
+ else
+ {
+ SubjectContext->ProcessAuditId = Thread->ThreadsProcess;
+ SubjectContext->ClientToken =
+ PsReferenceImpersonationToken(Thread,
+ &CopyOnOpen,
+ &EffectiveOnly,
+ &SubjectContext->ImpersonationLevel);
+ SubjectContext->PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
+ }
}
VOID STDCALL
SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- ObDereferenceObject (SubjectContext->PrimaryToken);
+ if (SubjectContext->PrimaryToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->PrimaryToken);
+ }
+
if (SubjectContext->ClientToken != NULL)
{
- ObDereferenceObject (SubjectContext->ClientToken);
+ ObDereferenceObject(SubjectContext->ClientToken);
}
}
* @implemented
*/
NTSTATUS STDCALL
-SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
- if ((*SecurityDescriptor) != NULL)
+ if (*SecurityDescriptor != NULL)
{
ExFreePool(*SecurityDescriptor);
- (*SecurityDescriptor) = NULL;
+ *SecurityDescriptor = NULL;
}
- return(STATUS_SUCCESS);
+
+ return STATUS_SUCCESS;
}
-#if 0
-VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
- PSID* Owner,
- PSID* PrimaryGroup,
- PSID* ProcessOwner,
- PSID* ProcessPrimaryGroup,
- PACL* DefaultDacl)
+/*
+ * @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)
{
- PACCESS_TOKEN Token;
-
- if (SubjectContext->ClientToken != NULL)
- {
- Token = SubjectContext->ClientToken;
- }
- else
- {
- Token = SubjectContext->PrimaryToken;
- }
- *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
- *PrimaryGroup = Token->PrimaryGroup;
- *DefaultDacl = Token->DefaultDacl;
- *ProcessOwner = SubjectContext->PrimaryToken->
- UserAndGroups[Token->DefaultOwnerIndex].Sid;
- *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS SepInheritAcl(PACL Acl,
- BOOLEAN IsDirectoryObject,
- PSID Owner,
- PSID PrimaryGroup,
- PACL DefaultAcl,
- PSID ProcessOwner,
- PSID ProcessGroup,
- PGENERIC_MAPPING GenericMapping)
-{
- if (Acl == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (Acl->AclRevision != 2 &&
- Acl->AclRevision != 3 )
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
-}
-#endif
/*
- * @unimplemented
+ * 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,
- PSECURITY_DESCRIPTOR ExplicitDescriptor,
- PSECURITY_DESCRIPTOR* NewDescriptor,
+SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
+ PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
+ PSECURITY_DESCRIPTOR *NewDescriptor,
BOOLEAN IsDirectoryObject,
PSECURITY_SUBJECT_CONTEXT SubjectContext,
PGENERIC_MAPPING GenericMapping,
POOL_TYPE PoolType)
{
-#if 0
- PSECURITY_DESCRIPTOR Descriptor;
- PSID Owner;
- PSID PrimaryGroup;
- PACL DefaultDacl;
- PSID ProcessOwner;
- PSID ProcessPrimaryGroup;
- PACL Sacl;
-
- if (ExplicitDescriptor == NULL)
- {
- RtlCreateSecurityDescriptor(&Descriptor, 1);
- }
- else
- {
- Descriptor = ExplicitDescriptor;
- }
- SeLockSubjectContext(SubjectContext);
- SepGetDefaultsSubjectContext(SubjectContext,
- &Owner,
- &PrimaryGroup,
- &DefaultDacl,
- &ProcessOwner,
- &ProcessPrimaryGroup);
- if (Descriptor->Control & SE_SACL_PRESENT ||
- Descriptor->Control & SE_SACL_DEFAULTED)
- {
- if (ParentDescriptor == NULL)
- {
- }
- if (Descriptor->Control & SE_SACL_PRESENT ||
- Descriptor->Sacl == NULL ||)
- {
- Sacl = NULL;
- }
- else
- {
- Sacl = Descriptor->Sacl;
- if (Descriptor->Control & SE_SELF_RELATIVE)
- {
- Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
- }
- }
- SepInheritAcl(Sacl,
- IsDirectoryObject,
- Owner,
- PrimaryGroup,
- DefaultDacl,
- ProcessOwner,
- GenericMapping);
- }
-#else
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-#endif
+ PSECURITY_DESCRIPTOR Descriptor;
+ PACCESS_TOKEN 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;
+
+ /* FIXME: Lock subject context */
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ Token = SubjectContext->ClientToken;
+ }
+ else
+ {
+ Token = SubjectContext->PrimaryToken;
+ }
+
+
+ /* Inherit the Owner SID */
+ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
+ {
+ DPRINT("Use explicit owner sid!\n");
+ Owner = ExplicitDescriptor->Owner;
+ if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+ {
+ Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
+ }
+ }
+ else
+ {
+ 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;
+ }
+
+ OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+
+
+ /* Inherit the Group SID */
+ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
+ {
+ DPRINT("Use explicit group sid!\n");
+ Group = ExplicitDescriptor->Group;
+ if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+ {
+ Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
+ }
+ }
+ else
+ {
+ 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;
+ }
+
+ GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+
+
+ /* Inherit the DACL */
+ if (ExplicitDescriptor != NULL &&
+ (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
+ !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
+ {
+ 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;
+ }
+ else if (ParentDescriptor != NULL &&
+ (ParentDescriptor->Control & SE_DACL_PRESENT))
+ {
+ 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);
+ }
+ else if (Token != NULL && Token->DefaultDacl != NULL)
+ {
+ DPRINT("Use token default DACL!\n");
+ /* FIXME: Inherit */
+ Dacl = Token->DefaultDacl;
+ Control |= (SE_DACL_PRESENT & SE_DACL_DEFAULTED);
+ }
+ else
+ {
+ DPRINT("Use NULL DACL!\n");
+ Dacl = NULL;
+ Control |= (SE_DACL_PRESENT & SE_DACL_DEFAULTED);
+ }
+
+ DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
+
+
+ /* 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;
+
+
+ /* Allocate and initialize the new security descriptor */
+ Length = sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength;
+
+ Descriptor = ExAllocatePool(NonPagedPool,
+ Length);
+ if (Descriptor == NULL)
+ {
+ DPRINT1("ExAlloctePool() failed\n");
+ /* FIXME: Unlock subject context */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCreateSecurityDescriptor(Descriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+
+ Descriptor->Control = Control | SE_SELF_RELATIVE;
+
+ Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
+
+ if (SaclLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Sacl,
+ SaclLength);
+ Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += SaclLength;
+ }
+
+ if (DaclLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Dacl,
+ DaclLength);
+ Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += DaclLength;
+ }
+
+ if (OwnerLength != 0)
+ {
+ RtlCopyMemory((PVOID)Current,
+ Owner,
+ OwnerLength);
+ Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ Current += OwnerLength;
+ }
+
+ if (GroupLength != 0)
+ {
+ memmove((PVOID)Current,
+ Group,
+ GroupLength);
+ Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ }
+
+ /* FIXME: Unlock subject context */
+
+ *NewDescriptor = Descriptor;
+
+ return STATUS_SUCCESS;
}
OUT PACCESS_MASK GrantedAccess,
OUT PNTSTATUS AccessStatus)
{
- ULONG i;
- PACL Dacl;
- BOOLEAN Present;
- BOOLEAN Defaulted;
- NTSTATUS Status;
- PACE CurrentAce;
- PSID Sid;
- ACCESS_MASK CurrentAccess;
-
- CurrentAccess = PreviouslyGrantedAccess;
-
- /*
- * Check the DACL
- */
- Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
- &Present,
- &Dacl,
- &Defaulted);
- if (!NT_SUCCESS(Status))
- {
- *AccessStatus = Status;
- return FALSE;
- }
-
- CurrentAce = (PACE)(Dacl + 1);
- for (i = 0; i < Dacl->AceCount; i++)
- {
- Sid = (PSID)(CurrentAce + 1);
- if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
- {
- if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- *GrantedAccess = 0;
- return(STATUS_SUCCESS);
- }
- }
-
- if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
- {
- if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
- {
- CurrentAccess |= CurrentAce->AccessMask;
- }
- }
- }
- if (!(CurrentAccess & DesiredAccess) &&
- !((~CurrentAccess) & DesiredAccess))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- }
- else
- {
- *AccessStatus = STATUS_SUCCESS;
- }
- *GrantedAccess = CurrentAccess;
-
- return TRUE;
-}
-
-
-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)
-{
- KPROCESSOR_MODE PreviousMode;
+ LUID_AND_ATTRIBUTES Privilege;
+ ACCESS_MASK CurrentAccess;
PACCESS_TOKEN Token;
+ ULONG i;
+ PACL Dacl;
BOOLEAN Present;
BOOLEAN Defaulted;
PACE CurrentAce;
- PACL Dacl;
PSID Sid;
- ACCESS_MASK CurrentAccess;
- ULONG i;
NTSTATUS Status;
- DPRINT("NtAccessCheck() called\n");
-
- PreviousMode = KeGetPreviousMode();
- if (PreviousMode == KernelMode)
- {
- *GrantedAccess = DesiredAccess;
- *AccessStatus = STATUS_SUCCESS;
- return STATUS_SUCCESS;
- }
-
- Status = ObReferenceObjectByHandle(TokenHandle,
- TOKEN_QUERY,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference token (Status %lx)\n", Status);
- return Status;
- }
-
- /* Check token type */
- if (Token->TokenType != TokenImpersonation)
- {
- DPRINT1("No impersonation token\n");
- ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
+ CurrentAccess = PreviouslyGrantedAccess;
- /* Check impersonation level */
- if (Token->ImpersonationLevel < SecurityAnonymous)
- {
- DPRINT1("Invalid impersonation level\n");
- ObDereferenceObject(Token);
- return STATUS_ACCESS_VIOLATION;
- }
+ Token = SubjectSecurityContext->ClientToken ?
+ SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
/* Get the DACL */
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
&Defaulted);
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlGetDaclSecurityDescriptor() failed (Status %lx)\n", Status);
- ObDereferenceObject(Token);
- return Status;
- }
+ *AccessStatus = Status;
+ return FALSE;
+ }
/* RULE 1: Grant desired access if the object is unprotected */
if (Dacl == NULL)
{
*GrantedAccess = DesiredAccess;
*AccessStatus = STATUS_SUCCESS;
- return STATUS_SUCCESS;
+ return TRUE;
}
- CurrentAccess = 0;
+ CurrentAccess = PreviouslyGrantedAccess;
- /* FIXME: RULE 2: Check token for 'take ownership' privilege */
+ /* 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))
+ {
+ CurrentAccess |= WRITE_OWNER;
+ if (DesiredAccess == CurrentAccess)
+ {
+ *GrantedAccess = CurrentAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+ }
/* RULE 3: Check whether the token is the owner */
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
- ObDereferenceObject(Token);
- return Status;
+ *AccessStatus = Status;
+ return FALSE;
}
if (SepSidInToken(Token, Sid))
CurrentAccess |= (READ_CONTROL | WRITE_DAC);
if (DesiredAccess == CurrentAccess)
{
- *AccessStatus = STATUS_SUCCESS;
*GrantedAccess = CurrentAccess;
- return STATUS_SUCCESS;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
}
}
{
if (SepSidInToken(Token, Sid))
{
- *AccessStatus = STATUS_ACCESS_DENIED;
*GrantedAccess = 0;
- return STATUS_SUCCESS;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
}
}
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
CurrentAccess, DesiredAccess);
- ObDereferenceObject(Token);
-
*GrantedAccess = CurrentAccess & DesiredAccess;
*AccessStatus =
(*GrantedAccess == DesiredAccess) ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
+ return TRUE;
+}
+
+
+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;
+ KPROCESSOR_MODE PreviousMode;
+ PACCESS_TOKEN Token;
+ NTSTATUS Status;
+
+ DPRINT("NtAccessCheck() called\n");
+
+ PreviousMode = KeGetPreviousMode();
+ if (PreviousMode == KernelMode)
+ {
+ *GrantedAccess = DesiredAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return STATUS_SUCCESS;
+ }
+
+ Status = ObReferenceObjectByHandle(TokenHandle,
+ TOKEN_QUERY,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference token (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Check token type */
+ if (Token->TokenType != TokenImpersonation)
+ {
+ DPRINT1("No impersonation token\n");
+ ObDereferenceObject(Token);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* Check impersonation level */
+ if (Token->ImpersonationLevel < SecurityAnonymous)
+ {
+ DPRINT1("Invalid impersonation level\n");
+ ObDereferenceObject(Token);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ RtlZeroMemory(&SubjectSecurityContext,
+ sizeof(SECURITY_SUBJECT_CONTEXT));
+ SubjectSecurityContext.ClientToken = Token;
+ SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
+
+ /* FIXME: Lock subject context */
+
+ if (!SeAccessCheck(SecurityDescriptor,
+ &SubjectSecurityContext,
+ TRUE,
+ DesiredAccess,
+ 0,
+ &PrivilegeSet,
+ GenericMapping,
+ PreviousMode,
+ GrantedAccess,
+ AccessStatus))
+ {
+ Status = *AccessStatus;
+ }
+ else
+ {
+ Status = STATUS_ACCESS_DENIED;
+ }
+
+ /* FIXME: Unlock subject context */
+
+ ObDereferenceObject(Token);
+
DPRINT("NtAccessCheck() done\n");
- return STATUS_SUCCESS;
+ return Status;
}
/* EOF */