1 /* $Id: semgr.c,v 1.50 2004/11/12 12:05:05 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/semgr.c
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 #define TAG_SXPT TAG('S', 'X', 'P', 'T')
21 /* GLOBALS ******************************************************************/
23 PSE_EXPORTS EXPORTED SeExports
= NULL
;
25 static ERESOURCE SepSubjectContextLock
;
28 /* PROTOTYPES ***************************************************************/
30 static BOOLEAN
SepInitExports(VOID
);
33 /* FUNCTIONS ****************************************************************/
40 if (!SepInitSecurityIDs())
51 if (!SepInitExports())
54 /* Initialize the subject context lock */
55 ExInitializeResource(&SepSubjectContextLock
);
64 SepInitializeTokenImplementation();
73 OBJECT_ATTRIBUTES ObjectAttributes
;
75 HANDLE DirectoryHandle
;
79 /* Create '\Security' directory */
80 RtlInitUnicodeString(&Name
,
82 InitializeObjectAttributes(&ObjectAttributes
,
87 Status
= NtCreateDirectoryObject(&DirectoryHandle
,
90 if (!NT_SUCCESS(Status
))
92 DPRINT1("Failed to create 'Security' directory!\n");
96 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
97 RtlInitUnicodeString(&Name
,
98 L
"\\LSA_AUTHENTICATION_INITALIZED");
99 InitializeObjectAttributes(&ObjectAttributes
,
104 Status
= NtCreateEvent(&EventHandle
,
107 SynchronizationEvent
,
109 if (!NT_SUCCESS(Status
))
111 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
112 NtClose(DirectoryHandle
);
116 NtClose(EventHandle
);
117 NtClose(DirectoryHandle
);
119 /* FIXME: Create SRM port and listener thread */
125 static BOOLEAN INIT_FUNCTION
128 SeExports
= ExAllocatePoolWithTag(NonPagedPool
,
131 if (SeExports
== NULL
)
134 SeExports
->SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
135 SeExports
->SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
136 SeExports
->SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
137 SeExports
->SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
138 SeExports
->SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
139 SeExports
->SeTcbPrivilege
= SeTcbPrivilege
;
140 SeExports
->SeSecurityPrivilege
= SeSecurityPrivilege
;
141 SeExports
->SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
142 SeExports
->SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
143 SeExports
->SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
144 SeExports
->SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
145 SeExports
->SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
146 SeExports
->SeSystemtimePrivilege
= SeSystemtimePrivilege
;
147 SeExports
->SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
148 SeExports
->SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
149 SeExports
->SeBackupPrivilege
= SeBackupPrivilege
;
150 SeExports
->SeRestorePrivilege
= SeRestorePrivilege
;
151 SeExports
->SeShutdownPrivilege
= SeShutdownPrivilege
;
152 SeExports
->SeDebugPrivilege
= SeDebugPrivilege
;
153 SeExports
->SeAuditPrivilege
= SeAuditPrivilege
;
154 SeExports
->SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
155 SeExports
->SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
156 SeExports
->SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
158 SeExports
->SeNullSid
= SeNullSid
;
159 SeExports
->SeWorldSid
= SeWorldSid
;
160 SeExports
->SeLocalSid
= SeLocalSid
;
161 SeExports
->SeCreatorOwnerSid
= SeCreatorOwnerSid
;
162 SeExports
->SeCreatorGroupSid
= SeCreatorGroupSid
;
163 SeExports
->SeNtAuthoritySid
= SeNtAuthoritySid
;
164 SeExports
->SeDialupSid
= SeDialupSid
;
165 SeExports
->SeNetworkSid
= SeNetworkSid
;
166 SeExports
->SeBatchSid
= SeBatchSid
;
167 SeExports
->SeInteractiveSid
= SeInteractiveSid
;
168 SeExports
->SeLocalSystemSid
= SeLocalSystemSid
;
169 SeExports
->SeAliasAdminsSid
= SeAliasAdminsSid
;
170 SeExports
->SeAliasUsersSid
= SeAliasUsersSid
;
171 SeExports
->SeAliasGuestsSid
= SeAliasGuestsSid
;
172 SeExports
->SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
173 SeExports
->SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
174 SeExports
->SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
175 SeExports
->SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
176 SeExports
->SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
182 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
187 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
197 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
201 BOOLEAN EffectiveOnly
;
203 Thread
= PsGetCurrentThread();
206 SubjectContext
->ProcessAuditId
= 0;
207 SubjectContext
->PrimaryToken
= NULL
;
208 SubjectContext
->ClientToken
= NULL
;
209 SubjectContext
->ImpersonationLevel
= 0;
213 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
214 SubjectContext
->ClientToken
=
215 PsReferenceImpersonationToken(Thread
,
218 &SubjectContext
->ImpersonationLevel
);
219 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
228 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
230 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
238 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
240 ExReleaseResourceLite(&SepSubjectContextLock
);
248 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
250 if (SubjectContext
->PrimaryToken
!= NULL
)
252 ObDereferenceObject(SubjectContext
->PrimaryToken
);
255 if (SubjectContext
->ClientToken
!= NULL
)
257 ObDereferenceObject(SubjectContext
->ClientToken
);
266 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
268 if (*SecurityDescriptor
!= NULL
)
270 ExFreePool(*SecurityDescriptor
);
271 *SecurityDescriptor
= NULL
;
274 return STATUS_SUCCESS
;
282 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
283 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
284 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
285 IN GUID
*ObjectType OPTIONAL
,
286 IN BOOLEAN IsDirectoryObject
,
287 IN ULONG AutoInheritFlags
,
288 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
289 IN PGENERIC_MAPPING GenericMapping
,
290 IN POOL_TYPE PoolType
)
293 return STATUS_NOT_IMPLEMENTED
;
298 * FUNCTION: Creates a security descriptor for a new object.
301 * ExplicitDescriptor =
303 * IsDirectoryObject =
312 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
313 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
314 PSECURITY_DESCRIPTOR
*NewDescriptor
,
315 BOOLEAN IsDirectoryObject
,
316 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
317 PGENERIC_MAPPING GenericMapping
,
320 PSECURITY_DESCRIPTOR Descriptor
;
322 ULONG OwnerLength
= 0;
323 ULONG GroupLength
= 0;
324 ULONG DaclLength
= 0;
325 ULONG SaclLength
= 0;
334 /* Lock subject context */
335 SeLockSubjectContext(SubjectContext
);
337 if (SubjectContext
->ClientToken
!= NULL
)
339 Token
= SubjectContext
->ClientToken
;
343 Token
= SubjectContext
->PrimaryToken
;
347 /* Inherit the Owner SID */
348 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
350 DPRINT("Use explicit owner sid!\n");
351 Owner
= ExplicitDescriptor
->Owner
;
352 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
354 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
361 DPRINT("Use token owner sid!\n");
362 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
366 DPRINT("Use default owner sid!\n");
367 Owner
= SeLocalSystemSid
;
370 Control
|= SE_OWNER_DEFAULTED
;
373 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
376 /* Inherit the Group SID */
377 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
379 DPRINT("Use explicit group sid!\n");
380 Group
= ExplicitDescriptor
->Group
;
381 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
383 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
390 DPRINT("Use token group sid!\n");
391 Group
= Token
->PrimaryGroup
;
395 DPRINT("Use default group sid!\n");
396 Group
= SeLocalSystemSid
;
399 Control
|= SE_OWNER_DEFAULTED
;
402 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
405 /* Inherit the DACL */
406 if (ExplicitDescriptor
!= NULL
&&
407 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
408 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
410 DPRINT("Use explicit DACL!\n");
411 Dacl
= ExplicitDescriptor
->Dacl
;
412 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
414 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
417 Control
|= SE_DACL_PRESENT
;
419 else if (ParentDescriptor
!= NULL
&&
420 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
422 DPRINT("Use parent DACL!\n");
424 Dacl
= ParentDescriptor
->Dacl
;
425 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
427 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
429 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
431 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
433 DPRINT("Use token default DACL!\n");
435 Dacl
= Token
->DefaultDacl
;
436 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
440 DPRINT("Use NULL DACL!\n");
442 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
445 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
448 /* Inherit the SACL */
449 if (ExplicitDescriptor
!= NULL
&&
450 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
451 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
453 DPRINT("Use explicit SACL!\n");
454 Sacl
= ExplicitDescriptor
->Sacl
;
455 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
457 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
460 Control
|= SE_SACL_PRESENT
;
462 else if (ParentDescriptor
!= NULL
&&
463 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
465 DPRINT("Use parent SACL!\n");
467 Sacl
= ParentDescriptor
->Sacl
;
468 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
470 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
472 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
475 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
478 /* Allocate and initialize the new security descriptor */
479 Length
= sizeof(SECURITY_DESCRIPTOR
) +
480 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
482 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
483 sizeof(SECURITY_DESCRIPTOR
),
489 Descriptor
= ExAllocatePool(NonPagedPool
,
491 RtlZeroMemory( Descriptor
, Length
);
493 if (Descriptor
== NULL
)
495 DPRINT1("ExAlloctePool() failed\n");
496 /* FIXME: Unlock subject context */
497 return STATUS_INSUFFICIENT_RESOURCES
;
500 RtlCreateSecurityDescriptor(Descriptor
,
501 SECURITY_DESCRIPTOR_REVISION
);
503 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
505 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
509 RtlCopyMemory((PVOID
)Current
,
512 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
513 Current
+= SaclLength
;
518 RtlCopyMemory((PVOID
)Current
,
521 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
522 Current
+= DaclLength
;
525 if (OwnerLength
!= 0)
527 RtlCopyMemory((PVOID
)Current
,
530 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
531 Current
+= OwnerLength
;
532 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
535 DPRINT("Owner of %x is zero length\n", Descriptor
);
537 if (GroupLength
!= 0)
539 memmove((PVOID
)Current
,
542 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
545 /* Unlock subject context */
546 SeUnlockSubjectContext(SubjectContext
);
548 *NewDescriptor
= Descriptor
;
550 DPRINT("Descrptor %x\n", Descriptor
);
551 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
553 return STATUS_SUCCESS
;
558 SepSidInToken(PACCESS_TOKEN Token
,
563 if (Token
->UserAndGroupCount
== 0)
568 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
570 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
572 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
586 * FUNCTION: Determines whether the requested access rights can be granted
587 * to an object protected by a security descriptor and an object owner
589 * SecurityDescriptor = Security descriptor protecting the object
590 * SubjectSecurityContext = Subject's captured security context
591 * SubjectContextLocked = Indicates the user's subject context is locked
592 * DesiredAccess = Access rights the caller is trying to acquire
593 * PreviouslyGrantedAccess = Specified the access rights already granted
595 * GenericMapping = Generic mapping associated with the object
596 * AccessMode = Access mode used for the check
597 * GrantedAccess (OUT) = On return specifies the access granted
598 * AccessStatus (OUT) = Status indicating why access was denied
599 * RETURNS: If access was granted, returns TRUE
604 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
605 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
606 IN BOOLEAN SubjectContextLocked
,
607 IN ACCESS_MASK DesiredAccess
,
608 IN ACCESS_MASK PreviouslyGrantedAccess
,
609 OUT PPRIVILEGE_SET
* Privileges
,
610 IN PGENERIC_MAPPING GenericMapping
,
611 IN KPROCESSOR_MODE AccessMode
,
612 OUT PACCESS_MASK GrantedAccess
,
613 OUT PNTSTATUS AccessStatus
)
615 LUID_AND_ATTRIBUTES Privilege
;
616 ACCESS_MASK CurrentAccess
;
626 CurrentAccess
= PreviouslyGrantedAccess
;
628 if (SubjectContextLocked
== FALSE
)
630 SeLockSubjectContext(SubjectSecurityContext
);
633 Token
= SubjectSecurityContext
->ClientToken
?
634 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
637 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
641 if (!NT_SUCCESS(Status
))
643 if (SubjectContextLocked
== FALSE
)
645 SeUnlockSubjectContext(SubjectSecurityContext
);
648 *AccessStatus
= Status
;
652 /* RULE 1: Grant desired access if the object is unprotected */
653 if (Present
== TRUE
&& Dacl
== NULL
)
655 if (SubjectContextLocked
== FALSE
)
657 SeUnlockSubjectContext(SubjectSecurityContext
);
660 *GrantedAccess
= DesiredAccess
;
661 *AccessStatus
= STATUS_SUCCESS
;
665 CurrentAccess
= PreviouslyGrantedAccess
;
667 /* RULE 2: Check token for 'take ownership' privilege */
668 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
669 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
671 if (SepPrivilegeCheck(Token
,
674 PRIVILEGE_SET_ALL_NECESSARY
,
677 CurrentAccess
|= WRITE_OWNER
;
678 if (DesiredAccess
== CurrentAccess
)
680 if (SubjectContextLocked
== FALSE
)
682 SeUnlockSubjectContext(SubjectSecurityContext
);
685 *GrantedAccess
= CurrentAccess
;
686 *AccessStatus
= STATUS_SUCCESS
;
691 /* RULE 3: Check whether the token is the owner */
692 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
695 if (!NT_SUCCESS(Status
))
697 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
698 if (SubjectContextLocked
== FALSE
)
700 SeUnlockSubjectContext(SubjectSecurityContext
);
703 *AccessStatus
= Status
;
707 if (SepSidInToken(Token
, Sid
))
709 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
710 if (DesiredAccess
== CurrentAccess
)
712 if (SubjectContextLocked
== FALSE
)
714 SeUnlockSubjectContext(SubjectSecurityContext
);
717 *GrantedAccess
= CurrentAccess
;
718 *AccessStatus
= STATUS_SUCCESS
;
723 /* Fail if DACL is absent */
724 if (Present
== FALSE
)
726 if (SubjectContextLocked
== FALSE
)
728 SeUnlockSubjectContext(SubjectSecurityContext
);
732 *AccessStatus
= STATUS_ACCESS_DENIED
;
736 /* RULE 4: Grant rights according to the DACL */
737 CurrentAce
= (PACE
)(Dacl
+ 1);
738 for (i
= 0; i
< Dacl
->AceCount
; i
++)
740 Sid
= (PSID
)(CurrentAce
+ 1);
741 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
743 if (SepSidInToken(Token
, Sid
))
745 if (SubjectContextLocked
== FALSE
)
747 SeUnlockSubjectContext(SubjectSecurityContext
);
751 *AccessStatus
= STATUS_ACCESS_DENIED
;
756 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
758 if (SepSidInToken(Token
, Sid
))
760 CurrentAccess
|= CurrentAce
->AccessMask
;
765 if (SubjectContextLocked
== FALSE
)
767 SeUnlockSubjectContext(SubjectSecurityContext
);
770 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
771 CurrentAccess
, DesiredAccess
);
773 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
776 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
783 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
784 IN HANDLE TokenHandle
,
785 IN ACCESS_MASK DesiredAccess
,
786 IN PGENERIC_MAPPING GenericMapping
,
787 OUT PPRIVILEGE_SET PrivilegeSet
,
788 OUT PULONG ReturnLength
,
789 OUT PACCESS_MASK GrantedAccess
,
790 OUT PNTSTATUS AccessStatus
)
792 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
793 KPROCESSOR_MODE PreviousMode
;
797 DPRINT("NtAccessCheck() called\n");
799 PreviousMode
= KeGetPreviousMode();
800 if (PreviousMode
== KernelMode
)
802 *GrantedAccess
= DesiredAccess
;
803 *AccessStatus
= STATUS_SUCCESS
;
804 return STATUS_SUCCESS
;
807 Status
= ObReferenceObjectByHandle(TokenHandle
,
813 if (!NT_SUCCESS(Status
))
815 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
819 /* Check token type */
820 if (Token
->TokenType
!= TokenImpersonation
)
822 DPRINT1("No impersonation token\n");
823 ObDereferenceObject(Token
);
824 return STATUS_ACCESS_VIOLATION
;
827 /* Check impersonation level */
828 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
830 DPRINT1("Invalid impersonation level\n");
831 ObDereferenceObject(Token
);
832 return STATUS_ACCESS_VIOLATION
;
835 RtlZeroMemory(&SubjectSecurityContext
,
836 sizeof(SECURITY_SUBJECT_CONTEXT
));
837 SubjectSecurityContext
.ClientToken
= Token
;
838 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
840 /* Lock subject context */
841 SeLockSubjectContext(&SubjectSecurityContext
);
843 if (SeAccessCheck(SecurityDescriptor
,
844 &SubjectSecurityContext
,
854 Status
= *AccessStatus
;
858 Status
= STATUS_ACCESS_DENIED
;
861 /* Unlock subject context */
862 SeUnlockSubjectContext(&SubjectSecurityContext
);
864 ObDereferenceObject(Token
);
866 DPRINT("NtAccessCheck() done\n");