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 ****************************************************************/
39 if (!SepInitSecurityIDs())
50 if (!SepInitExports())
53 /* Initialize the subject context lock */
54 ExInitializeResource(&SepSubjectContextLock
);
65 SepInitializeTokenImplementation();
75 OBJECT_ATTRIBUTES ObjectAttributes
;
77 HANDLE DirectoryHandle
;
81 /* Create '\Security' directory */
82 RtlInitUnicodeString(&Name
,
84 InitializeObjectAttributes(&ObjectAttributes
,
89 Status
= ZwCreateDirectoryObject(&DirectoryHandle
,
92 if (!NT_SUCCESS(Status
))
94 DPRINT1("Failed to create 'Security' directory!\n");
98 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
99 RtlInitUnicodeString(&Name
,
100 L
"\\LSA_AUTHENTICATION_INITALIZED");
101 InitializeObjectAttributes(&ObjectAttributes
,
106 Status
= ZwCreateEvent(&EventHandle
,
109 SynchronizationEvent
,
111 if (!NT_SUCCESS(Status
))
113 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
114 NtClose(DirectoryHandle
);
118 ZwClose(EventHandle
);
119 ZwClose(DirectoryHandle
);
121 /* FIXME: Create SRM port and listener thread */
127 static BOOLEAN INIT_FUNCTION
130 SepExports
.SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
131 SepExports
.SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
132 SepExports
.SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
133 SepExports
.SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
134 SepExports
.SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
135 SepExports
.SeTcbPrivilege
= SeTcbPrivilege
;
136 SepExports
.SeSecurityPrivilege
= SeSecurityPrivilege
;
137 SepExports
.SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
138 SepExports
.SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
139 SepExports
.SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
140 SepExports
.SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
141 SepExports
.SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
142 SepExports
.SeSystemtimePrivilege
= SeSystemtimePrivilege
;
143 SepExports
.SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
144 SepExports
.SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
145 SepExports
.SeBackupPrivilege
= SeBackupPrivilege
;
146 SepExports
.SeRestorePrivilege
= SeRestorePrivilege
;
147 SepExports
.SeShutdownPrivilege
= SeShutdownPrivilege
;
148 SepExports
.SeDebugPrivilege
= SeDebugPrivilege
;
149 SepExports
.SeAuditPrivilege
= SeAuditPrivilege
;
150 SepExports
.SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
151 SepExports
.SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
152 SepExports
.SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
154 SepExports
.SeNullSid
= SeNullSid
;
155 SepExports
.SeWorldSid
= SeWorldSid
;
156 SepExports
.SeLocalSid
= SeLocalSid
;
157 SepExports
.SeCreatorOwnerSid
= SeCreatorOwnerSid
;
158 SepExports
.SeCreatorGroupSid
= SeCreatorGroupSid
;
159 SepExports
.SeNtAuthoritySid
= SeNtAuthoritySid
;
160 SepExports
.SeDialupSid
= SeDialupSid
;
161 SepExports
.SeNetworkSid
= SeNetworkSid
;
162 SepExports
.SeBatchSid
= SeBatchSid
;
163 SepExports
.SeInteractiveSid
= SeInteractiveSid
;
164 SepExports
.SeLocalSystemSid
= SeLocalSystemSid
;
165 SepExports
.SeAliasAdminsSid
= SeAliasAdminsSid
;
166 SepExports
.SeAliasUsersSid
= SeAliasUsersSid
;
167 SepExports
.SeAliasGuestsSid
= SeAliasGuestsSid
;
168 SepExports
.SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
169 SepExports
.SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
170 SepExports
.SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
171 SepExports
.SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
172 SepExports
.SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
173 SepExports
.SeAuthenticatedUsersSid
= SeAuthenticatedUsersSid
;
174 SepExports
.SeRestrictedSid
= SeRestrictedSid
;
175 SepExports
.SeAnonymousLogonSid
= SeAnonymousLogonSid
;
177 SepExports
.SeUndockPrivilege
= SeUndockPrivilege
;
178 SepExports
.SeSyncAgentPrivilege
= SeSyncAgentPrivilege
;
179 SepExports
.SeEnableDelegationPrivilege
= SeEnableDelegationPrivilege
;
181 SeExports
= &SepExports
;
186 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
191 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
198 SeDefaultObjectMethod(PVOID Object
,
199 SECURITY_OPERATION_CODE OperationType
,
200 SECURITY_INFORMATION SecurityInformation
,
201 PSECURITY_DESCRIPTOR SecurityDescriptor
,
203 PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
205 PGENERIC_MAPPING GenericMapping
)
207 PSECURITY_DESCRIPTOR ObjectSd
;
208 PSECURITY_DESCRIPTOR NewSd
;
209 POBJECT_HEADER Header
= BODY_TO_HEADER(Object
);
214 ULONG OwnerLength
= 0;
215 ULONG GroupLength
= 0;
216 ULONG DaclLength
= 0;
217 ULONG SaclLength
= 0;
222 if (OperationType
== SetSecurityDescriptor
)
224 ObjectSd
= Header
->SecurityDescriptor
;
226 /* Get owner and owner size */
227 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
229 if (SecurityDescriptor
->Owner
!= NULL
)
231 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
232 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
233 (ULONG_PTR
)SecurityDescriptor
);
235 Owner
= (PSID
)SecurityDescriptor
->Owner
;
236 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
238 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
242 if (ObjectSd
->Owner
!= NULL
)
244 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
245 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
247 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
250 /* Get group and group size */
251 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
253 if (SecurityDescriptor
->Group
!= NULL
)
255 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
256 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
257 (ULONG_PTR
)SecurityDescriptor
);
259 Group
= (PSID
)SecurityDescriptor
->Group
;
260 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
262 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
266 if (ObjectSd
->Group
!= NULL
)
268 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
269 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
271 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
274 /* Get DACL and DACL size */
275 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
277 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
278 (SecurityDescriptor
->Dacl
!= NULL
))
280 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
281 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
282 (ULONG_PTR
)SecurityDescriptor
);
284 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
286 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
288 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
292 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
293 (ObjectSd
->Dacl
!= NULL
))
295 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
296 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
298 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
301 /* Get SACL and SACL size */
302 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
304 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
305 (SecurityDescriptor
->Sacl
!= NULL
))
307 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
308 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
309 (ULONG_PTR
)SecurityDescriptor
);
311 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
312 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
314 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
318 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
319 (ObjectSd
->Sacl
!= NULL
))
321 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
322 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
324 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
327 NewSd
= ExAllocatePool(NonPagedPool
,
328 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
329 DaclLength
+ SaclLength
);
332 ObDereferenceObject(Object
);
333 return STATUS_INSUFFICIENT_RESOURCES
;
336 RtlCreateSecurityDescriptor(NewSd
,
337 SECURITY_DESCRIPTOR_REVISION1
);
338 /* We always build a self-relative descriptor */
339 NewSd
->Control
= Control
| SE_SELF_RELATIVE
;
341 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
343 if (OwnerLength
!= 0)
345 RtlCopyMemory((PVOID
)Current
,
348 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
349 Current
+= OwnerLength
;
352 if (GroupLength
!= 0)
354 RtlCopyMemory((PVOID
)Current
,
357 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
358 Current
+= GroupLength
;
363 RtlCopyMemory((PVOID
)Current
,
366 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
367 Current
+= DaclLength
;
372 RtlCopyMemory((PVOID
)Current
,
375 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
376 Current
+= SaclLength
;
380 Status
= ObpAddSecurityDescriptor(NewSd
,
381 &Header
->SecurityDescriptor
);
382 if (NT_SUCCESS(Status
))
384 /* Remove the old security descriptor */
385 ObpRemoveSecurityDescriptor(ObjectSd
);
389 /* Restore the old security descriptor */
390 Header
->SecurityDescriptor
= ObjectSd
;
395 else if (OperationType
== QuerySecurityDescriptor
)
397 Status
= SeQuerySecurityDescriptorInfo(&SecurityInformation
,
400 &Header
->SecurityDescriptor
);
402 else if (OperationType
== AssignSecurityDescriptor
)
404 /* Assign the security descriptor to the object header */
405 Status
= ObpAddSecurityDescriptor(SecurityDescriptor
,
406 &Header
->SecurityDescriptor
);
410 return STATUS_SUCCESS
;
417 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
421 BOOLEAN EffectiveOnly
;
425 Thread
= PsGetCurrentThread();
428 SubjectContext
->ProcessAuditId
= 0;
429 SubjectContext
->PrimaryToken
= NULL
;
430 SubjectContext
->ClientToken
= NULL
;
431 SubjectContext
->ImpersonationLevel
= 0;
435 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
436 SubjectContext
->ClientToken
=
437 PsReferenceImpersonationToken(Thread
,
440 &SubjectContext
->ImpersonationLevel
);
441 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
450 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
454 KeEnterCriticalRegion();
455 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
463 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
467 ExReleaseResourceLite(&SepSubjectContextLock
);
468 KeLeaveCriticalRegion();
476 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
480 if (SubjectContext
->PrimaryToken
!= NULL
)
482 ObDereferenceObject(SubjectContext
->PrimaryToken
);
485 if (SubjectContext
->ClientToken
!= NULL
)
487 ObDereferenceObject(SubjectContext
->ClientToken
);
496 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
500 if (*SecurityDescriptor
!= NULL
)
502 ExFreePool(*SecurityDescriptor
);
503 *SecurityDescriptor
= NULL
;
506 return STATUS_SUCCESS
;
514 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
515 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
516 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
517 IN GUID
*ObjectType OPTIONAL
,
518 IN BOOLEAN IsDirectoryObject
,
519 IN ULONG AutoInheritFlags
,
520 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
521 IN PGENERIC_MAPPING GenericMapping
,
522 IN POOL_TYPE PoolType
)
525 return STATUS_NOT_IMPLEMENTED
;
530 * FUNCTION: Creates a security descriptor for a new object.
533 * ExplicitDescriptor =
535 * IsDirectoryObject =
544 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
545 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
546 PSECURITY_DESCRIPTOR
*NewDescriptor
,
547 BOOLEAN IsDirectoryObject
,
548 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
549 PGENERIC_MAPPING GenericMapping
,
552 PSECURITY_DESCRIPTOR Descriptor
;
554 ULONG OwnerLength
= 0;
555 ULONG GroupLength
= 0;
556 ULONG DaclLength
= 0;
557 ULONG SaclLength
= 0;
568 /* Lock subject context */
569 SeLockSubjectContext(SubjectContext
);
571 if (SubjectContext
->ClientToken
!= NULL
)
573 Token
= SubjectContext
->ClientToken
;
577 Token
= SubjectContext
->PrimaryToken
;
581 /* Inherit the Owner SID */
582 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
584 DPRINT("Use explicit owner sid!\n");
585 Owner
= ExplicitDescriptor
->Owner
;
587 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
589 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
597 DPRINT("Use token owner sid!\n");
598 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
602 DPRINT("Use default owner sid!\n");
603 Owner
= SeLocalSystemSid
;
606 Control
|= SE_OWNER_DEFAULTED
;
609 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
612 /* Inherit the Group SID */
613 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
615 DPRINT("Use explicit group sid!\n");
616 Group
= ExplicitDescriptor
->Group
;
617 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
619 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
626 DPRINT("Use token group sid!\n");
627 Group
= Token
->PrimaryGroup
;
631 DPRINT("Use default group sid!\n");
632 Group
= SeLocalSystemSid
;
635 Control
|= SE_OWNER_DEFAULTED
;
638 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
641 /* Inherit the DACL */
642 if (ExplicitDescriptor
!= NULL
&&
643 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
644 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
646 DPRINT("Use explicit DACL!\n");
647 Dacl
= ExplicitDescriptor
->Dacl
;
648 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
650 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
653 Control
|= SE_DACL_PRESENT
;
655 else if (ParentDescriptor
!= NULL
&&
656 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
658 DPRINT("Use parent DACL!\n");
660 Dacl
= ParentDescriptor
->Dacl
;
661 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
663 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
665 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
667 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
669 DPRINT("Use token default DACL!\n");
671 Dacl
= Token
->DefaultDacl
;
672 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
676 DPRINT("Use NULL DACL!\n");
678 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
681 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
684 /* Inherit the SACL */
685 if (ExplicitDescriptor
!= NULL
&&
686 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
687 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
689 DPRINT("Use explicit SACL!\n");
690 Sacl
= ExplicitDescriptor
->Sacl
;
691 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
693 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
696 Control
|= SE_SACL_PRESENT
;
698 else if (ParentDescriptor
!= NULL
&&
699 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
701 DPRINT("Use parent SACL!\n");
703 Sacl
= ParentDescriptor
->Sacl
;
704 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
706 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
708 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
711 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
714 /* Allocate and initialize the new security descriptor */
715 Length
= sizeof(SECURITY_DESCRIPTOR
) +
716 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
718 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
719 sizeof(SECURITY_DESCRIPTOR
),
725 Descriptor
= ExAllocatePool(PagedPool
,
727 if (Descriptor
== NULL
)
729 DPRINT1("ExAlloctePool() failed\n");
730 /* FIXME: Unlock subject context */
731 return STATUS_INSUFFICIENT_RESOURCES
;
734 RtlZeroMemory( Descriptor
, Length
);
735 RtlCreateSecurityDescriptor(Descriptor
,
736 SECURITY_DESCRIPTOR_REVISION
);
738 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
740 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
744 RtlCopyMemory((PVOID
)Current
,
747 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
748 Current
+= SaclLength
;
753 RtlCopyMemory((PVOID
)Current
,
756 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
757 Current
+= DaclLength
;
760 if (OwnerLength
!= 0)
762 RtlCopyMemory((PVOID
)Current
,
765 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
766 Current
+= OwnerLength
;
767 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
770 DPRINT("Owner of %x is zero length\n", Descriptor
);
772 if (GroupLength
!= 0)
774 memmove((PVOID
)Current
,
777 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
780 /* Unlock subject context */
781 SeUnlockSubjectContext(SubjectContext
);
783 *NewDescriptor
= Descriptor
;
785 DPRINT("Descrptor %x\n", Descriptor
);
786 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
788 return STATUS_SUCCESS
;
793 SepSidInToken(PACCESS_TOKEN _Token
,
797 PTOKEN Token
= (PTOKEN
)_Token
;
801 if (Token
->UserAndGroupCount
== 0)
806 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
808 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
810 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
824 * FUNCTION: Determines whether the requested access rights can be granted
825 * to an object protected by a security descriptor and an object owner
827 * SecurityDescriptor = Security descriptor protecting the object
828 * SubjectSecurityContext = Subject's captured security context
829 * SubjectContextLocked = Indicates the user's subject context is locked
830 * DesiredAccess = Access rights the caller is trying to acquire
831 * PreviouslyGrantedAccess = Specified the access rights already granted
833 * GenericMapping = Generic mapping associated with the object
834 * AccessMode = Access mode used for the check
835 * GrantedAccess (OUT) = On return specifies the access granted
836 * AccessStatus (OUT) = Status indicating why access was denied
837 * RETURNS: If access was granted, returns TRUE
842 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
843 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
844 IN BOOLEAN SubjectContextLocked
,
845 IN ACCESS_MASK DesiredAccess
,
846 IN ACCESS_MASK PreviouslyGrantedAccess
,
847 OUT PPRIVILEGE_SET
* Privileges
,
848 IN PGENERIC_MAPPING GenericMapping
,
849 IN KPROCESSOR_MODE AccessMode
,
850 OUT PACCESS_MASK GrantedAccess
,
851 OUT PNTSTATUS AccessStatus
)
853 LUID_AND_ATTRIBUTES Privilege
;
854 ACCESS_MASK CurrentAccess
;
866 CurrentAccess
= PreviouslyGrantedAccess
;
868 if (SubjectContextLocked
== FALSE
)
870 SeLockSubjectContext(SubjectSecurityContext
);
873 Token
= SubjectSecurityContext
->ClientToken
?
874 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
877 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
881 if (!NT_SUCCESS(Status
))
883 if (SubjectContextLocked
== FALSE
)
885 SeUnlockSubjectContext(SubjectSecurityContext
);
888 *AccessStatus
= Status
;
892 /* RULE 1: Grant desired access if the object is unprotected */
893 if (Present
== TRUE
&& Dacl
== NULL
)
895 if (SubjectContextLocked
== FALSE
)
897 SeUnlockSubjectContext(SubjectSecurityContext
);
900 *GrantedAccess
= DesiredAccess
;
901 *AccessStatus
= STATUS_SUCCESS
;
905 CurrentAccess
= PreviouslyGrantedAccess
;
907 /* RULE 2: Check token for 'take ownership' privilege */
908 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
909 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
911 if (SepPrivilegeCheck(Token
,
914 PRIVILEGE_SET_ALL_NECESSARY
,
917 CurrentAccess
|= WRITE_OWNER
;
918 if (DesiredAccess
== CurrentAccess
)
920 if (SubjectContextLocked
== FALSE
)
922 SeUnlockSubjectContext(SubjectSecurityContext
);
925 *GrantedAccess
= CurrentAccess
;
926 *AccessStatus
= STATUS_SUCCESS
;
931 /* RULE 3: Check whether the token is the owner */
932 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
935 if (!NT_SUCCESS(Status
))
937 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
938 if (SubjectContextLocked
== FALSE
)
940 SeUnlockSubjectContext(SubjectSecurityContext
);
943 *AccessStatus
= Status
;
947 if (SepSidInToken(Token
, Sid
))
949 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
950 if (DesiredAccess
== CurrentAccess
)
952 if (SubjectContextLocked
== FALSE
)
954 SeUnlockSubjectContext(SubjectSecurityContext
);
957 *GrantedAccess
= CurrentAccess
;
958 *AccessStatus
= STATUS_SUCCESS
;
963 /* Fail if DACL is absent */
964 if (Present
== FALSE
)
966 if (SubjectContextLocked
== FALSE
)
968 SeUnlockSubjectContext(SubjectSecurityContext
);
972 *AccessStatus
= STATUS_ACCESS_DENIED
;
976 /* RULE 4: Grant rights according to the DACL */
977 CurrentAce
= (PACE
)(Dacl
+ 1);
978 for (i
= 0; i
< Dacl
->AceCount
; i
++)
980 Sid
= (PSID
)(CurrentAce
+ 1);
981 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
983 if (SepSidInToken(Token
, Sid
))
985 if (SubjectContextLocked
== FALSE
)
987 SeUnlockSubjectContext(SubjectSecurityContext
);
991 *AccessStatus
= STATUS_ACCESS_DENIED
;
996 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
998 if (SepSidInToken(Token
, Sid
))
1000 CurrentAccess
|= CurrentAce
->AccessMask
;
1005 if (SubjectContextLocked
== FALSE
)
1007 SeUnlockSubjectContext(SubjectSecurityContext
);
1010 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
1011 CurrentAccess
, DesiredAccess
);
1013 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
1016 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
1023 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1024 IN HANDLE TokenHandle
,
1025 IN ACCESS_MASK DesiredAccess
,
1026 IN PGENERIC_MAPPING GenericMapping
,
1027 OUT PPRIVILEGE_SET PrivilegeSet
,
1028 OUT PULONG ReturnLength
,
1029 OUT PACCESS_MASK GrantedAccess
,
1030 OUT PNTSTATUS AccessStatus
)
1032 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
1033 KPROCESSOR_MODE PreviousMode
;
1039 DPRINT("NtAccessCheck() called\n");
1041 PreviousMode
= KeGetPreviousMode();
1042 if (PreviousMode
== KernelMode
)
1044 *GrantedAccess
= DesiredAccess
;
1045 *AccessStatus
= STATUS_SUCCESS
;
1046 return STATUS_SUCCESS
;
1049 Status
= ObReferenceObjectByHandle(TokenHandle
,
1055 if (!NT_SUCCESS(Status
))
1057 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1061 /* Check token type */
1062 if (Token
->TokenType
!= TokenImpersonation
)
1064 DPRINT1("No impersonation token\n");
1065 ObDereferenceObject(Token
);
1066 return STATUS_ACCESS_VIOLATION
;
1069 /* Check impersonation level */
1070 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
1072 DPRINT1("Invalid impersonation level\n");
1073 ObDereferenceObject(Token
);
1074 return STATUS_ACCESS_VIOLATION
;
1077 RtlZeroMemory(&SubjectSecurityContext
,
1078 sizeof(SECURITY_SUBJECT_CONTEXT
));
1079 SubjectSecurityContext
.ClientToken
= Token
;
1080 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
1082 /* Lock subject context */
1083 SeLockSubjectContext(&SubjectSecurityContext
);
1085 if (SeAccessCheck(SecurityDescriptor
,
1086 &SubjectSecurityContext
,
1096 Status
= *AccessStatus
;
1100 Status
= STATUS_ACCESS_DENIED
;
1103 /* Unlock subject context */
1104 SeUnlockSubjectContext(&SubjectSecurityContext
);
1106 ObDereferenceObject(Token
);
1108 DPRINT("NtAccessCheck() done\n");