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 /* GLOBALS ******************************************************************/
19 PSE_EXPORTS EXPORTED SeExports
= NULL
;
20 SE_EXPORTS SepExports
;
22 static ERESOURCE SepSubjectContextLock
;
25 /* PROTOTYPES ***************************************************************/
27 static BOOLEAN
SepInitExports(VOID
);
30 /* FUNCTIONS ****************************************************************/
37 if (!SepInitSecurityIDs())
48 if (!SepInitExports())
51 /* Initialize the subject context lock */
52 ExInitializeResource(&SepSubjectContextLock
);
61 SepInitializeTokenImplementation();
70 OBJECT_ATTRIBUTES ObjectAttributes
;
72 HANDLE DirectoryHandle
;
76 /* Create '\Security' directory */
77 RtlInitUnicodeString(&Name
,
79 InitializeObjectAttributes(&ObjectAttributes
,
84 Status
= ZwCreateDirectoryObject(&DirectoryHandle
,
87 if (!NT_SUCCESS(Status
))
89 DPRINT1("Failed to create 'Security' directory!\n");
93 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
94 RtlInitUnicodeString(&Name
,
95 L
"\\LSA_AUTHENTICATION_INITALIZED");
96 InitializeObjectAttributes(&ObjectAttributes
,
101 Status
= ZwCreateEvent(&EventHandle
,
104 SynchronizationEvent
,
106 if (!NT_SUCCESS(Status
))
108 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
109 NtClose(DirectoryHandle
);
113 ZwClose(EventHandle
);
114 ZwClose(DirectoryHandle
);
116 /* FIXME: Create SRM port and listener thread */
122 static BOOLEAN INIT_FUNCTION
125 SepExports
.SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
126 SepExports
.SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
127 SepExports
.SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
128 SepExports
.SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
129 SepExports
.SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
130 SepExports
.SeTcbPrivilege
= SeTcbPrivilege
;
131 SepExports
.SeSecurityPrivilege
= SeSecurityPrivilege
;
132 SepExports
.SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
133 SepExports
.SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
134 SepExports
.SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
135 SepExports
.SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
136 SepExports
.SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
137 SepExports
.SeSystemtimePrivilege
= SeSystemtimePrivilege
;
138 SepExports
.SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
139 SepExports
.SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
140 SepExports
.SeBackupPrivilege
= SeBackupPrivilege
;
141 SepExports
.SeRestorePrivilege
= SeRestorePrivilege
;
142 SepExports
.SeShutdownPrivilege
= SeShutdownPrivilege
;
143 SepExports
.SeDebugPrivilege
= SeDebugPrivilege
;
144 SepExports
.SeAuditPrivilege
= SeAuditPrivilege
;
145 SepExports
.SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
146 SepExports
.SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
147 SepExports
.SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
149 SepExports
.SeNullSid
= SeNullSid
;
150 SepExports
.SeWorldSid
= SeWorldSid
;
151 SepExports
.SeLocalSid
= SeLocalSid
;
152 SepExports
.SeCreatorOwnerSid
= SeCreatorOwnerSid
;
153 SepExports
.SeCreatorGroupSid
= SeCreatorGroupSid
;
154 SepExports
.SeNtAuthoritySid
= SeNtAuthoritySid
;
155 SepExports
.SeDialupSid
= SeDialupSid
;
156 SepExports
.SeNetworkSid
= SeNetworkSid
;
157 SepExports
.SeBatchSid
= SeBatchSid
;
158 SepExports
.SeInteractiveSid
= SeInteractiveSid
;
159 SepExports
.SeLocalSystemSid
= SeLocalSystemSid
;
160 SepExports
.SeAliasAdminsSid
= SeAliasAdminsSid
;
161 SepExports
.SeAliasUsersSid
= SeAliasUsersSid
;
162 SepExports
.SeAliasGuestsSid
= SeAliasGuestsSid
;
163 SepExports
.SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
164 SepExports
.SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
165 SepExports
.SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
166 SepExports
.SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
167 SepExports
.SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
169 SeExports
= &SepExports
;
174 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
179 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
189 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
193 BOOLEAN EffectiveOnly
;
197 Thread
= PsGetCurrentThread();
200 SubjectContext
->ProcessAuditId
= 0;
201 SubjectContext
->PrimaryToken
= NULL
;
202 SubjectContext
->ClientToken
= NULL
;
203 SubjectContext
->ImpersonationLevel
= 0;
207 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
208 SubjectContext
->ClientToken
=
209 PsReferenceImpersonationToken(Thread
,
212 &SubjectContext
->ImpersonationLevel
);
213 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
222 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
226 KeEnterCriticalRegion();
227 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
235 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
239 ExReleaseResourceLite(&SepSubjectContextLock
);
240 KeLeaveCriticalRegion();
248 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
252 if (SubjectContext
->PrimaryToken
!= NULL
)
254 ObDereferenceObject(SubjectContext
->PrimaryToken
);
257 if (SubjectContext
->ClientToken
!= NULL
)
259 ObDereferenceObject(SubjectContext
->ClientToken
);
268 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
272 if (*SecurityDescriptor
!= NULL
)
274 ExFreePool(*SecurityDescriptor
);
275 *SecurityDescriptor
= NULL
;
278 return STATUS_SUCCESS
;
286 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
287 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
288 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
289 IN GUID
*ObjectType OPTIONAL
,
290 IN BOOLEAN IsDirectoryObject
,
291 IN ULONG AutoInheritFlags
,
292 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
293 IN PGENERIC_MAPPING GenericMapping
,
294 IN POOL_TYPE PoolType
)
297 return STATUS_NOT_IMPLEMENTED
;
302 * FUNCTION: Creates a security descriptor for a new object.
305 * ExplicitDescriptor =
307 * IsDirectoryObject =
316 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
317 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
318 PSECURITY_DESCRIPTOR
*NewDescriptor
,
319 BOOLEAN IsDirectoryObject
,
320 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
321 PGENERIC_MAPPING GenericMapping
,
324 PSECURITY_DESCRIPTOR Descriptor
;
326 ULONG OwnerLength
= 0;
327 ULONG GroupLength
= 0;
328 ULONG DaclLength
= 0;
329 ULONG SaclLength
= 0;
340 /* Lock subject context */
341 SeLockSubjectContext(SubjectContext
);
343 if (SubjectContext
->ClientToken
!= NULL
)
345 Token
= SubjectContext
->ClientToken
;
349 Token
= SubjectContext
->PrimaryToken
;
353 /* Inherit the Owner SID */
354 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
356 DPRINT("Use explicit owner sid!\n");
357 Owner
= ExplicitDescriptor
->Owner
;
359 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
361 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
369 DPRINT("Use token owner sid!\n");
370 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
374 DPRINT("Use default owner sid!\n");
375 Owner
= SeLocalSystemSid
;
378 Control
|= SE_OWNER_DEFAULTED
;
381 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
384 /* Inherit the Group SID */
385 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
387 DPRINT("Use explicit group sid!\n");
388 Group
= ExplicitDescriptor
->Group
;
389 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
391 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
398 DPRINT("Use token group sid!\n");
399 Group
= Token
->PrimaryGroup
;
403 DPRINT("Use default group sid!\n");
404 Group
= SeLocalSystemSid
;
407 Control
|= SE_OWNER_DEFAULTED
;
410 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
413 /* Inherit the DACL */
414 if (ExplicitDescriptor
!= NULL
&&
415 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
416 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
418 DPRINT("Use explicit DACL!\n");
419 Dacl
= ExplicitDescriptor
->Dacl
;
420 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
422 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
425 Control
|= SE_DACL_PRESENT
;
427 else if (ParentDescriptor
!= NULL
&&
428 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
430 DPRINT("Use parent DACL!\n");
432 Dacl
= ParentDescriptor
->Dacl
;
433 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
435 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
437 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
439 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
441 DPRINT("Use token default DACL!\n");
443 Dacl
= Token
->DefaultDacl
;
444 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
448 DPRINT("Use NULL DACL!\n");
450 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
453 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
456 /* Inherit the SACL */
457 if (ExplicitDescriptor
!= NULL
&&
458 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
459 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
461 DPRINT("Use explicit SACL!\n");
462 Sacl
= ExplicitDescriptor
->Sacl
;
463 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
465 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
468 Control
|= SE_SACL_PRESENT
;
470 else if (ParentDescriptor
!= NULL
&&
471 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
473 DPRINT("Use parent SACL!\n");
475 Sacl
= ParentDescriptor
->Sacl
;
476 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
478 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
480 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
483 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
486 /* Allocate and initialize the new security descriptor */
487 Length
= sizeof(SECURITY_DESCRIPTOR
) +
488 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
490 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
491 sizeof(SECURITY_DESCRIPTOR
),
497 Descriptor
= ExAllocatePool(PagedPool
,
499 RtlZeroMemory( Descriptor
, Length
);
501 if (Descriptor
== NULL
)
503 DPRINT1("ExAlloctePool() failed\n");
504 /* FIXME: Unlock subject context */
505 return STATUS_INSUFFICIENT_RESOURCES
;
508 RtlCreateSecurityDescriptor(Descriptor
,
509 SECURITY_DESCRIPTOR_REVISION
);
511 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
513 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
517 RtlCopyMemory((PVOID
)Current
,
520 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
521 Current
+= SaclLength
;
526 RtlCopyMemory((PVOID
)Current
,
529 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
530 Current
+= DaclLength
;
533 if (OwnerLength
!= 0)
535 RtlCopyMemory((PVOID
)Current
,
538 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
539 Current
+= OwnerLength
;
540 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
543 DPRINT("Owner of %x is zero length\n", Descriptor
);
545 if (GroupLength
!= 0)
547 memmove((PVOID
)Current
,
550 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
553 /* Unlock subject context */
554 SeUnlockSubjectContext(SubjectContext
);
556 *NewDescriptor
= Descriptor
;
558 DPRINT("Descrptor %x\n", Descriptor
);
559 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
561 return STATUS_SUCCESS
;
566 SepSidInToken(PACCESS_TOKEN _Token
,
570 PTOKEN Token
= (PTOKEN
)_Token
;
574 if (Token
->UserAndGroupCount
== 0)
579 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
581 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
583 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
597 * FUNCTION: Determines whether the requested access rights can be granted
598 * to an object protected by a security descriptor and an object owner
600 * SecurityDescriptor = Security descriptor protecting the object
601 * SubjectSecurityContext = Subject's captured security context
602 * SubjectContextLocked = Indicates the user's subject context is locked
603 * DesiredAccess = Access rights the caller is trying to acquire
604 * PreviouslyGrantedAccess = Specified the access rights already granted
606 * GenericMapping = Generic mapping associated with the object
607 * AccessMode = Access mode used for the check
608 * GrantedAccess (OUT) = On return specifies the access granted
609 * AccessStatus (OUT) = Status indicating why access was denied
610 * RETURNS: If access was granted, returns TRUE
615 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
616 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
617 IN BOOLEAN SubjectContextLocked
,
618 IN ACCESS_MASK DesiredAccess
,
619 IN ACCESS_MASK PreviouslyGrantedAccess
,
620 OUT PPRIVILEGE_SET
* Privileges
,
621 IN PGENERIC_MAPPING GenericMapping
,
622 IN KPROCESSOR_MODE AccessMode
,
623 OUT PACCESS_MASK GrantedAccess
,
624 OUT PNTSTATUS AccessStatus
)
626 LUID_AND_ATTRIBUTES Privilege
;
627 ACCESS_MASK CurrentAccess
;
639 CurrentAccess
= PreviouslyGrantedAccess
;
641 if (SubjectContextLocked
== FALSE
)
643 SeLockSubjectContext(SubjectSecurityContext
);
646 Token
= SubjectSecurityContext
->ClientToken
?
647 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
650 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
654 if (!NT_SUCCESS(Status
))
656 if (SubjectContextLocked
== FALSE
)
658 SeUnlockSubjectContext(SubjectSecurityContext
);
661 *AccessStatus
= Status
;
665 /* RULE 1: Grant desired access if the object is unprotected */
666 if (Present
== TRUE
&& Dacl
== NULL
)
668 if (SubjectContextLocked
== FALSE
)
670 SeUnlockSubjectContext(SubjectSecurityContext
);
673 *GrantedAccess
= DesiredAccess
;
674 *AccessStatus
= STATUS_SUCCESS
;
678 CurrentAccess
= PreviouslyGrantedAccess
;
680 /* RULE 2: Check token for 'take ownership' privilege */
681 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
682 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
684 if (SepPrivilegeCheck(Token
,
687 PRIVILEGE_SET_ALL_NECESSARY
,
690 CurrentAccess
|= WRITE_OWNER
;
691 if (DesiredAccess
== CurrentAccess
)
693 if (SubjectContextLocked
== FALSE
)
695 SeUnlockSubjectContext(SubjectSecurityContext
);
698 *GrantedAccess
= CurrentAccess
;
699 *AccessStatus
= STATUS_SUCCESS
;
704 /* RULE 3: Check whether the token is the owner */
705 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
708 if (!NT_SUCCESS(Status
))
710 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
711 if (SubjectContextLocked
== FALSE
)
713 SeUnlockSubjectContext(SubjectSecurityContext
);
716 *AccessStatus
= Status
;
720 if (SepSidInToken(Token
, Sid
))
722 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
723 if (DesiredAccess
== CurrentAccess
)
725 if (SubjectContextLocked
== FALSE
)
727 SeUnlockSubjectContext(SubjectSecurityContext
);
730 *GrantedAccess
= CurrentAccess
;
731 *AccessStatus
= STATUS_SUCCESS
;
736 /* Fail if DACL is absent */
737 if (Present
== FALSE
)
739 if (SubjectContextLocked
== FALSE
)
741 SeUnlockSubjectContext(SubjectSecurityContext
);
745 *AccessStatus
= STATUS_ACCESS_DENIED
;
749 /* RULE 4: Grant rights according to the DACL */
750 CurrentAce
= (PACE
)(Dacl
+ 1);
751 for (i
= 0; i
< Dacl
->AceCount
; i
++)
753 Sid
= (PSID
)(CurrentAce
+ 1);
754 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
756 if (SepSidInToken(Token
, Sid
))
758 if (SubjectContextLocked
== FALSE
)
760 SeUnlockSubjectContext(SubjectSecurityContext
);
764 *AccessStatus
= STATUS_ACCESS_DENIED
;
769 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
771 if (SepSidInToken(Token
, Sid
))
773 CurrentAccess
|= CurrentAce
->AccessMask
;
778 if (SubjectContextLocked
== FALSE
)
780 SeUnlockSubjectContext(SubjectSecurityContext
);
783 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
784 CurrentAccess
, DesiredAccess
);
786 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
789 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
796 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
797 IN HANDLE TokenHandle
,
798 IN ACCESS_MASK DesiredAccess
,
799 IN PGENERIC_MAPPING GenericMapping
,
800 OUT PPRIVILEGE_SET PrivilegeSet
,
801 OUT PULONG ReturnLength
,
802 OUT PACCESS_MASK GrantedAccess
,
803 OUT PNTSTATUS AccessStatus
)
805 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
806 KPROCESSOR_MODE PreviousMode
;
812 DPRINT("NtAccessCheck() called\n");
814 PreviousMode
= KeGetPreviousMode();
815 if (PreviousMode
== KernelMode
)
817 *GrantedAccess
= DesiredAccess
;
818 *AccessStatus
= STATUS_SUCCESS
;
819 return STATUS_SUCCESS
;
822 Status
= ObReferenceObjectByHandle(TokenHandle
,
828 if (!NT_SUCCESS(Status
))
830 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
834 /* Check token type */
835 if (Token
->TokenType
!= TokenImpersonation
)
837 DPRINT1("No impersonation token\n");
838 ObDereferenceObject(Token
);
839 return STATUS_ACCESS_VIOLATION
;
842 /* Check impersonation level */
843 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
845 DPRINT1("Invalid impersonation level\n");
846 ObDereferenceObject(Token
);
847 return STATUS_ACCESS_VIOLATION
;
850 RtlZeroMemory(&SubjectSecurityContext
,
851 sizeof(SECURITY_SUBJECT_CONTEXT
));
852 SubjectSecurityContext
.ClientToken
= Token
;
853 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
855 /* Lock subject context */
856 SeLockSubjectContext(&SubjectSecurityContext
);
858 if (SeAccessCheck(SecurityDescriptor
,
859 &SubjectSecurityContext
,
869 Status
= *AccessStatus
;
873 Status
= STATUS_ACCESS_DENIED
;
876 /* Unlock subject context */
877 SeUnlockSubjectContext(&SubjectSecurityContext
);
879 ObDereferenceObject(Token
);
881 DPRINT("NtAccessCheck() done\n");