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 PISECURITY_DESCRIPTOR ObjectSd
;
208 PISECURITY_DESCRIPTOR NewSd
;
209 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
210 POBJECT_HEADER Header
= BODY_TO_HEADER(Object
);
215 ULONG OwnerLength
= 0;
216 ULONG GroupLength
= 0;
217 ULONG DaclLength
= 0;
218 ULONG SaclLength
= 0;
223 if (OperationType
== SetSecurityDescriptor
)
225 ObjectSd
= Header
->SecurityDescriptor
;
227 /* Get owner and owner size */
228 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
230 if (SecurityDescriptor
->Owner
!= NULL
)
232 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
233 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
234 (ULONG_PTR
)SecurityDescriptor
);
236 Owner
= (PSID
)SecurityDescriptor
->Owner
;
237 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
239 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
243 if (ObjectSd
->Owner
!= NULL
)
245 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
246 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
248 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
251 /* Get group and group size */
252 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
254 if (SecurityDescriptor
->Group
!= NULL
)
256 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
257 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
258 (ULONG_PTR
)SecurityDescriptor
);
260 Group
= (PSID
)SecurityDescriptor
->Group
;
261 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
263 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
267 if (ObjectSd
->Group
!= NULL
)
269 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
270 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
272 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
275 /* Get DACL and DACL size */
276 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
278 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
279 (SecurityDescriptor
->Dacl
!= NULL
))
281 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
282 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
283 (ULONG_PTR
)SecurityDescriptor
);
285 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
287 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
289 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
293 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
294 (ObjectSd
->Dacl
!= NULL
))
296 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
297 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
299 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
302 /* Get SACL and SACL size */
303 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
305 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
306 (SecurityDescriptor
->Sacl
!= NULL
))
308 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
309 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
310 (ULONG_PTR
)SecurityDescriptor
);
312 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
313 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
315 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
319 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
320 (ObjectSd
->Sacl
!= NULL
))
322 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
323 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
325 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
328 NewSd
= ExAllocatePool(NonPagedPool
,
329 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
330 DaclLength
+ SaclLength
);
333 ObDereferenceObject(Object
);
334 return STATUS_INSUFFICIENT_RESOURCES
;
337 RtlCreateSecurityDescriptor(NewSd
,
338 SECURITY_DESCRIPTOR_REVISION1
);
339 /* We always build a self-relative descriptor */
340 NewSd
->Control
= Control
| SE_SELF_RELATIVE
;
342 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
344 if (OwnerLength
!= 0)
346 RtlCopyMemory((PVOID
)Current
,
349 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
350 Current
+= OwnerLength
;
353 if (GroupLength
!= 0)
355 RtlCopyMemory((PVOID
)Current
,
358 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
359 Current
+= GroupLength
;
364 RtlCopyMemory((PVOID
)Current
,
367 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
368 Current
+= DaclLength
;
373 RtlCopyMemory((PVOID
)Current
,
376 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
377 Current
+= SaclLength
;
381 Status
= ObpAddSecurityDescriptor(NewSd
,
382 &Header
->SecurityDescriptor
);
383 if (NT_SUCCESS(Status
))
385 /* Remove the old security descriptor */
386 ObpRemoveSecurityDescriptor(ObjectSd
);
390 /* Restore the old security descriptor */
391 Header
->SecurityDescriptor
= ObjectSd
;
396 else if (OperationType
== QuerySecurityDescriptor
)
398 Status
= SeQuerySecurityDescriptorInfo(&SecurityInformation
,
401 &Header
->SecurityDescriptor
);
403 else if (OperationType
== AssignSecurityDescriptor
)
405 /* Assign the security descriptor to the object header */
406 Status
= ObpAddSecurityDescriptor(SecurityDescriptor
,
407 &Header
->SecurityDescriptor
);
411 return STATUS_SUCCESS
;
418 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
422 BOOLEAN EffectiveOnly
;
426 Thread
= PsGetCurrentThread();
429 SubjectContext
->ProcessAuditId
= 0;
430 SubjectContext
->PrimaryToken
= NULL
;
431 SubjectContext
->ClientToken
= NULL
;
432 SubjectContext
->ImpersonationLevel
= 0;
436 SubjectContext
->ProcessAuditId
= Thread
->ThreadsProcess
;
437 SubjectContext
->ClientToken
=
438 PsReferenceImpersonationToken(Thread
,
441 &SubjectContext
->ImpersonationLevel
);
442 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Thread
->ThreadsProcess
);
451 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
455 KeEnterCriticalRegion();
456 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
464 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
468 ExReleaseResourceLite(&SepSubjectContextLock
);
469 KeLeaveCriticalRegion();
477 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
481 if (SubjectContext
->PrimaryToken
!= NULL
)
483 ObDereferenceObject(SubjectContext
->PrimaryToken
);
486 if (SubjectContext
->ClientToken
!= NULL
)
488 ObDereferenceObject(SubjectContext
->ClientToken
);
497 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
501 if (*SecurityDescriptor
!= NULL
)
503 ExFreePool(*SecurityDescriptor
);
504 *SecurityDescriptor
= NULL
;
507 return STATUS_SUCCESS
;
515 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
516 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
517 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
518 IN GUID
*ObjectType OPTIONAL
,
519 IN BOOLEAN IsDirectoryObject
,
520 IN ULONG AutoInheritFlags
,
521 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
522 IN PGENERIC_MAPPING GenericMapping
,
523 IN POOL_TYPE PoolType
)
526 return STATUS_NOT_IMPLEMENTED
;
531 * FUNCTION: Creates a security descriptor for a new object.
534 * ExplicitDescriptor =
536 * IsDirectoryObject =
545 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
546 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
547 PSECURITY_DESCRIPTOR
*NewDescriptor
,
548 BOOLEAN IsDirectoryObject
,
549 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
550 PGENERIC_MAPPING GenericMapping
,
553 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
554 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
555 PISECURITY_DESCRIPTOR Descriptor
;
557 ULONG OwnerLength
= 0;
558 ULONG GroupLength
= 0;
559 ULONG DaclLength
= 0;
560 ULONG SaclLength
= 0;
571 /* Lock subject context */
572 SeLockSubjectContext(SubjectContext
);
574 if (SubjectContext
->ClientToken
!= NULL
)
576 Token
= SubjectContext
->ClientToken
;
580 Token
= SubjectContext
->PrimaryToken
;
584 /* Inherit the Owner SID */
585 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
587 DPRINT("Use explicit owner sid!\n");
588 Owner
= ExplicitDescriptor
->Owner
;
590 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
592 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
600 DPRINT("Use token owner sid!\n");
601 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
605 DPRINT("Use default owner sid!\n");
606 Owner
= SeLocalSystemSid
;
609 Control
|= SE_OWNER_DEFAULTED
;
612 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
615 /* Inherit the Group SID */
616 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
618 DPRINT("Use explicit group sid!\n");
619 Group
= ExplicitDescriptor
->Group
;
620 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
622 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
629 DPRINT("Use token group sid!\n");
630 Group
= Token
->PrimaryGroup
;
634 DPRINT("Use default group sid!\n");
635 Group
= SeLocalSystemSid
;
638 Control
|= SE_OWNER_DEFAULTED
;
641 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
644 /* Inherit the DACL */
645 if (ExplicitDescriptor
!= NULL
&&
646 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
647 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
649 DPRINT("Use explicit DACL!\n");
650 Dacl
= ExplicitDescriptor
->Dacl
;
651 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
653 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
656 Control
|= SE_DACL_PRESENT
;
658 else if (ParentDescriptor
!= NULL
&&
659 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
661 DPRINT("Use parent DACL!\n");
663 Dacl
= ParentDescriptor
->Dacl
;
664 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
666 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
668 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
670 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
672 DPRINT("Use token default DACL!\n");
674 Dacl
= Token
->DefaultDacl
;
675 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
679 DPRINT("Use NULL DACL!\n");
681 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
684 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
687 /* Inherit the SACL */
688 if (ExplicitDescriptor
!= NULL
&&
689 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
690 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
692 DPRINT("Use explicit SACL!\n");
693 Sacl
= ExplicitDescriptor
->Sacl
;
694 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
696 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
699 Control
|= SE_SACL_PRESENT
;
701 else if (ParentDescriptor
!= NULL
&&
702 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
704 DPRINT("Use parent SACL!\n");
706 Sacl
= ParentDescriptor
->Sacl
;
707 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
709 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
711 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
714 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
717 /* Allocate and initialize the new security descriptor */
718 Length
= sizeof(SECURITY_DESCRIPTOR
) +
719 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
721 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
722 sizeof(SECURITY_DESCRIPTOR
),
728 Descriptor
= ExAllocatePool(PagedPool
,
730 if (Descriptor
== NULL
)
732 DPRINT1("ExAlloctePool() failed\n");
733 /* FIXME: Unlock subject context */
734 return STATUS_INSUFFICIENT_RESOURCES
;
737 RtlZeroMemory( Descriptor
, Length
);
738 RtlCreateSecurityDescriptor(Descriptor
,
739 SECURITY_DESCRIPTOR_REVISION
);
741 Descriptor
->Control
= Control
| SE_SELF_RELATIVE
;
743 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
747 RtlCopyMemory((PVOID
)Current
,
750 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
751 Current
+= SaclLength
;
756 RtlCopyMemory((PVOID
)Current
,
759 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
760 Current
+= DaclLength
;
763 if (OwnerLength
!= 0)
765 RtlCopyMemory((PVOID
)Current
,
768 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
769 Current
+= OwnerLength
;
770 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
773 DPRINT("Owner of %x is zero length\n", Descriptor
);
775 if (GroupLength
!= 0)
777 memmove((PVOID
)Current
,
780 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
783 /* Unlock subject context */
784 SeUnlockSubjectContext(SubjectContext
);
786 *NewDescriptor
= Descriptor
;
788 DPRINT("Descrptor %x\n", Descriptor
);
789 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
791 return STATUS_SUCCESS
;
796 SepSidInToken(PACCESS_TOKEN _Token
,
800 PTOKEN Token
= (PTOKEN
)_Token
;
804 if (Token
->UserAndGroupCount
== 0)
809 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
811 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
813 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
827 * FUNCTION: Determines whether the requested access rights can be granted
828 * to an object protected by a security descriptor and an object owner
830 * SecurityDescriptor = Security descriptor protecting the object
831 * SubjectSecurityContext = Subject's captured security context
832 * SubjectContextLocked = Indicates the user's subject context is locked
833 * DesiredAccess = Access rights the caller is trying to acquire
834 * PreviouslyGrantedAccess = Specified the access rights already granted
836 * GenericMapping = Generic mapping associated with the object
837 * AccessMode = Access mode used for the check
838 * GrantedAccess (OUT) = On return specifies the access granted
839 * AccessStatus (OUT) = Status indicating why access was denied
840 * RETURNS: If access was granted, returns TRUE
845 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
846 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
847 IN BOOLEAN SubjectContextLocked
,
848 IN ACCESS_MASK DesiredAccess
,
849 IN ACCESS_MASK PreviouslyGrantedAccess
,
850 OUT PPRIVILEGE_SET
* Privileges
,
851 IN PGENERIC_MAPPING GenericMapping
,
852 IN KPROCESSOR_MODE AccessMode
,
853 OUT PACCESS_MASK GrantedAccess
,
854 OUT PNTSTATUS AccessStatus
)
856 LUID_AND_ATTRIBUTES Privilege
;
857 ACCESS_MASK CurrentAccess
;
869 CurrentAccess
= PreviouslyGrantedAccess
;
871 if (SubjectContextLocked
== FALSE
)
873 SeLockSubjectContext(SubjectSecurityContext
);
876 Token
= SubjectSecurityContext
->ClientToken
?
877 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
880 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
884 if (!NT_SUCCESS(Status
))
886 if (SubjectContextLocked
== FALSE
)
888 SeUnlockSubjectContext(SubjectSecurityContext
);
891 *AccessStatus
= Status
;
895 /* RULE 1: Grant desired access if the object is unprotected */
896 if (Present
== TRUE
&& Dacl
== NULL
)
898 if (SubjectContextLocked
== FALSE
)
900 SeUnlockSubjectContext(SubjectSecurityContext
);
903 *GrantedAccess
= DesiredAccess
;
904 *AccessStatus
= STATUS_SUCCESS
;
908 CurrentAccess
= PreviouslyGrantedAccess
;
910 /* RULE 2: Check token for 'take ownership' privilege */
911 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
912 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
914 if (SepPrivilegeCheck(Token
,
917 PRIVILEGE_SET_ALL_NECESSARY
,
920 CurrentAccess
|= WRITE_OWNER
;
921 if (DesiredAccess
== CurrentAccess
)
923 if (SubjectContextLocked
== FALSE
)
925 SeUnlockSubjectContext(SubjectSecurityContext
);
928 *GrantedAccess
= CurrentAccess
;
929 *AccessStatus
= STATUS_SUCCESS
;
934 /* RULE 3: Check whether the token is the owner */
935 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
938 if (!NT_SUCCESS(Status
))
940 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
941 if (SubjectContextLocked
== FALSE
)
943 SeUnlockSubjectContext(SubjectSecurityContext
);
946 *AccessStatus
= Status
;
950 if (SepSidInToken(Token
, Sid
))
952 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
953 if (DesiredAccess
== CurrentAccess
)
955 if (SubjectContextLocked
== FALSE
)
957 SeUnlockSubjectContext(SubjectSecurityContext
);
960 *GrantedAccess
= CurrentAccess
;
961 *AccessStatus
= STATUS_SUCCESS
;
966 /* Fail if DACL is absent */
967 if (Present
== FALSE
)
969 if (SubjectContextLocked
== FALSE
)
971 SeUnlockSubjectContext(SubjectSecurityContext
);
975 *AccessStatus
= STATUS_ACCESS_DENIED
;
979 /* RULE 4: Grant rights according to the DACL */
980 CurrentAce
= (PACE
)(Dacl
+ 1);
981 for (i
= 0; i
< Dacl
->AceCount
; i
++)
983 Sid
= (PSID
)(CurrentAce
+ 1);
984 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
986 if (SepSidInToken(Token
, Sid
))
988 if (SubjectContextLocked
== FALSE
)
990 SeUnlockSubjectContext(SubjectSecurityContext
);
994 *AccessStatus
= STATUS_ACCESS_DENIED
;
999 if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
1001 if (SepSidInToken(Token
, Sid
))
1003 CurrentAccess
|= CurrentAce
->AccessMask
;
1008 if (SubjectContextLocked
== FALSE
)
1010 SeUnlockSubjectContext(SubjectSecurityContext
);
1013 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
1014 CurrentAccess
, DesiredAccess
);
1016 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
1019 (*GrantedAccess
== DesiredAccess
) ? STATUS_SUCCESS
: STATUS_ACCESS_DENIED
;
1026 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1027 IN HANDLE TokenHandle
,
1028 IN ACCESS_MASK DesiredAccess
,
1029 IN PGENERIC_MAPPING GenericMapping
,
1030 OUT PPRIVILEGE_SET PrivilegeSet
,
1031 OUT PULONG ReturnLength
,
1032 OUT PACCESS_MASK GrantedAccess
,
1033 OUT PNTSTATUS AccessStatus
)
1035 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
;
1036 KPROCESSOR_MODE PreviousMode
;
1042 DPRINT("NtAccessCheck() called\n");
1044 PreviousMode
= KeGetPreviousMode();
1045 if (PreviousMode
== KernelMode
)
1047 *GrantedAccess
= DesiredAccess
;
1048 *AccessStatus
= STATUS_SUCCESS
;
1049 return STATUS_SUCCESS
;
1052 Status
= ObReferenceObjectByHandle(TokenHandle
,
1058 if (!NT_SUCCESS(Status
))
1060 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1064 /* Check token type */
1065 if (Token
->TokenType
!= TokenImpersonation
)
1067 DPRINT1("No impersonation token\n");
1068 ObDereferenceObject(Token
);
1069 return STATUS_ACCESS_VIOLATION
;
1072 /* Check impersonation level */
1073 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
1075 DPRINT1("Invalid impersonation level\n");
1076 ObDereferenceObject(Token
);
1077 return STATUS_ACCESS_VIOLATION
;
1080 RtlZeroMemory(&SubjectSecurityContext
,
1081 sizeof(SECURITY_SUBJECT_CONTEXT
));
1082 SubjectSecurityContext
.ClientToken
= Token
;
1083 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
1085 /* Lock subject context */
1086 SeLockSubjectContext(&SubjectSecurityContext
);
1088 if (SeAccessCheck(SecurityDescriptor
,
1089 &SubjectSecurityContext
,
1099 Status
= *AccessStatus
;
1103 Status
= STATUS_ACCESS_DENIED
;
1106 /* Unlock subject context */
1107 SeUnlockSubjectContext(&SubjectSecurityContext
);
1109 ObDereferenceObject(Token
);
1111 DPRINT("NtAccessCheck() done\n");