3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/semgr.c
6 * PURPOSE: Security manager
8 * PROGRAMMERS: No programmer listed.
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 #define TAG_SXPT TAG('S', 'X', 'P', 'T')
20 /* GLOBALS ******************************************************************/
22 PSE_EXPORTS EXPORTED SeExports
= NULL
;
24 static ERESOURCE SepSubjectContextLock
;
27 /* PROTOTYPES ***************************************************************/
29 static BOOLEAN
SepInitExports(VOID
);
32 /* FUNCTIONS ****************************************************************/
39 if (!SepInitSecurityIDs())
50 if (!SepInitExports())
53 /* Initialize the subject context lock */
54 ExInitializeResource(&SepSubjectContextLock
);
63 SepInitializeTokenImplementation();
72 OBJECT_ATTRIBUTES ObjectAttributes
;
74 HANDLE DirectoryHandle
;
78 /* Create '\Security' directory */
79 RtlInitUnicodeString(&Name
,
81 InitializeObjectAttributes(&ObjectAttributes
,
86 Status
= ZwCreateDirectoryObject(&DirectoryHandle
,
89 if (!NT_SUCCESS(Status
))
91 DPRINT1("Failed to create 'Security' directory!\n");
95 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
96 RtlInitUnicodeString(&Name
,
97 L
"\\LSA_AUTHENTICATION_INITALIZED");
98 InitializeObjectAttributes(&ObjectAttributes
,
103 Status
= ZwCreateEvent(&EventHandle
,
106 SynchronizationEvent
,
108 if (!NT_SUCCESS(Status
))
110 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
111 NtClose(DirectoryHandle
);
115 ZwClose(EventHandle
);
116 ZwClose(DirectoryHandle
);
118 /* FIXME: Create SRM port and listener thread */
124 static BOOLEAN INIT_FUNCTION
127 SeExports
= ExAllocatePoolWithTag(NonPagedPool
,
130 if (SeExports
== NULL
)
133 SeExports
->SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
134 SeExports
->SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
135 SeExports
->SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
136 SeExports
->SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
137 SeExports
->SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
138 SeExports
->SeTcbPrivilege
= SeTcbPrivilege
;
139 SeExports
->SeSecurityPrivilege
= SeSecurityPrivilege
;
140 SeExports
->SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
141 SeExports
->SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
142 SeExports
->SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
143 SeExports
->SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
144 SeExports
->SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
145 SeExports
->SeSystemtimePrivilege
= SeSystemtimePrivilege
;
146 SeExports
->SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
147 SeExports
->SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
148 SeExports
->SeBackupPrivilege
= SeBackupPrivilege
;
149 SeExports
->SeRestorePrivilege
= SeRestorePrivilege
;
150 SeExports
->SeShutdownPrivilege
= SeShutdownPrivilege
;
151 SeExports
->SeDebugPrivilege
= SeDebugPrivilege
;
152 SeExports
->SeAuditPrivilege
= SeAuditPrivilege
;
153 SeExports
->SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
154 SeExports
->SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
155 SeExports
->SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
157 SeExports
->SeNullSid
= SeNullSid
;
158 SeExports
->SeWorldSid
= SeWorldSid
;
159 SeExports
->SeLocalSid
= SeLocalSid
;
160 SeExports
->SeCreatorOwnerSid
= SeCreatorOwnerSid
;
161 SeExports
->SeCreatorGroupSid
= SeCreatorGroupSid
;
162 SeExports
->SeNtAuthoritySid
= SeNtAuthoritySid
;
163 SeExports
->SeDialupSid
= SeDialupSid
;
164 SeExports
->SeNetworkSid
= SeNetworkSid
;
165 SeExports
->SeBatchSid
= SeBatchSid
;
166 SeExports
->SeInteractiveSid
= SeInteractiveSid
;
167 SeExports
->SeLocalSystemSid
= SeLocalSystemSid
;
168 SeExports
->SeAliasAdminsSid
= SeAliasAdminsSid
;
169 SeExports
->SeAliasUsersSid
= SeAliasUsersSid
;
170 SeExports
->SeAliasGuestsSid
= SeAliasGuestsSid
;
171 SeExports
->SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
172 SeExports
->SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
173 SeExports
->SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
174 SeExports
->SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
175 SeExports
->SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
181 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
186 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
196 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
200 BOOLEAN EffectiveOnly
;
204 Thread
= PsGetCurrentThread();
207 SubjectContext
->ProcessAuditId
= 0;
208 SubjectContext
->PrimaryToken
= NULL
;
209 SubjectContext
->ClientToken
= NULL
;
210 SubjectContext
->ImpersonationLevel
= 0;
214 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
215 SubjectContext
->ClientToken
=
216 PsReferenceImpersonationToken(Thread
,
219 &SubjectContext
->ImpersonationLevel
);
220 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
229 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
233 KeEnterCriticalRegion();
234 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
242 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
246 ExReleaseResourceLite(&SepSubjectContextLock
);
247 KeLeaveCriticalRegion();
255 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
259 if (SubjectContext
->PrimaryToken
!= NULL
)
261 ObDereferenceObject(SubjectContext
->PrimaryToken
);
264 if (SubjectContext
->ClientToken
!= NULL
)
266 ObDereferenceObject(SubjectContext
->ClientToken
);
275 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
279 if (*SecurityDescriptor
!= NULL
)
281 ExFreePool(*SecurityDescriptor
);
282 *SecurityDescriptor
= NULL
;
285 return STATUS_SUCCESS
;
293 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
294 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
295 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
296 IN GUID
*ObjectType OPTIONAL
,
297 IN BOOLEAN IsDirectoryObject
,
298 IN ULONG AutoInheritFlags
,
299 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
300 IN PGENERIC_MAPPING GenericMapping
,
301 IN POOL_TYPE PoolType
)
304 return STATUS_NOT_IMPLEMENTED
;
309 * FUNCTION: Creates a security descriptor for a new object.
312 * ExplicitDescriptor =
314 * IsDirectoryObject =
323 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
324 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
325 PSECURITY_DESCRIPTOR
*NewDescriptor
,
326 BOOLEAN IsDirectoryObject
,
327 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
328 PGENERIC_MAPPING GenericMapping
,
331 PSECURITY_DESCRIPTOR Descriptor
;
333 ULONG OwnerLength
= 0;
334 ULONG GroupLength
= 0;
335 ULONG DaclLength
= 0;
336 ULONG SaclLength
= 0;
347 /* Lock subject context */
348 SeLockSubjectContext(SubjectContext
);
350 if (SubjectContext
->ClientToken
!= NULL
)
352 Token
= SubjectContext
->ClientToken
;
356 Token
= SubjectContext
->PrimaryToken
;
360 /* Inherit the Owner SID */
361 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
363 DPRINT("Use explicit owner sid!\n");
364 Owner
= ExplicitDescriptor
->Owner
;
365 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
367 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
374 DPRINT("Use token owner sid!\n");
375 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
379 DPRINT("Use default owner sid!\n");
380 Owner
= SeLocalSystemSid
;
383 Control
|= SE_OWNER_DEFAULTED
;
386 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
389 /* Inherit the Group SID */
390 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
392 DPRINT("Use explicit group sid!\n");
393 Group
= ExplicitDescriptor
->Group
;
394 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
396 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
403 DPRINT("Use token group sid!\n");
404 Group
= Token
->PrimaryGroup
;
408 DPRINT("Use default group sid!\n");
409 Group
= SeLocalSystemSid
;
412 Control
|= SE_OWNER_DEFAULTED
;
415 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
418 /* Inherit the DACL */
419 if (ExplicitDescriptor
!= NULL
&&
420 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
421 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
423 DPRINT("Use explicit DACL!\n");
424 Dacl
= ExplicitDescriptor
->Dacl
;
425 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
427 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
430 Control
|= SE_DACL_PRESENT
;
432 else if (ParentDescriptor
!= NULL
&&
433 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
435 DPRINT("Use parent DACL!\n");
437 Dacl
= ParentDescriptor
->Dacl
;
438 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
440 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
442 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
444 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
446 DPRINT("Use token default DACL!\n");
448 Dacl
= Token
->DefaultDacl
;
449 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
453 DPRINT("Use NULL DACL!\n");
455 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
458 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
461 /* Inherit the SACL */
462 if (ExplicitDescriptor
!= NULL
&&
463 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
464 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
466 DPRINT("Use explicit SACL!\n");
467 Sacl
= ExplicitDescriptor
->Sacl
;
468 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
470 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
473 Control
|= SE_SACL_PRESENT
;
475 else if (ParentDescriptor
!= NULL
&&
476 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
478 DPRINT("Use parent SACL!\n");
480 Sacl
= ParentDescriptor
->Sacl
;
481 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
483 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
485 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
488 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
491 /* Allocate and initialize the new security descriptor */
492 Length
= sizeof(SECURITY_DESCRIPTOR
) +
493 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
495 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
496 sizeof(SECURITY_DESCRIPTOR
),
502 Descriptor
= ExAllocatePool(NonPagedPool
,
504 RtlZeroMemory( Descriptor
, Length
);
506 if (Descriptor
== NULL
)
508 DPRINT1("ExAlloctePool() failed\n");
509 /* FIXME: Unlock subject context */
510 return STATUS_INSUFFICIENT_RESOURCES
;
513 RtlCreateSecurityDescriptor(Descriptor
,
514 SECURITY_DESCRIPTOR_REVISION
);
516 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
518 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
522 RtlCopyMemory((PVOID
)Current
,
525 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
526 Current
+= SaclLength
;
531 RtlCopyMemory((PVOID
)Current
,
534 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
535 Current
+= DaclLength
;
538 if (OwnerLength
!= 0)
540 RtlCopyMemory((PVOID
)Current
,
543 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
544 Current
+= OwnerLength
;
545 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
548 DPRINT("Owner of %x is zero length\n", Descriptor
);
550 if (GroupLength
!= 0)
552 memmove((PVOID
)Current
,
555 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
558 /* Unlock subject context */
559 SeUnlockSubjectContext(SubjectContext
);
561 *NewDescriptor
= Descriptor
;
563 DPRINT("Descrptor %x\n", Descriptor
);
564 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
566 return STATUS_SUCCESS
;
571 SepSidInToken(PACCESS_TOKEN _Token
,
575 PTOKEN Token
= (PTOKEN
)_Token
;
579 if (Token
->UserAndGroupCount
== 0)
584 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
586 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
588 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
602 * FUNCTION: Determines whether the requested access rights can be granted
603 * to an object protected by a security descriptor and an object owner
605 * SecurityDescriptor = Security descriptor protecting the object
606 * SubjectSecurityContext = Subject's captured security context
607 * SubjectContextLocked = Indicates the user's subject context is locked
608 * DesiredAccess = Access rights the caller is trying to acquire
609 * PreviouslyGrantedAccess = Specified the access rights already granted
611 * GenericMapping = Generic mapping associated with the object
612 * AccessMode = Access mode used for the check
613 * GrantedAccess (OUT) = On return specifies the access granted
614 * AccessStatus (OUT) = Status indicating why access was denied
615 * RETURNS: If access was granted, returns TRUE
620 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
621 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
622 IN BOOLEAN SubjectContextLocked
,
623 IN ACCESS_MASK DesiredAccess
,
624 IN ACCESS_MASK PreviouslyGrantedAccess
,
625 OUT PPRIVILEGE_SET
* Privileges
,
626 IN PGENERIC_MAPPING GenericMapping
,
627 IN KPROCESSOR_MODE AccessMode
,
628 OUT PACCESS_MASK GrantedAccess
,
629 OUT PNTSTATUS AccessStatus
)
631 LUID_AND_ATTRIBUTES Privilege
;
632 ACCESS_MASK CurrentAccess
;
644 CurrentAccess
= PreviouslyGrantedAccess
;
646 if (SubjectContextLocked
== FALSE
)
648 SeLockSubjectContext(SubjectSecurityContext
);
651 Token
= SubjectSecurityContext
->ClientToken
?
652 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
655 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
659 if (!NT_SUCCESS(Status
))
661 if (SubjectContextLocked
== FALSE
)
663 SeUnlockSubjectContext(SubjectSecurityContext
);
666 *AccessStatus
= Status
;
670 /* RULE 1: Grant desired access if the object is unprotected */
671 if (Present
== TRUE
&& Dacl
== NULL
)
673 if (SubjectContextLocked
== FALSE
)
675 SeUnlockSubjectContext(SubjectSecurityContext
);
678 *GrantedAccess
= DesiredAccess
;
679 *AccessStatus
= STATUS_SUCCESS
;
683 CurrentAccess
= PreviouslyGrantedAccess
;
685 /* RULE 2: Check token for 'take ownership' privilege */
686 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
687 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
689 if (SepPrivilegeCheck(Token
,
692 PRIVILEGE_SET_ALL_NECESSARY
,
695 CurrentAccess
|= WRITE_OWNER
;
696 if (DesiredAccess
== CurrentAccess
)
698 if (SubjectContextLocked
== FALSE
)
700 SeUnlockSubjectContext(SubjectSecurityContext
);
703 *GrantedAccess
= CurrentAccess
;
704 *AccessStatus
= STATUS_SUCCESS
;
709 /* RULE 3: Check whether the token is the owner */
710 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
713 if (!NT_SUCCESS(Status
))
715 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
716 if (SubjectContextLocked
== FALSE
)
718 SeUnlockSubjectContext(SubjectSecurityContext
);
721 *AccessStatus
= Status
;
725 if (SepSidInToken(Token
, Sid
))
727 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
728 if (DesiredAccess
== CurrentAccess
)
730 if (SubjectContextLocked
== FALSE
)
732 SeUnlockSubjectContext(SubjectSecurityContext
);
735 *GrantedAccess
= CurrentAccess
;
736 *AccessStatus
= STATUS_SUCCESS
;
741 /* Fail if DACL is absent */
742 if (Present
== FALSE
)
744 if (SubjectContextLocked
== FALSE
)
746 SeUnlockSubjectContext(SubjectSecurityContext
);
750 *AccessStatus
= STATUS_ACCESS_DENIED
;
754 /* RULE 4: Grant rights according to the DACL */
755 CurrentAce
= (PACE
)(Dacl
+ 1);
756 for (i
= 0; i
< Dacl
->AceCount
; i
++)
758 Sid
= (PSID
)(CurrentAce
+ 1);
759 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
761 if (SepSidInToken(Token
, Sid
))
763 if (SubjectContextLocked
== FALSE
)
765 SeUnlockSubjectContext(SubjectSecurityContext
);
769 *AccessStatus
= STATUS_ACCESS_DENIED
;
774 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
776 if (SepSidInToken(Token
, Sid
))
778 CurrentAccess
|= CurrentAce
->AccessMask
;
783 if (SubjectContextLocked
== FALSE
)
785 SeUnlockSubjectContext(SubjectSecurityContext
);
788 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
789 CurrentAccess
, DesiredAccess
);
791 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
794 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
801 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
802 IN HANDLE TokenHandle
,
803 IN ACCESS_MASK DesiredAccess
,
804 IN PGENERIC_MAPPING GenericMapping
,
805 OUT PPRIVILEGE_SET PrivilegeSet
,
806 OUT PULONG ReturnLength
,
807 OUT PACCESS_MASK GrantedAccess
,
808 OUT PNTSTATUS AccessStatus
)
810 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
811 KPROCESSOR_MODE PreviousMode
;
817 DPRINT("NtAccessCheck() called\n");
819 PreviousMode
= KeGetPreviousMode();
820 if (PreviousMode
== KernelMode
)
822 *GrantedAccess
= DesiredAccess
;
823 *AccessStatus
= STATUS_SUCCESS
;
824 return STATUS_SUCCESS
;
827 Status
= ObReferenceObjectByHandle(TokenHandle
,
833 if (!NT_SUCCESS(Status
))
835 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
839 /* Check token type */
840 if (Token
->TokenType
!= TokenImpersonation
)
842 DPRINT1("No impersonation token\n");
843 ObDereferenceObject(Token
);
844 return STATUS_ACCESS_VIOLATION
;
847 /* Check impersonation level */
848 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
850 DPRINT1("Invalid impersonation level\n");
851 ObDereferenceObject(Token
);
852 return STATUS_ACCESS_VIOLATION
;
855 RtlZeroMemory(&SubjectSecurityContext
,
856 sizeof(SECURITY_SUBJECT_CONTEXT
));
857 SubjectSecurityContext
.ClientToken
= Token
;
858 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
860 /* Lock subject context */
861 SeLockSubjectContext(&SubjectSecurityContext
);
863 if (SeAccessCheck(SecurityDescriptor
,
864 &SubjectSecurityContext
,
874 Status
= *AccessStatus
;
878 Status
= STATUS_ACCESS_DENIED
;
881 /* Unlock subject context */
882 SeUnlockSubjectContext(&SubjectSecurityContext
);
884 ObDereferenceObject(Token
);
886 DPRINT("NtAccessCheck() done\n");