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 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
;
168 SepExports
.SeAuthenticatedUsersSid
= SeAuthenticatedUsersSid
;
169 SepExports
.SeRestrictedSid
= SeRestrictedSid
;
170 SepExports
.SeAnonymousLogonSid
= SeAnonymousLogonSid
;
172 SepExports
.SeUndockPrivilege
= SeUndockPrivilege
;
173 SepExports
.SeSyncAgentPrivilege
= SeSyncAgentPrivilege
;
174 SepExports
.SeEnableDelegationPrivilege
= SeEnableDelegationPrivilege
;
176 SeExports
= &SepExports
;
181 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
186 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
193 SeDefaultObjectMethod(PVOID Object
,
194 SECURITY_OPERATION_CODE OperationType
,
195 SECURITY_INFORMATION SecurityInformation
,
196 PSECURITY_DESCRIPTOR SecurityDescriptor
,
198 PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
200 PGENERIC_MAPPING GenericMapping
)
202 PSECURITY_DESCRIPTOR ObjectSd
;
203 PSECURITY_DESCRIPTOR NewSd
;
204 POBJECT_HEADER Header
= BODY_TO_HEADER(Object
);
209 ULONG OwnerLength
= 0;
210 ULONG GroupLength
= 0;
211 ULONG DaclLength
= 0;
212 ULONG SaclLength
= 0;
217 if (OperationType
== SetSecurityDescriptor
)
219 ObjectSd
= Header
->SecurityDescriptor
;
221 /* Get owner and owner size */
222 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
224 if (SecurityDescriptor
->Owner
!= NULL
)
226 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
227 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
228 (ULONG_PTR
)SecurityDescriptor
);
230 Owner
= (PSID
)SecurityDescriptor
->Owner
;
231 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
233 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
237 if (ObjectSd
->Owner
!= NULL
)
239 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
240 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
242 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
245 /* Get group and group size */
246 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
248 if (SecurityDescriptor
->Group
!= NULL
)
250 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
251 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
252 (ULONG_PTR
)SecurityDescriptor
);
254 Group
= (PSID
)SecurityDescriptor
->Group
;
255 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
257 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
261 if (ObjectSd
->Group
!= NULL
)
263 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
264 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
266 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
269 /* Get DACL and DACL size */
270 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
272 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
273 (SecurityDescriptor
->Dacl
!= NULL
))
275 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
276 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
277 (ULONG_PTR
)SecurityDescriptor
);
279 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
281 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
283 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
287 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
288 (ObjectSd
->Dacl
!= NULL
))
290 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
291 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
293 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
296 /* Get SACL and SACL size */
297 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
299 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
300 (SecurityDescriptor
->Sacl
!= NULL
))
302 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
303 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
304 (ULONG_PTR
)SecurityDescriptor
);
306 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
307 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
309 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
313 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
314 (ObjectSd
->Sacl
!= NULL
))
316 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
317 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
319 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
322 NewSd
= ExAllocatePool(NonPagedPool
,
323 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
324 DaclLength
+ SaclLength
);
327 ObDereferenceObject(Object
);
328 return STATUS_INSUFFICIENT_RESOURCES
;
331 RtlCreateSecurityDescriptor(NewSd
,
332 SECURITY_DESCRIPTOR_REVISION1
);
333 /* We always build a self-relative descriptor */
334 NewSd
->Control
= Control
| SE_SELF_RELATIVE
;
336 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
338 if (OwnerLength
!= 0)
340 RtlCopyMemory((PVOID
)Current
,
343 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
344 Current
+= OwnerLength
;
347 if (GroupLength
!= 0)
349 RtlCopyMemory((PVOID
)Current
,
352 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
353 Current
+= GroupLength
;
358 RtlCopyMemory((PVOID
)Current
,
361 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
362 Current
+= DaclLength
;
367 RtlCopyMemory((PVOID
)Current
,
370 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
371 Current
+= SaclLength
;
375 Status
= ObpAddSecurityDescriptor(NewSd
,
376 &Header
->SecurityDescriptor
);
377 if (NT_SUCCESS(Status
))
379 /* Remove the old security descriptor */
380 ObpRemoveSecurityDescriptor(ObjectSd
);
384 /* Restore the old security descriptor */
385 Header
->SecurityDescriptor
= ObjectSd
;
390 else if (OperationType
== QuerySecurityDescriptor
)
392 Status
= SeQuerySecurityDescriptorInfo(&SecurityInformation
,
395 &Header
->SecurityDescriptor
);
397 else if (OperationType
== AssignSecurityDescriptor
)
399 /* Assign the security descriptor to the object header */
400 Status
= ObpAddSecurityDescriptor(SecurityDescriptor
,
401 &Header
->SecurityDescriptor
);
405 return STATUS_SUCCESS
;
412 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
416 BOOLEAN EffectiveOnly
;
420 Thread
= PsGetCurrentThread();
423 SubjectContext
->ProcessAuditId
= 0;
424 SubjectContext
->PrimaryToken
= NULL
;
425 SubjectContext
->ClientToken
= NULL
;
426 SubjectContext
->ImpersonationLevel
= 0;
430 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
431 SubjectContext
->ClientToken
=
432 PsReferenceImpersonationToken(Thread
,
435 &SubjectContext
->ImpersonationLevel
);
436 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
445 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
449 KeEnterCriticalRegion();
450 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
458 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
462 ExReleaseResourceLite(&SepSubjectContextLock
);
463 KeLeaveCriticalRegion();
471 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
475 if (SubjectContext
->PrimaryToken
!= NULL
)
477 ObDereferenceObject(SubjectContext
->PrimaryToken
);
480 if (SubjectContext
->ClientToken
!= NULL
)
482 ObDereferenceObject(SubjectContext
->ClientToken
);
491 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
495 if (*SecurityDescriptor
!= NULL
)
497 ExFreePool(*SecurityDescriptor
);
498 *SecurityDescriptor
= NULL
;
501 return STATUS_SUCCESS
;
509 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
510 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
511 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
512 IN GUID
*ObjectType OPTIONAL
,
513 IN BOOLEAN IsDirectoryObject
,
514 IN ULONG AutoInheritFlags
,
515 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
516 IN PGENERIC_MAPPING GenericMapping
,
517 IN POOL_TYPE PoolType
)
520 return STATUS_NOT_IMPLEMENTED
;
525 * FUNCTION: Creates a security descriptor for a new object.
528 * ExplicitDescriptor =
530 * IsDirectoryObject =
539 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
540 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
541 PSECURITY_DESCRIPTOR
*NewDescriptor
,
542 BOOLEAN IsDirectoryObject
,
543 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
544 PGENERIC_MAPPING GenericMapping
,
547 PSECURITY_DESCRIPTOR Descriptor
;
549 ULONG OwnerLength
= 0;
550 ULONG GroupLength
= 0;
551 ULONG DaclLength
= 0;
552 ULONG SaclLength
= 0;
563 /* Lock subject context */
564 SeLockSubjectContext(SubjectContext
);
566 if (SubjectContext
->ClientToken
!= NULL
)
568 Token
= SubjectContext
->ClientToken
;
572 Token
= SubjectContext
->PrimaryToken
;
576 /* Inherit the Owner SID */
577 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
579 DPRINT("Use explicit owner sid!\n");
580 Owner
= ExplicitDescriptor
->Owner
;
582 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
584 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
592 DPRINT("Use token owner sid!\n");
593 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
597 DPRINT("Use default owner sid!\n");
598 Owner
= SeLocalSystemSid
;
601 Control
|= SE_OWNER_DEFAULTED
;
604 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
607 /* Inherit the Group SID */
608 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
610 DPRINT("Use explicit group sid!\n");
611 Group
= ExplicitDescriptor
->Group
;
612 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
614 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
621 DPRINT("Use token group sid!\n");
622 Group
= Token
->PrimaryGroup
;
626 DPRINT("Use default group sid!\n");
627 Group
= SeLocalSystemSid
;
630 Control
|= SE_OWNER_DEFAULTED
;
633 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
636 /* Inherit the DACL */
637 if (ExplicitDescriptor
!= NULL
&&
638 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
639 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
641 DPRINT("Use explicit DACL!\n");
642 Dacl
= ExplicitDescriptor
->Dacl
;
643 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
645 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
648 Control
|= SE_DACL_PRESENT
;
650 else if (ParentDescriptor
!= NULL
&&
651 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
653 DPRINT("Use parent DACL!\n");
655 Dacl
= ParentDescriptor
->Dacl
;
656 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
658 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
660 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
662 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
664 DPRINT("Use token default DACL!\n");
666 Dacl
= Token
->DefaultDacl
;
667 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
671 DPRINT("Use NULL DACL!\n");
673 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
676 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
679 /* Inherit the SACL */
680 if (ExplicitDescriptor
!= NULL
&&
681 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
682 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
684 DPRINT("Use explicit SACL!\n");
685 Sacl
= ExplicitDescriptor
->Sacl
;
686 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
688 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
691 Control
|= SE_SACL_PRESENT
;
693 else if (ParentDescriptor
!= NULL
&&
694 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
696 DPRINT("Use parent SACL!\n");
698 Sacl
= ParentDescriptor
->Sacl
;
699 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
701 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
703 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
706 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
709 /* Allocate and initialize the new security descriptor */
710 Length
= sizeof(SECURITY_DESCRIPTOR
) +
711 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
713 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
714 sizeof(SECURITY_DESCRIPTOR
),
720 Descriptor
= ExAllocatePool(PagedPool
,
722 if (Descriptor
== NULL
)
724 DPRINT1("ExAlloctePool() failed\n");
725 /* FIXME: Unlock subject context */
726 return STATUS_INSUFFICIENT_RESOURCES
;
729 RtlZeroMemory( Descriptor
, Length
);
730 RtlCreateSecurityDescriptor(Descriptor
,
731 SECURITY_DESCRIPTOR_REVISION
);
733 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
735 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
739 RtlCopyMemory((PVOID
)Current
,
742 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
743 Current
+= SaclLength
;
748 RtlCopyMemory((PVOID
)Current
,
751 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
752 Current
+= DaclLength
;
755 if (OwnerLength
!= 0)
757 RtlCopyMemory((PVOID
)Current
,
760 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
761 Current
+= OwnerLength
;
762 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
765 DPRINT("Owner of %x is zero length\n", Descriptor
);
767 if (GroupLength
!= 0)
769 memmove((PVOID
)Current
,
772 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
775 /* Unlock subject context */
776 SeUnlockSubjectContext(SubjectContext
);
778 *NewDescriptor
= Descriptor
;
780 DPRINT("Descrptor %x\n", Descriptor
);
781 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
783 return STATUS_SUCCESS
;
788 SepSidInToken(PACCESS_TOKEN _Token
,
792 PTOKEN Token
= (PTOKEN
)_Token
;
796 if (Token
->UserAndGroupCount
== 0)
801 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
803 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
805 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
819 * FUNCTION: Determines whether the requested access rights can be granted
820 * to an object protected by a security descriptor and an object owner
822 * SecurityDescriptor = Security descriptor protecting the object
823 * SubjectSecurityContext = Subject's captured security context
824 * SubjectContextLocked = Indicates the user's subject context is locked
825 * DesiredAccess = Access rights the caller is trying to acquire
826 * PreviouslyGrantedAccess = Specified the access rights already granted
828 * GenericMapping = Generic mapping associated with the object
829 * AccessMode = Access mode used for the check
830 * GrantedAccess (OUT) = On return specifies the access granted
831 * AccessStatus (OUT) = Status indicating why access was denied
832 * RETURNS: If access was granted, returns TRUE
837 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
838 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
839 IN BOOLEAN SubjectContextLocked
,
840 IN ACCESS_MASK DesiredAccess
,
841 IN ACCESS_MASK PreviouslyGrantedAccess
,
842 OUT PPRIVILEGE_SET
* Privileges
,
843 IN PGENERIC_MAPPING GenericMapping
,
844 IN KPROCESSOR_MODE AccessMode
,
845 OUT PACCESS_MASK GrantedAccess
,
846 OUT PNTSTATUS AccessStatus
)
848 LUID_AND_ATTRIBUTES Privilege
;
849 ACCESS_MASK CurrentAccess
;
861 CurrentAccess
= PreviouslyGrantedAccess
;
863 if (SubjectContextLocked
== FALSE
)
865 SeLockSubjectContext(SubjectSecurityContext
);
868 Token
= SubjectSecurityContext
->ClientToken
?
869 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
872 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
876 if (!NT_SUCCESS(Status
))
878 if (SubjectContextLocked
== FALSE
)
880 SeUnlockSubjectContext(SubjectSecurityContext
);
883 *AccessStatus
= Status
;
887 /* RULE 1: Grant desired access if the object is unprotected */
888 if (Present
== TRUE
&& Dacl
== NULL
)
890 if (SubjectContextLocked
== FALSE
)
892 SeUnlockSubjectContext(SubjectSecurityContext
);
895 *GrantedAccess
= DesiredAccess
;
896 *AccessStatus
= STATUS_SUCCESS
;
900 CurrentAccess
= PreviouslyGrantedAccess
;
902 /* RULE 2: Check token for 'take ownership' privilege */
903 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
904 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
906 if (SepPrivilegeCheck(Token
,
909 PRIVILEGE_SET_ALL_NECESSARY
,
912 CurrentAccess
|= WRITE_OWNER
;
913 if (DesiredAccess
== CurrentAccess
)
915 if (SubjectContextLocked
== FALSE
)
917 SeUnlockSubjectContext(SubjectSecurityContext
);
920 *GrantedAccess
= CurrentAccess
;
921 *AccessStatus
= STATUS_SUCCESS
;
926 /* RULE 3: Check whether the token is the owner */
927 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
930 if (!NT_SUCCESS(Status
))
932 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
933 if (SubjectContextLocked
== FALSE
)
935 SeUnlockSubjectContext(SubjectSecurityContext
);
938 *AccessStatus
= Status
;
942 if (SepSidInToken(Token
, Sid
))
944 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
945 if (DesiredAccess
== CurrentAccess
)
947 if (SubjectContextLocked
== FALSE
)
949 SeUnlockSubjectContext(SubjectSecurityContext
);
952 *GrantedAccess
= CurrentAccess
;
953 *AccessStatus
= STATUS_SUCCESS
;
958 /* Fail if DACL is absent */
959 if (Present
== FALSE
)
961 if (SubjectContextLocked
== FALSE
)
963 SeUnlockSubjectContext(SubjectSecurityContext
);
967 *AccessStatus
= STATUS_ACCESS_DENIED
;
971 /* RULE 4: Grant rights according to the DACL */
972 CurrentAce
= (PACE
)(Dacl
+ 1);
973 for (i
= 0; i
< Dacl
->AceCount
; i
++)
975 Sid
= (PSID
)(CurrentAce
+ 1);
976 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
978 if (SepSidInToken(Token
, Sid
))
980 if (SubjectContextLocked
== FALSE
)
982 SeUnlockSubjectContext(SubjectSecurityContext
);
986 *AccessStatus
= STATUS_ACCESS_DENIED
;
991 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
993 if (SepSidInToken(Token
, Sid
))
995 CurrentAccess
|= CurrentAce
->AccessMask
;
1000 if (SubjectContextLocked
== FALSE
)
1002 SeUnlockSubjectContext(SubjectSecurityContext
);
1005 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
1006 CurrentAccess
, DesiredAccess
);
1008 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
1011 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
1018 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1019 IN HANDLE TokenHandle
,
1020 IN ACCESS_MASK DesiredAccess
,
1021 IN PGENERIC_MAPPING GenericMapping
,
1022 OUT PPRIVILEGE_SET PrivilegeSet
,
1023 OUT PULONG ReturnLength
,
1024 OUT PACCESS_MASK GrantedAccess
,
1025 OUT PNTSTATUS AccessStatus
)
1027 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
1028 KPROCESSOR_MODE PreviousMode
;
1034 DPRINT("NtAccessCheck() called\n");
1036 PreviousMode
= KeGetPreviousMode();
1037 if (PreviousMode
== KernelMode
)
1039 *GrantedAccess
= DesiredAccess
;
1040 *AccessStatus
= STATUS_SUCCESS
;
1041 return STATUS_SUCCESS
;
1044 Status
= ObReferenceObjectByHandle(TokenHandle
,
1050 if (!NT_SUCCESS(Status
))
1052 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1056 /* Check token type */
1057 if (Token
->TokenType
!= TokenImpersonation
)
1059 DPRINT1("No impersonation token\n");
1060 ObDereferenceObject(Token
);
1061 return STATUS_ACCESS_VIOLATION
;
1064 /* Check impersonation level */
1065 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
1067 DPRINT1("Invalid impersonation level\n");
1068 ObDereferenceObject(Token
);
1069 return STATUS_ACCESS_VIOLATION
;
1072 RtlZeroMemory(&SubjectSecurityContext
,
1073 sizeof(SECURITY_SUBJECT_CONTEXT
));
1074 SubjectSecurityContext
.ClientToken
= Token
;
1075 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
1077 /* Lock subject context */
1078 SeLockSubjectContext(&SubjectSecurityContext
);
1080 if (SeAccessCheck(SecurityDescriptor
,
1081 &SubjectSecurityContext
,
1091 Status
= *AccessStatus
;
1095 Status
= STATUS_ACCESS_DENIED
;
1098 /* Unlock subject context */
1099 SeUnlockSubjectContext(&SubjectSecurityContext
);
1101 ObDereferenceObject(Token
);
1103 DPRINT("NtAccessCheck() done\n");