2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/semgr.c
5 * PURPOSE: Security manager
7 * PROGRAMMERS: No programmer listed.
10 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 PSE_EXPORTS SeExports
= NULL
;
19 SE_EXPORTS SepExports
;
20 ULONG SidInTokenCalls
= 0;
22 extern ULONG ExpInitializationPhase
;
23 extern ERESOURCE SepSubjectContextLock
;
25 /* PRIVATE FUNCTIONS **********************************************************/
31 SepExports
.SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
32 SepExports
.SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
33 SepExports
.SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
34 SepExports
.SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
35 SepExports
.SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
36 SepExports
.SeTcbPrivilege
= SeTcbPrivilege
;
37 SepExports
.SeSecurityPrivilege
= SeSecurityPrivilege
;
38 SepExports
.SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
39 SepExports
.SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
40 SepExports
.SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
41 SepExports
.SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
42 SepExports
.SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
43 SepExports
.SeSystemtimePrivilege
= SeSystemtimePrivilege
;
44 SepExports
.SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
45 SepExports
.SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
46 SepExports
.SeBackupPrivilege
= SeBackupPrivilege
;
47 SepExports
.SeRestorePrivilege
= SeRestorePrivilege
;
48 SepExports
.SeShutdownPrivilege
= SeShutdownPrivilege
;
49 SepExports
.SeDebugPrivilege
= SeDebugPrivilege
;
50 SepExports
.SeAuditPrivilege
= SeAuditPrivilege
;
51 SepExports
.SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
52 SepExports
.SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
53 SepExports
.SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
55 SepExports
.SeNullSid
= SeNullSid
;
56 SepExports
.SeWorldSid
= SeWorldSid
;
57 SepExports
.SeLocalSid
= SeLocalSid
;
58 SepExports
.SeCreatorOwnerSid
= SeCreatorOwnerSid
;
59 SepExports
.SeCreatorGroupSid
= SeCreatorGroupSid
;
60 SepExports
.SeNtAuthoritySid
= SeNtAuthoritySid
;
61 SepExports
.SeDialupSid
= SeDialupSid
;
62 SepExports
.SeNetworkSid
= SeNetworkSid
;
63 SepExports
.SeBatchSid
= SeBatchSid
;
64 SepExports
.SeInteractiveSid
= SeInteractiveSid
;
65 SepExports
.SeLocalSystemSid
= SeLocalSystemSid
;
66 SepExports
.SeAliasAdminsSid
= SeAliasAdminsSid
;
67 SepExports
.SeAliasUsersSid
= SeAliasUsersSid
;
68 SepExports
.SeAliasGuestsSid
= SeAliasGuestsSid
;
69 SepExports
.SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
70 SepExports
.SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
71 SepExports
.SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
72 SepExports
.SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
73 SepExports
.SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
74 SepExports
.SeAuthenticatedUsersSid
= SeAuthenticatedUsersSid
;
75 SepExports
.SeRestrictedSid
= SeRestrictedSid
;
76 SepExports
.SeAnonymousLogonSid
= SeAnonymousLogonSid
;
78 SepExports
.SeUndockPrivilege
= SeUndockPrivilege
;
79 SepExports
.SeSyncAgentPrivilege
= SeSyncAgentPrivilege
;
80 SepExports
.SeEnableDelegationPrivilege
= SeEnableDelegationPrivilege
;
82 SeExports
= &SepExports
;
90 SepInitializationPhase0(VOID
)
95 if (!SepInitSecurityIDs()) return FALSE
;
96 if (!SepInitDACLs()) return FALSE
;
97 if (!SepInitSDs()) return FALSE
;
99 if (!SepInitExports()) return FALSE
;
101 /* Initialize the subject context lock */
102 ExInitializeResource(&SepSubjectContextLock
);
104 /* Initialize token objects */
105 SepInitializeTokenImplementation();
107 /* Clear impersonation info for the idle thread */
108 PsGetCurrentThread()->ImpersonationInfo
= NULL
;
109 PspClearCrossThreadFlag(PsGetCurrentThread(),
110 CT_ACTIVE_IMPERSONATION_INFO_BIT
);
112 /* Initialize the boot token */
113 ObInitializeFastReference(&PsGetCurrentProcess()->Token
, NULL
);
114 ObInitializeFastReference(&PsGetCurrentProcess()->Token
,
115 SepCreateSystemProcessToken());
122 SepInitializationPhase1(VOID
)
128 /* Insert the system token into the tree */
129 Status
= ObInsertObject((PVOID
)(PsGetCurrentProcess()->Token
.Value
&
136 ASSERT(NT_SUCCESS(Status
));
138 /* FIXME: TODO \\ Security directory */
147 /* Check the initialization phase */
148 switch (ExpInitializationPhase
)
153 return SepInitializationPhase0();
158 return SepInitializationPhase1();
162 /* Don't know any other phase! Bugcheck! */
163 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL
,
165 ExpInitializationPhase
,
177 OBJECT_ATTRIBUTES ObjectAttributes
;
179 HANDLE DirectoryHandle
;
183 /* Create '\Security' directory */
184 RtlInitUnicodeString(&Name
,
186 InitializeObjectAttributes(&ObjectAttributes
,
191 Status
= ZwCreateDirectoryObject(&DirectoryHandle
,
192 DIRECTORY_ALL_ACCESS
,
194 if (!NT_SUCCESS(Status
))
196 DPRINT1("Failed to create 'Security' directory!\n");
200 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
201 RtlInitUnicodeString(&Name
,
202 L
"\\LSA_AUTHENTICATION_INITALIZED");
203 InitializeObjectAttributes(&ObjectAttributes
,
208 Status
= ZwCreateEvent(&EventHandle
,
211 SynchronizationEvent
,
213 if (!NT_SUCCESS(Status
))
215 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
216 NtClose(DirectoryHandle
);
220 ZwClose(EventHandle
);
221 ZwClose(DirectoryHandle
);
223 /* FIXME: Create SRM port and listener thread */
230 SeDefaultObjectMethod(IN PVOID Object
,
231 IN SECURITY_OPERATION_CODE OperationType
,
232 IN PSECURITY_INFORMATION SecurityInformation
,
233 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
234 IN OUT PULONG ReturnLength OPTIONAL
,
235 IN OUT PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
236 IN POOL_TYPE PoolType
,
237 IN PGENERIC_MAPPING GenericMapping
)
241 /* Select the operation type */
242 switch (OperationType
)
244 /* Setting a new descriptor */
245 case SetSecurityDescriptor
:
248 ASSERT((PoolType
== PagedPool
) || (PoolType
== NonPagedPool
));
250 /* Set the information */
251 return ObSetSecurityDescriptorInfo(Object
,
254 OldSecurityDescriptor
,
258 case QuerySecurityDescriptor
:
260 /* Query the information */
261 return ObQuerySecurityDescriptorInfo(Object
,
265 OldSecurityDescriptor
);
267 case DeleteSecurityDescriptor
:
270 return ObDeassignSecurity(OldSecurityDescriptor
);
272 case AssignSecurityDescriptor
:
275 ObAssignObjectSecurityDescriptor(Object
, SecurityDescriptor
, PoolType
);
276 return STATUS_SUCCESS
;
281 KeBugCheckEx(SECURITY_SYSTEM
, 0, STATUS_INVALID_PARAMETER
, 0, 0);
284 /* Should never reach here */
286 return STATUS_SUCCESS
;
291 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
292 OUT PACCESS_MASK DesiredAccess
)
296 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
|
297 GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
299 *DesiredAccess
|= READ_CONTROL
;
302 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
304 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
310 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
311 OUT PACCESS_MASK DesiredAccess
)
315 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
317 *DesiredAccess
|= WRITE_OWNER
;
320 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
322 *DesiredAccess
|= WRITE_DAC
;
325 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
327 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
332 #define OLD_ACCESS_CHECK
335 SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
336 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
337 IN ACCESS_MASK DesiredAccess
,
338 IN ACCESS_MASK PreviouslyGrantedAccess
,
339 OUT PPRIVILEGE_SET
* Privileges
,
340 IN PGENERIC_MAPPING GenericMapping
,
341 IN KPROCESSOR_MODE AccessMode
,
342 OUT PACCESS_MASK GrantedAccess
,
343 OUT PNTSTATUS AccessStatus
)
345 LUID_AND_ATTRIBUTES Privilege
;
346 #ifdef OLD_ACCESS_CHECK
347 ACCESS_MASK CurrentAccess
, AccessMask
;
349 ACCESS_MASK RemainingAccess
;
350 ACCESS_MASK TempAccess
;
351 ACCESS_MASK TempGrantedAccess
= 0;
352 ACCESS_MASK TempDeniedAccess
= 0;
363 /* Check for no access desired */
366 /* Check if we had no previous access */
367 if (!PreviouslyGrantedAccess
)
369 /* Then there's nothing to give */
370 *AccessStatus
= STATUS_ACCESS_DENIED
;
374 /* Return the previous access only */
375 *GrantedAccess
= PreviouslyGrantedAccess
;
376 *AccessStatus
= STATUS_SUCCESS
;
381 /* Map given accesses */
382 RtlMapGenericMask(&DesiredAccess
, GenericMapping
);
383 if (PreviouslyGrantedAccess
)
384 RtlMapGenericMask(&PreviouslyGrantedAccess
, GenericMapping
);
386 #ifdef OLD_ACCESS_CHECK
387 CurrentAccess
= PreviouslyGrantedAccess
;
389 /* Initialize remaining access rights */
390 RemainingAccess
= DesiredAccess
;
392 Token
= SubjectSecurityContext
->ClientToken
?
393 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
395 /* Check for system security access */
396 if (RemainingAccess
& ACCESS_SYSTEM_SECURITY
)
398 Privilege
.Luid
= SeSecurityPrivilege
;
399 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
401 /* Fail if we do not the SeSecurityPrivilege */
402 if (!SepPrivilegeCheck(Token
,
405 PRIVILEGE_SET_ALL_NECESSARY
,
408 *AccessStatus
= STATUS_PRIVILEGE_NOT_HELD
;
412 /* Adjust access rights */
413 RemainingAccess
&= ~ACCESS_SYSTEM_SECURITY
;
414 PreviouslyGrantedAccess
|= ACCESS_SYSTEM_SECURITY
;
416 /* Succeed if there are no more rights to grant */
417 if (RemainingAccess
== 0)
419 *GrantedAccess
= PreviouslyGrantedAccess
;
420 *AccessStatus
= STATUS_SUCCESS
;
426 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
430 if (!NT_SUCCESS(Status
))
432 *AccessStatus
= Status
;
436 /* RULE 1: Grant desired access if the object is unprotected */
437 if (Present
== FALSE
|| Dacl
== NULL
)
439 if (DesiredAccess
& MAXIMUM_ALLOWED
)
441 *GrantedAccess
= GenericMapping
->GenericAll
;
442 *GrantedAccess
|= (DesiredAccess
& ~MAXIMUM_ALLOWED
);
446 *GrantedAccess
= DesiredAccess
| PreviouslyGrantedAccess
;
449 *AccessStatus
= STATUS_SUCCESS
;
453 #ifdef OLD_ACCESS_CHECK
454 CurrentAccess
= PreviouslyGrantedAccess
;
457 /* RULE 2: Check token for 'take ownership' privilege */
458 if (DesiredAccess
& WRITE_OWNER
)
460 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
461 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
463 if (SepPrivilegeCheck(Token
,
466 PRIVILEGE_SET_ALL_NECESSARY
,
469 /* Adjust access rights */
470 RemainingAccess
&= ~WRITE_OWNER
;
471 PreviouslyGrantedAccess
|= WRITE_OWNER
;
472 #ifdef OLD_ACCESS_CHECK
473 CurrentAccess
|= WRITE_OWNER
;
476 /* Succeed if there are no more rights to grant */
477 if (RemainingAccess
== 0)
479 *GrantedAccess
= PreviouslyGrantedAccess
;
480 *AccessStatus
= STATUS_SUCCESS
;
486 /* Deny access if the DACL is empty */
487 if (Dacl
->AceCount
== 0)
489 if (RemainingAccess
== MAXIMUM_ALLOWED
&& PreviouslyGrantedAccess
!= 0)
491 *GrantedAccess
= PreviouslyGrantedAccess
;
492 *AccessStatus
= STATUS_SUCCESS
;
498 *AccessStatus
= STATUS_ACCESS_DENIED
;
503 /* Fail if DACL is absent */
504 if (Present
== FALSE
)
507 *AccessStatus
= STATUS_ACCESS_DENIED
;
511 /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
512 if (DesiredAccess
& MAXIMUM_ALLOWED
)
514 CurrentAce
= (PACE
)(Dacl
+ 1);
515 for (i
= 0; i
< Dacl
->AceCount
; i
++)
517 if (!(CurrentAce
->Header
.AceFlags
& INHERIT_ONLY_ACE
))
519 Sid
= (PSID
)(CurrentAce
+ 1);
520 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
522 if (SepSidInToken(Token
, Sid
))
524 /* Map access rights from the ACE */
525 TempAccess
= CurrentAce
->AccessMask
;
526 RtlMapGenericMask(&TempAccess
, GenericMapping
);
528 /* Deny access rights that have not been granted yet */
529 TempDeniedAccess
|= (TempAccess
& ~TempGrantedAccess
);
532 else if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
534 if (SepSidInToken(Token
, Sid
))
536 /* Map access rights from the ACE */
537 TempAccess
= CurrentAce
->AccessMask
;
538 RtlMapGenericMask(&TempAccess
, GenericMapping
);
540 /* Grant access rights that have not been denied yet */
541 TempGrantedAccess
|= (TempAccess
& ~TempDeniedAccess
);
546 DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce
->Header
.AceType
);
550 /* Get the next ACE */
551 CurrentAce
= (PACE
)((ULONG_PTR
)CurrentAce
+ CurrentAce
->Header
.AceSize
);
554 /* Fail if some rights have not been granted */
555 RemainingAccess
&= ~(MAXIMUM_ALLOWED
| TempGrantedAccess
);
556 if (RemainingAccess
!= 0)
559 *AccessStatus
= STATUS_ACCESS_DENIED
;
563 /* Set granted access right and access status */
564 *GrantedAccess
= TempGrantedAccess
| PreviouslyGrantedAccess
;
565 if (*GrantedAccess
!= 0)
567 *AccessStatus
= STATUS_SUCCESS
;
572 *AccessStatus
= STATUS_ACCESS_DENIED
;
577 /* RULE 4: Grant rights according to the DACL */
578 CurrentAce
= (PACE
)(Dacl
+ 1);
579 for (i
= 0; i
< Dacl
->AceCount
; i
++)
581 if (!(CurrentAce
->Header
.AceFlags
& INHERIT_ONLY_ACE
))
583 Sid
= (PSID
)(CurrentAce
+ 1);
584 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
586 if (SepSidInToken(Token
, Sid
))
588 #ifdef OLD_ACCESS_CHECK
590 *AccessStatus
= STATUS_ACCESS_DENIED
;
593 /* Map access rights from the ACE */
594 TempAccess
= CurrentAce
->AccessMask
;
595 RtlMapGenericMask(&TempAccess
, GenericMapping
);
597 /* Leave if a remaining right must be denied */
598 if (RemainingAccess
& TempAccess
)
603 else if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
605 if (SepSidInToken(Token
, Sid
))
607 #ifdef OLD_ACCESS_CHECK
608 AccessMask
= CurrentAce
->AccessMask
;
609 RtlMapGenericMask(&AccessMask
, GenericMapping
);
610 CurrentAccess
|= AccessMask
;
612 /* Map access rights from the ACE */
613 TempAccess
= CurrentAce
->AccessMask
;
614 RtlMapGenericMask(&TempAccess
, GenericMapping
);
616 /* Remove granted rights */
617 RemainingAccess
&= ~TempAccess
;
623 DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce
->Header
.AceType
);
627 /* Get the next ACE */
628 CurrentAce
= (PACE
)((ULONG_PTR
)CurrentAce
+ CurrentAce
->Header
.AceSize
);
631 #ifdef OLD_ACCESS_CHECK
632 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
633 CurrentAccess
, DesiredAccess
);
635 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
637 if ((*GrantedAccess
& ~VALID_INHERIT_FLAGS
) ==
638 (DesiredAccess
& ~VALID_INHERIT_FLAGS
))
640 *AccessStatus
= STATUS_SUCCESS
;
645 DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n",
646 *GrantedAccess
, DesiredAccess
, GenericMapping
);
647 //*AccessStatus = STATUS_ACCESS_DENIED;
649 *GrantedAccess
= DesiredAccess
;
650 *AccessStatus
= STATUS_SUCCESS
;
654 DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n",
655 DesiredAccess
, PreviouslyGrantedAccess
, RemainingAccess
);
657 /* Fail if some rights have not been granted */
658 if (RemainingAccess
!= 0)
661 *AccessStatus
= STATUS_ACCESS_DENIED
;
665 /* Set granted access rights */
666 *GrantedAccess
= DesiredAccess
| PreviouslyGrantedAccess
;
668 DPRINT("GrantedAccess %08lx\n", *GrantedAccess
);
670 /* Fail if no rights have been granted */
671 if (*GrantedAccess
== 0)
673 *AccessStatus
= STATUS_ACCESS_DENIED
;
677 *AccessStatus
= STATUS_SUCCESS
;
683 SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
685 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
688 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
689 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
690 (ULONG_PTR
)SecurityDescriptor
);
692 Owner
= (PSID
)SecurityDescriptor
->Owner
;
698 SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
700 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
703 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
704 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
705 (ULONG_PTR
)SecurityDescriptor
);
707 Group
= (PSID
)SecurityDescriptor
->Group
;
713 /* PUBLIC FUNCTIONS ***********************************************************/
720 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
721 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
722 IN BOOLEAN SubjectContextLocked
,
723 IN ACCESS_MASK DesiredAccess
,
724 IN ACCESS_MASK PreviouslyGrantedAccess
,
725 OUT PPRIVILEGE_SET
* Privileges
,
726 IN PGENERIC_MAPPING GenericMapping
,
727 IN KPROCESSOR_MODE AccessMode
,
728 OUT PACCESS_MASK GrantedAccess
,
729 OUT PNTSTATUS AccessStatus
)
735 /* Check if this is kernel mode */
736 if (AccessMode
== KernelMode
)
738 /* Check if kernel wants everything */
739 if (DesiredAccess
& MAXIMUM_ALLOWED
)
742 *GrantedAccess
= GenericMapping
->GenericAll
;
743 *GrantedAccess
|= (DesiredAccess
&~ MAXIMUM_ALLOWED
);
744 *GrantedAccess
|= PreviouslyGrantedAccess
;
748 /* Give the desired and previous access */
749 *GrantedAccess
= DesiredAccess
| PreviouslyGrantedAccess
;
753 *AccessStatus
= STATUS_SUCCESS
;
757 /* Check if we didn't get an SD */
758 if (!SecurityDescriptor
)
760 /* Automatic failure */
761 *AccessStatus
= STATUS_ACCESS_DENIED
;
765 /* Check for invalid impersonation */
766 if ((SubjectSecurityContext
->ClientToken
) &&
767 (SubjectSecurityContext
->ImpersonationLevel
< SecurityImpersonation
))
769 *AccessStatus
= STATUS_BAD_IMPERSONATION_LEVEL
;
773 /* Acquire the lock if needed */
774 if (!SubjectContextLocked
)
775 SeLockSubjectContext(SubjectSecurityContext
);
777 /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
778 if (DesiredAccess
& (WRITE_DAC
| READ_CONTROL
| MAXIMUM_ALLOWED
))
780 PACCESS_TOKEN Token
= SubjectSecurityContext
->ClientToken
?
781 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
783 if (SepTokenIsOwner(Token
,
787 if (DesiredAccess
& MAXIMUM_ALLOWED
)
788 PreviouslyGrantedAccess
|= (WRITE_DAC
| READ_CONTROL
);
790 PreviouslyGrantedAccess
|= (DesiredAccess
& (WRITE_DAC
| READ_CONTROL
));
792 DesiredAccess
&= ~(WRITE_DAC
| READ_CONTROL
);
796 if (DesiredAccess
== 0)
798 *GrantedAccess
= PreviouslyGrantedAccess
;
799 *AccessStatus
= STATUS_SUCCESS
;
804 /* Call the internal function */
805 ret
= SepAccessCheck(SecurityDescriptor
,
806 SubjectSecurityContext
,
808 PreviouslyGrantedAccess
,
816 /* Release the lock if needed */
817 if (!SubjectContextLocked
)
818 SeUnlockSubjectContext(SubjectSecurityContext
);
823 /* SYSTEM CALLS ***************************************************************/
830 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
831 IN HANDLE TokenHandle
,
832 IN ACCESS_MASK DesiredAccess
,
833 IN PGENERIC_MAPPING GenericMapping
,
834 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL
,
835 IN OUT PULONG PrivilegeSetLength
,
836 OUT PACCESS_MASK GrantedAccess
,
837 OUT PNTSTATUS AccessStatus
)
839 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
= NULL
;
840 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
841 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
842 ACCESS_MASK PreviouslyGrantedAccess
= 0;
847 /* Check if this is kernel mode */
848 if (PreviousMode
== KernelMode
)
850 /* Check if kernel wants everything */
851 if (DesiredAccess
& MAXIMUM_ALLOWED
)
854 *GrantedAccess
= GenericMapping
->GenericAll
;
855 *GrantedAccess
|= (DesiredAccess
&~ MAXIMUM_ALLOWED
);
859 /* Just give the desired access */
860 *GrantedAccess
= DesiredAccess
;
864 *AccessStatus
= STATUS_SUCCESS
;
865 return STATUS_SUCCESS
;
868 /* Protect probe in SEH */
871 /* Probe all pointers */
872 ProbeForRead(GenericMapping
, sizeof(GENERIC_MAPPING
), sizeof(ULONG
));
873 ProbeForRead(PrivilegeSetLength
, sizeof(ULONG
), sizeof(ULONG
));
874 ProbeForWrite(PrivilegeSet
, *PrivilegeSetLength
, sizeof(ULONG
));
875 ProbeForWrite(GrantedAccess
, sizeof(ACCESS_MASK
), sizeof(ULONG
));
876 ProbeForWrite(AccessStatus
, sizeof(NTSTATUS
), sizeof(ULONG
));
878 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
880 /* Return the exception code */
881 _SEH2_YIELD(return _SEH2_GetExceptionCode());
885 /* Check for unmapped access rights */
886 if (DesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
| GENERIC_ALL
))
887 return STATUS_GENERIC_NOT_MAPPED
;
889 /* Reference the token */
890 Status
= ObReferenceObjectByHandle(TokenHandle
,
896 if (!NT_SUCCESS(Status
))
898 DPRINT("Failed to reference token (Status %lx)\n", Status
);
902 /* Check token type */
903 if (Token
->TokenType
!= TokenImpersonation
)
905 DPRINT("No impersonation token\n");
906 ObDereferenceObject(Token
);
907 return STATUS_NO_IMPERSONATION_TOKEN
;
910 /* Check the impersonation level */
911 if (Token
->ImpersonationLevel
< SecurityIdentification
)
913 DPRINT("Impersonation level < SecurityIdentification\n");
914 ObDereferenceObject(Token
);
915 return STATUS_BAD_IMPERSONATION_LEVEL
;
918 /* Capture the security descriptor */
919 Status
= SeCaptureSecurityDescriptor(SecurityDescriptor
,
923 &CapturedSecurityDescriptor
);
924 if (!NT_SUCCESS(Status
))
926 DPRINT("Failed to capture the Security Descriptor\n");
927 ObDereferenceObject(Token
);
931 /* Check the captured security descriptor */
932 if (CapturedSecurityDescriptor
== NULL
)
934 DPRINT("Security Descriptor is NULL\n");
935 ObDereferenceObject(Token
);
936 return STATUS_INVALID_SECURITY_DESCR
;
939 /* Check security descriptor for valid owner and group */
940 if (SepGetSDOwner(SecurityDescriptor
) == NULL
|| // FIXME: use CapturedSecurityDescriptor
941 SepGetSDGroup(SecurityDescriptor
) == NULL
) // FIXME: use CapturedSecurityDescriptor
943 DPRINT("Security Descriptor does not have a valid group or owner\n");
944 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor
,
947 ObDereferenceObject(Token
);
948 return STATUS_INVALID_SECURITY_DESCR
;
951 /* Set up the subject context, and lock it */
952 SeCaptureSubjectContext(&SubjectSecurityContext
);
955 SepAcquireTokenLockShared(Token
);
957 /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
958 if (DesiredAccess
& (WRITE_DAC
| READ_CONTROL
| MAXIMUM_ALLOWED
))
960 if (SepTokenIsOwner(Token
, SecurityDescriptor
, FALSE
)) // FIXME: use CapturedSecurityDescriptor
962 if (DesiredAccess
& MAXIMUM_ALLOWED
)
963 PreviouslyGrantedAccess
|= (WRITE_DAC
| READ_CONTROL
);
965 PreviouslyGrantedAccess
|= (DesiredAccess
& (WRITE_DAC
| READ_CONTROL
));
967 DesiredAccess
&= ~(WRITE_DAC
| READ_CONTROL
);
971 if (DesiredAccess
== 0)
973 *GrantedAccess
= PreviouslyGrantedAccess
;
974 *AccessStatus
= STATUS_SUCCESS
;
978 /* Now perform the access check */
979 SepAccessCheck(SecurityDescriptor
, // FIXME: use CapturedSecurityDescriptor
980 &SubjectSecurityContext
,
982 PreviouslyGrantedAccess
,
983 &PrivilegeSet
, //FIXME
990 /* Release subject context and unlock the token */
991 SeReleaseSubjectContext(&SubjectSecurityContext
);
992 SepReleaseTokenLock(Token
);
994 /* Release the captured security descriptor */
995 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor
,
999 /* Dereference the token */
1000 ObDereferenceObject(Token
);
1002 /* Check succeeded */
1003 return STATUS_SUCCESS
;
1009 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1010 IN PSID PrincipalSelfSid
,
1011 IN HANDLE ClientToken
,
1012 IN ACCESS_MASK DesiredAccess
,
1013 IN POBJECT_TYPE_LIST ObjectTypeList
,
1014 IN ULONG ObjectTypeLength
,
1015 IN PGENERIC_MAPPING GenericMapping
,
1016 IN PPRIVILEGE_SET PrivilegeSet
,
1017 IN OUT PULONG PrivilegeSetLength
,
1018 OUT PACCESS_MASK GrantedAccess
,
1019 OUT PNTSTATUS AccessStatus
)
1022 return STATUS_NOT_IMPLEMENTED
;
1027 NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName
,
1029 IN PUNICODE_STRING ObjectTypeName
,
1030 IN PUNICODE_STRING ObjectName
,
1031 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1032 IN PSID PrincipalSelfSid
,
1033 IN ACCESS_MASK DesiredAccess
,
1034 IN AUDIT_EVENT_TYPE AuditType
,
1036 IN POBJECT_TYPE_LIST ObjectTypeList
,
1037 IN ULONG ObjectTypeLength
,
1038 IN PGENERIC_MAPPING GenericMapping
,
1039 IN BOOLEAN ObjectCreation
,
1040 OUT PACCESS_MASK GrantedAccess
,
1041 OUT PNTSTATUS AccessStatus
,
1042 OUT PBOOLEAN GenerateOnClose
)
1045 return STATUS_NOT_IMPLEMENTED
;
1050 NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1051 IN PSID PrincipalSelfSid
,
1052 IN HANDLE ClientToken
,
1053 IN ACCESS_MASK DesiredAccess
,
1054 IN POBJECT_TYPE_LIST ObjectTypeList
,
1055 IN ULONG ObjectTypeLength
,
1056 IN PGENERIC_MAPPING GenericMapping
,
1057 IN PPRIVILEGE_SET PrivilegeSet
,
1058 IN OUT PULONG PrivilegeSetLength
,
1059 OUT PACCESS_MASK GrantedAccess
,
1060 OUT PNTSTATUS AccessStatus
)
1063 return STATUS_NOT_IMPLEMENTED
;
1068 NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName
,
1070 IN PUNICODE_STRING ObjectTypeName
,
1071 IN PUNICODE_STRING ObjectName
,
1072 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1073 IN PSID PrincipalSelfSid
,
1074 IN ACCESS_MASK DesiredAccess
,
1075 IN AUDIT_EVENT_TYPE AuditType
,
1077 IN POBJECT_TYPE_LIST ObjectTypeList
,
1078 IN ULONG ObjectTypeLength
,
1079 IN PGENERIC_MAPPING GenericMapping
,
1080 IN BOOLEAN ObjectCreation
,
1081 OUT PACCESS_MASK GrantedAccess
,
1082 OUT PNTSTATUS AccessStatus
,
1083 OUT PBOOLEAN GenerateOnClose
)
1086 return STATUS_NOT_IMPLEMENTED
;
1091 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName
,
1093 IN HANDLE ClientToken
,
1094 IN PUNICODE_STRING ObjectTypeName
,
1095 IN PUNICODE_STRING ObjectName
,
1096 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1097 IN PSID PrincipalSelfSid
,
1098 IN ACCESS_MASK DesiredAccess
,
1099 IN AUDIT_EVENT_TYPE AuditType
,
1101 IN POBJECT_TYPE_LIST ObjectTypeList
,
1102 IN ULONG ObjectTypeLength
,
1103 IN PGENERIC_MAPPING GenericMapping
,
1104 IN BOOLEAN ObjectCreation
,
1105 OUT PACCESS_MASK GrantedAccess
,
1106 OUT PNTSTATUS AccessStatus
,
1107 OUT PBOOLEAN GenerateOnClose
)
1110 return STATUS_NOT_IMPLEMENTED
;