-/* $Id: semgr.c,v 1.30 2004/05/20 12:42:11 ekohl Exp $
+/* $Id$
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Security manager
- * FILE: kernel/se/semgr.c
- * PROGRAMER: ?
- * REVISION HISTORY:
- * 26/07/98: Added stubs for security functions
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/se/semgr.c
+ * PURPOSE: Security manager
+ *
+ * PROGRAMMERS: No programmer listed.
*/
/* 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')
-
-
/* GLOBALS ******************************************************************/
-PSE_EXPORTS EXPORTED SeExports = NULL;
+PSE_EXPORTS SeExports = NULL;
+SE_EXPORTS SepExports;
+
+static ERESOURCE SepSubjectContextLock;
/* PROTOTYPES ***************************************************************/
static BOOLEAN SepInitExports(VOID);
-/* FUNCTIONS ****************************************************************/
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, SeInit1)
+#pragma alloc_text(INIT, SeInit2)
+#pragma alloc_text(INIT, SepInitExports)
+#endif
+/* FUNCTIONS ****************************************************************/
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
SeInit1(VOID)
{
SepInitLuid();
if (!SepInitExports())
return FALSE;
+ /* Initialize the subject context lock */
+ ExInitializeResource(&SepSubjectContextLock);
+
return TRUE;
}
-BOOLEAN INIT_FUNCTION
+BOOLEAN
+INIT_FUNCTION
+NTAPI
SeInit2(VOID)
{
SepInitializeTokenImplementation();
BOOLEAN
+NTAPI
SeInitSRM(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
OBJ_PERMANENT,
0,
NULL);
- Status = NtCreateDirectoryObject(&DirectoryHandle,
+ Status = ZwCreateDirectoryObject(&DirectoryHandle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
OBJ_PERMANENT,
DirectoryHandle,
SePublicDefaultSd);
- Status = NtCreateEvent(&EventHandle,
+ Status = ZwCreateEvent(&EventHandle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
- FALSE,
+ SynchronizationEvent,
FALSE);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
- NtClose(EventHandle);
- NtClose(DirectoryHandle);
+ ZwClose(EventHandle);
+ ZwClose(DirectoryHandle);
/* FIXME: Create SRM port and listener thread */
static BOOLEAN INIT_FUNCTION
SepInitExports(VOID)
{
- SeExports = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(SE_EXPORTS),
- TAG_SXPT);
- if (SeExports == NULL)
- return FALSE;
-
- SeExports->SeCreateTokenPrivilege = SeCreateTokenPrivilege;
- SeExports->SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
- SeExports->SeLockMemoryPrivilege = SeLockMemoryPrivilege;
- SeExports->SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
- SeExports->SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
- SeExports->SeTcbPrivilege = SeTcbPrivilege;
- SeExports->SeSecurityPrivilege = SeSecurityPrivilege;
- SeExports->SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
- SeExports->SeLoadDriverPrivilege = SeLoadDriverPrivilege;
- SeExports->SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
- SeExports->SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
- SeExports->SeSystemProfilePrivilege = SeSystemProfilePrivilege;
- SeExports->SeSystemtimePrivilege = SeSystemtimePrivilege;
- SeExports->SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
- SeExports->SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
- SeExports->SeBackupPrivilege = SeBackupPrivilege;
- SeExports->SeRestorePrivilege = SeRestorePrivilege;
- SeExports->SeShutdownPrivilege = SeShutdownPrivilege;
- SeExports->SeDebugPrivilege = SeDebugPrivilege;
- SeExports->SeAuditPrivilege = SeAuditPrivilege;
- SeExports->SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
- SeExports->SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
- SeExports->SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
-
- SeExports->SeNullSid = SeNullSid;
- SeExports->SeWorldSid = SeWorldSid;
- SeExports->SeLocalSid = SeLocalSid;
- SeExports->SeCreatorOwnerSid = SeCreatorOwnerSid;
- SeExports->SeCreatorGroupSid = SeCreatorGroupSid;
- SeExports->SeNtAuthoritySid = SeNtAuthoritySid;
- SeExports->SeDialupSid = SeDialupSid;
- SeExports->SeNetworkSid = SeNetworkSid;
- SeExports->SeBatchSid = SeBatchSid;
- SeExports->SeInteractiveSid = SeInteractiveSid;
- SeExports->SeLocalSystemSid = SeLocalSystemSid;
- SeExports->SeAliasAdminsSid = SeAliasAdminsSid;
- SeExports->SeAliasUsersSid = SeAliasUsersSid;
- SeExports->SeAliasGuestsSid = SeAliasGuestsSid;
- SeExports->SeAliasPowerUsersSid = SeAliasPowerUsersSid;
- SeExports->SeAliasAccountOpsSid = SeAliasAccountOpsSid;
- SeExports->SeAliasSystemOpsSid = SeAliasSystemOpsSid;
- SeExports->SeAliasPrintOpsSid = SeAliasPrintOpsSid;
- SeExports->SeAliasBackupOpsSid = SeAliasBackupOpsSid;
-
+ 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;
}
UNIMPLEMENTED;
}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtAllocateUuids(PULARGE_INTEGER Time,
- PULONG Range,
- PULONG Sequence)
+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)
{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
+ PISECURITY_DESCRIPTOR ObjectSd;
+ PISECURITY_DESCRIPTOR NewSd;
+ PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+ POBJECT_HEADER Header = BODY_TO_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 = 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);
+ }
-NTSTATUS STDCALL
-NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
- IN HANDLE ClientToken,
- IN ACCESS_MASK DesiredAccess,
- IN PGENERIC_MAPPING GenericMapping,
- OUT PPRIVILEGE_SET PrivilegeSet,
- OUT PULONG ReturnLength,
- OUT PULONG GrantedAccess,
- OUT PBOOLEAN AccessStatus)
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
+ return STATUS_SUCCESS;
+}
/*
* @implemented
VOID STDCALL
SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- PEPROCESS Process;
+ PETHREAD Thread;
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
- Process = PsGetCurrentThread ()->ThreadsProcess;
+ PAGED_CODE();
- 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);
+ }
}
/*
- * @unimplemented
+ * @implemented
*/
VOID STDCALL
SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
+
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
}
* @implemented
*/
VOID STDCALL
-SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
+SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- ObDereferenceObject (SubjectContext->PrimaryToken);
- if (SubjectContext->ClientToken != NULL)
- {
- ObDereferenceObject (SubjectContext->ClientToken);
- }
+ PAGED_CODE();
+
+ ExReleaseResourceLite(&SepSubjectContextLock);
+ KeLeaveCriticalRegion();
}
/*
- * @unimplemented
+ * @implemented
*/
VOID STDCALL
-SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
+SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
+
+ if (SubjectContext->PrimaryToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->PrimaryToken);
+ }
+
+ if (SubjectContext->ClientToken != NULL)
+ {
+ ObDereferenceObject(SubjectContext->ClientToken);
+ }
}
* @implemented
*/
NTSTATUS STDCALL
-SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
- if ((*SecurityDescriptor) != NULL)
+ PAGED_CODE();
+
+ 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
+ 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;
+ }
+
+
+ /* 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;
+
+ DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
+ sizeof(SECURITY_DESCRIPTOR),
+ OwnerLength,
+ GroupLength,
+ DaclLength,
+ SaclLength);
+
+ Descriptor = ExAllocatePool(PagedPool,
+ Length);
+ if (Descriptor == NULL)
+ {
+ DPRINT1("ExAlloctePool() failed\n");
+ /* FIXME: Unlock subject context */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory( Descriptor, Length );
+ 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;
+ DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
+ }
+ else
+ DPRINT("Owner of %x is zero length\n", Descriptor);
+
+ if (GroupLength != 0)
+ {
+ memmove((PVOID)Current,
+ Group,
+ GroupLength);
+ Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+ }
+
+ /* Unlock subject context */
+ SeUnlockSubjectContext(SubjectContext);
+
+ *NewDescriptor = Descriptor;
+
+ DPRINT("Descrptor %x\n", Descriptor);
+ ASSERT(RtlLengthSecurityDescriptor(Descriptor));
+
+ return STATUS_SUCCESS;
}
-BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
- PSID Sid)
+
+static BOOLEAN
+SepSidInToken(PACCESS_TOKEN _Token,
+ PSID Sid)
{
- ULONG i;
-
- if (Token->UserAndGroupCount == 0)
- {
- return(FALSE);
- }
-
- 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);
- }
- }
- return(FALSE);
+ ULONG i;
+ PTOKEN Token = (PTOKEN)_Token;
+
+ PAGED_CODE();
+
+ if (Token->UserAndGroupCount == 0)
+ {
+ return FALSE;
+ }
+
+ for (i=0; i<Token->UserAndGroupCount; i++)
+ {
+ if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
+ {
+ if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+
+ return FALSE;
}
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-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_MODE GrantedAccess,
- OUT PNTSTATUS AccessStatus)
/*
* FUNCTION: Determines whether the requested access rights can be granted
* to an object protected by a security descriptor and an object owner
* 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
+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)
{
- ULONG i;
- PACL Dacl;
- BOOLEAN Present;
- BOOLEAN Defaulted;
- NTSTATUS Status;
- PACE CurrentAce;
- PSID Sid;
- ACCESS_MASK CurrentAccess;
-
- CurrentAccess = PreviouslyGrantedAccess;
-
- /*
- * Ignore the SACL for now
- */
-
- /*
- * Check the DACL
- */
- Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
- &Present,
- &Dacl,
+ 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();
+
+ CurrentAccess = PreviouslyGrantedAccess;
+
+ if (SubjectContextLocked == FALSE)
+ {
+ SeLockSubjectContext(SubjectSecurityContext);
+ }
+
+ 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);
+ }
+
+ *AccessStatus = Status;
+ return FALSE;
+ }
+
+ /* RULE 1: Grant desired access if the object is unprotected */
+ if (Present == TRUE && Dacl == NULL)
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = DesiredAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+
+ 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))
+ {
+ CurrentAccess |= WRITE_OWNER;
+ if (DesiredAccess == CurrentAccess)
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = CurrentAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+ }
+
+ /* RULE 3: Check whether the token is the owner */
+ Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
+ &Sid,
&Defaulted);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- 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 = CurrentAccess |
- CurrentAce->AccessMask;
- }
- }
- }
- if (!(CurrentAccess & DesiredAccess) &&
- !((~CurrentAccess) & DesiredAccess))
- {
- *AccessStatus = STATUS_ACCESS_DENIED;
- }
- else
- {
- *AccessStatus = STATUS_SUCCESS;
- }
- *GrantedAccess = CurrentAccess;
-
- return(STATUS_SUCCESS);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *AccessStatus = Status;
+ return FALSE;
+ }
+
+ if (SepSidInToken(Token, Sid))
+ {
+ CurrentAccess |= (READ_CONTROL | WRITE_DAC);
+ if (DesiredAccess == CurrentAccess)
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = CurrentAccess;
+ *AccessStatus = STATUS_SUCCESS;
+ return TRUE;
+ }
+ }
+
+ /* Fail if DACL is absent */
+ if (Present == FALSE)
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = 0;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
+ }
+
+ /* RULE 4: Grant rights according to the DACL */
+ 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(Token, Sid))
+ {
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ *GrantedAccess = 0;
+ *AccessStatus = STATUS_ACCESS_DENIED;
+ return TRUE;
+ }
+ }
+
+ if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+ {
+ if (SepSidInToken(Token, Sid))
+ {
+ CurrentAccess |= CurrentAce->AccessMask;
+ }
+ }
+ }
+
+ if (SubjectContextLocked == FALSE)
+ {
+ SeUnlockSubjectContext(SubjectSecurityContext);
+ }
+
+ DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
+ CurrentAccess, DesiredAccess);
+
+ *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;
+ PTOKEN Token;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ 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;
+
+ /* Lock subject context */
+ SeLockSubjectContext(&SubjectSecurityContext);
+
+ if (SeAccessCheck(SecurityDescriptor,
+ &SubjectSecurityContext,
+ TRUE,
+ DesiredAccess,
+ 0,
+ &PrivilegeSet,
+ GenericMapping,
+ PreviousMode,
+ GrantedAccess,
+ AccessStatus))
+ {
+ Status = *AccessStatus;
+ }
+ else
+ {
+ Status = STATUS_ACCESS_DENIED;
+ }
+
+ /* Unlock subject context */
+ SeUnlockSubjectContext(&SubjectSecurityContext);
+
+ ObDereferenceObject(Token);
+
+ DPRINT("NtAccessCheck() done\n");
+
+ return Status;
}
/* EOF */