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
);
29 #if defined (ALLOC_PRAGMA)
30 #pragma alloc_text(INIT, SeInit)
31 #pragma alloc_text(INIT, SepInitExports)
34 /* FUNCTIONS ****************************************************************/
41 DPRINT1("FIXME: SeAccessCheck has been HACKED to always grant access!\n");
42 DPRINT1("FIXME: Please fix all the code that doesn't get proper rights!\n");
46 if (!SepInitSecurityIDs())
57 if (!SepInitExports())
60 /* Initialize the subject context lock */
61 ExInitializeResource(&SepSubjectContextLock
);
63 /* Initialize token objects */
64 SepInitializeTokenImplementation();
66 /* Clear impersonation info for the idle thread */
67 PsGetCurrentThread()->ImpersonationInfo
= NULL
;
68 PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT
);
70 /* Initailize the boot token */
71 ObInitializeFastReference(&PsGetCurrentProcess()->Token
, NULL
);
72 ObInitializeFastReference(&PsGetCurrentProcess()->Token
,
73 SepCreateSystemProcessToken());
81 OBJECT_ATTRIBUTES ObjectAttributes
;
83 HANDLE DirectoryHandle
;
87 /* Create '\Security' directory */
88 RtlInitUnicodeString(&Name
,
90 InitializeObjectAttributes(&ObjectAttributes
,
95 Status
= ZwCreateDirectoryObject(&DirectoryHandle
,
98 if (!NT_SUCCESS(Status
))
100 DPRINT1("Failed to create 'Security' directory!\n");
104 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
105 RtlInitUnicodeString(&Name
,
106 L
"\\LSA_AUTHENTICATION_INITALIZED");
107 InitializeObjectAttributes(&ObjectAttributes
,
112 Status
= ZwCreateEvent(&EventHandle
,
115 SynchronizationEvent
,
117 if (!NT_SUCCESS(Status
))
119 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
120 NtClose(DirectoryHandle
);
124 ZwClose(EventHandle
);
125 ZwClose(DirectoryHandle
);
127 /* FIXME: Create SRM port and listener thread */
133 static BOOLEAN INIT_FUNCTION
136 SepExports
.SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
137 SepExports
.SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
138 SepExports
.SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
139 SepExports
.SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
140 SepExports
.SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
141 SepExports
.SeTcbPrivilege
= SeTcbPrivilege
;
142 SepExports
.SeSecurityPrivilege
= SeSecurityPrivilege
;
143 SepExports
.SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
144 SepExports
.SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
145 SepExports
.SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
146 SepExports
.SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
147 SepExports
.SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
148 SepExports
.SeSystemtimePrivilege
= SeSystemtimePrivilege
;
149 SepExports
.SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
150 SepExports
.SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
151 SepExports
.SeBackupPrivilege
= SeBackupPrivilege
;
152 SepExports
.SeRestorePrivilege
= SeRestorePrivilege
;
153 SepExports
.SeShutdownPrivilege
= SeShutdownPrivilege
;
154 SepExports
.SeDebugPrivilege
= SeDebugPrivilege
;
155 SepExports
.SeAuditPrivilege
= SeAuditPrivilege
;
156 SepExports
.SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
157 SepExports
.SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
158 SepExports
.SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
160 SepExports
.SeNullSid
= SeNullSid
;
161 SepExports
.SeWorldSid
= SeWorldSid
;
162 SepExports
.SeLocalSid
= SeLocalSid
;
163 SepExports
.SeCreatorOwnerSid
= SeCreatorOwnerSid
;
164 SepExports
.SeCreatorGroupSid
= SeCreatorGroupSid
;
165 SepExports
.SeNtAuthoritySid
= SeNtAuthoritySid
;
166 SepExports
.SeDialupSid
= SeDialupSid
;
167 SepExports
.SeNetworkSid
= SeNetworkSid
;
168 SepExports
.SeBatchSid
= SeBatchSid
;
169 SepExports
.SeInteractiveSid
= SeInteractiveSid
;
170 SepExports
.SeLocalSystemSid
= SeLocalSystemSid
;
171 SepExports
.SeAliasAdminsSid
= SeAliasAdminsSid
;
172 SepExports
.SeAliasUsersSid
= SeAliasUsersSid
;
173 SepExports
.SeAliasGuestsSid
= SeAliasGuestsSid
;
174 SepExports
.SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
175 SepExports
.SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
176 SepExports
.SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
177 SepExports
.SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
178 SepExports
.SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
179 SepExports
.SeAuthenticatedUsersSid
= SeAuthenticatedUsersSid
;
180 SepExports
.SeRestrictedSid
= SeRestrictedSid
;
181 SepExports
.SeAnonymousLogonSid
= SeAnonymousLogonSid
;
183 SepExports
.SeUndockPrivilege
= SeUndockPrivilege
;
184 SepExports
.SeSyncAgentPrivilege
= SeSyncAgentPrivilege
;
185 SepExports
.SeEnableDelegationPrivilege
= SeEnableDelegationPrivilege
;
187 SeExports
= &SepExports
;
192 VOID
SepReferenceLogonSession(PLUID AuthenticationId
)
197 VOID
SepDeReferenceLogonSession(PLUID AuthenticationId
)
204 SeDefaultObjectMethod(PVOID Object
,
205 SECURITY_OPERATION_CODE OperationType
,
206 PSECURITY_INFORMATION _SecurityInformation
,
207 PSECURITY_DESCRIPTOR _SecurityDescriptor
,
209 PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
211 PGENERIC_MAPPING GenericMapping
)
213 PISECURITY_DESCRIPTOR ObjectSd
;
214 PISECURITY_DESCRIPTOR NewSd
;
215 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
216 POBJECT_HEADER Header
= OBJECT_TO_OBJECT_HEADER(Object
);
221 ULONG OwnerLength
= 0;
222 ULONG GroupLength
= 0;
223 ULONG DaclLength
= 0;
224 ULONG SaclLength
= 0;
228 SECURITY_INFORMATION SecurityInformation
;
230 if (OperationType
== SetSecurityDescriptor
)
232 ObjectSd
= Header
->SecurityDescriptor
;
233 SecurityInformation
= *_SecurityInformation
;
235 /* Get owner and owner size */
236 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
238 if (SecurityDescriptor
->Owner
!= NULL
)
240 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
241 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
242 (ULONG_PTR
)SecurityDescriptor
);
244 Owner
= (PSID
)SecurityDescriptor
->Owner
;
245 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
247 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
251 if (ObjectSd
->Owner
!= NULL
)
253 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
254 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
256 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
259 /* Get group and group size */
260 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
262 if (SecurityDescriptor
->Group
!= NULL
)
264 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
265 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
266 (ULONG_PTR
)SecurityDescriptor
);
268 Group
= (PSID
)SecurityDescriptor
->Group
;
269 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
271 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
275 if (ObjectSd
->Group
!= NULL
)
277 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
278 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
280 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
283 /* Get DACL and DACL size */
284 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
286 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
287 (SecurityDescriptor
->Dacl
!= NULL
))
289 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
290 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
291 (ULONG_PTR
)SecurityDescriptor
);
293 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
295 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
297 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
301 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
302 (ObjectSd
->Dacl
!= NULL
))
304 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
305 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
307 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
310 /* Get SACL and SACL size */
311 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
313 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
314 (SecurityDescriptor
->Sacl
!= NULL
))
316 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
317 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
318 (ULONG_PTR
)SecurityDescriptor
);
320 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
321 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
323 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
327 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
328 (ObjectSd
->Sacl
!= NULL
))
330 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
331 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
333 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
336 NewSd
= ExAllocatePool(NonPagedPool
,
337 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
338 DaclLength
+ SaclLength
);
341 ObDereferenceObject(Object
);
342 return STATUS_INSUFFICIENT_RESOURCES
;
345 RtlCreateSecurityDescriptor(NewSd
,
346 SECURITY_DESCRIPTOR_REVISION1
);
347 /* We always build a self-relative descriptor */
348 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
350 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
352 if (OwnerLength
!= 0)
354 RtlCopyMemory((PVOID
)Current
,
357 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
358 Current
+= OwnerLength
;
361 if (GroupLength
!= 0)
363 RtlCopyMemory((PVOID
)Current
,
366 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
367 Current
+= GroupLength
;
372 RtlCopyMemory((PVOID
)Current
,
375 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
376 Current
+= DaclLength
;
381 RtlCopyMemory((PVOID
)Current
,
384 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
385 Current
+= SaclLength
;
389 Status
= ObpAddSecurityDescriptor(NewSd
,
390 &Header
->SecurityDescriptor
);
391 if (NT_SUCCESS(Status
))
393 /* Remove the old security descriptor */
394 ObpRemoveSecurityDescriptor(ObjectSd
);
398 /* Restore the old security descriptor */
399 Header
->SecurityDescriptor
= ObjectSd
;
404 else if (OperationType
== QuerySecurityDescriptor
)
406 Status
= SeQuerySecurityDescriptorInfo(_SecurityInformation
,
409 &Header
->SecurityDescriptor
);
411 else if (OperationType
== AssignSecurityDescriptor
)
413 /* Assign the security descriptor to the object header */
414 Status
= ObpAddSecurityDescriptor(SecurityDescriptor
,
415 &Header
->SecurityDescriptor
);
419 return STATUS_SUCCESS
;
424 SeCaptureSubjectContextEx(IN PETHREAD Thread
,
425 IN PEPROCESS Process
,
426 OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
428 BOOLEAN CopyOnOpen
, EffectiveOnly
;
431 /* Save the unique ID */
432 SubjectContext
->ProcessAuditId
= Process
->UniqueProcessId
;
434 /* Check if we have a thread */
437 /* We don't, so no token */
438 SubjectContext
->ClientToken
= NULL
;
442 /* Get the impersonation token */
443 SubjectContext
->ClientToken
=
444 PsReferenceImpersonationToken(Thread
,
447 &SubjectContext
->ImpersonationLevel
);
450 /* Get the primary token */
451 SubjectContext
->PrimaryToken
= PsReferencePrimaryToken(Process
);
459 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext
)
461 /* Call the internal API */
462 SeCaptureSubjectContextEx(PsGetCurrentThread(),
463 PsGetCurrentProcess(),
472 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
476 KeEnterCriticalRegion();
477 ExAcquireResourceExclusiveLite(&SepSubjectContextLock
, TRUE
);
485 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
489 ExReleaseResourceLite(&SepSubjectContextLock
);
490 KeLeaveCriticalRegion();
498 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext
)
502 if (SubjectContext
->PrimaryToken
!= NULL
)
504 ObFastDereferenceObject(&PsGetCurrentProcess()->Token
, SubjectContext
->PrimaryToken
);
507 if (SubjectContext
->ClientToken
!= NULL
)
509 ObDereferenceObject(SubjectContext
->ClientToken
);
518 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
522 if (*SecurityDescriptor
!= NULL
)
524 ExFreePool(*SecurityDescriptor
);
525 *SecurityDescriptor
= NULL
;
528 return STATUS_SUCCESS
;
536 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
537 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
538 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
539 IN GUID
*ObjectType OPTIONAL
,
540 IN BOOLEAN IsDirectoryObject
,
541 IN ULONG AutoInheritFlags
,
542 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
543 IN PGENERIC_MAPPING GenericMapping
,
544 IN POOL_TYPE PoolType
)
547 return STATUS_NOT_IMPLEMENTED
;
552 * FUNCTION: Creates a security descriptor for a new object.
555 * ExplicitDescriptor =
557 * IsDirectoryObject =
566 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
567 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
568 PSECURITY_DESCRIPTOR
*NewDescriptor
,
569 BOOLEAN IsDirectoryObject
,
570 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
571 PGENERIC_MAPPING GenericMapping
,
574 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
575 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
576 PISECURITY_DESCRIPTOR Descriptor
;
578 ULONG OwnerLength
= 0;
579 ULONG GroupLength
= 0;
580 ULONG DaclLength
= 0;
581 ULONG SaclLength
= 0;
592 /* Lock subject context */
593 SeLockSubjectContext(SubjectContext
);
595 if (SubjectContext
->ClientToken
!= NULL
)
597 Token
= SubjectContext
->ClientToken
;
601 Token
= SubjectContext
->PrimaryToken
;
605 /* Inherit the Owner SID */
606 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
608 DPRINT("Use explicit owner sid!\n");
609 Owner
= ExplicitDescriptor
->Owner
;
611 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
613 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
621 DPRINT("Use token owner sid!\n");
622 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
626 DPRINT("Use default owner sid!\n");
627 Owner
= SeLocalSystemSid
;
630 Control
|= SE_OWNER_DEFAULTED
;
633 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
636 /* Inherit the Group SID */
637 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
639 DPRINT("Use explicit group sid!\n");
640 Group
= ExplicitDescriptor
->Group
;
641 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
643 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
650 DPRINT("Use token group sid!\n");
651 Group
= Token
->PrimaryGroup
;
655 DPRINT("Use default group sid!\n");
656 Group
= SeLocalSystemSid
;
659 Control
|= SE_OWNER_DEFAULTED
;
662 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
665 /* Inherit the DACL */
666 if (ExplicitDescriptor
!= NULL
&&
667 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
668 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
670 DPRINT("Use explicit DACL!\n");
671 Dacl
= ExplicitDescriptor
->Dacl
;
672 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
674 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
677 Control
|= SE_DACL_PRESENT
;
679 else if (ParentDescriptor
!= NULL
&&
680 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
682 DPRINT("Use parent DACL!\n");
684 Dacl
= ParentDescriptor
->Dacl
;
685 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
687 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
689 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
691 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
693 DPRINT("Use token default DACL!\n");
695 Dacl
= Token
->DefaultDacl
;
696 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
700 DPRINT("Use NULL DACL!\n");
702 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
705 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
708 /* Inherit the SACL */
709 if (ExplicitDescriptor
!= NULL
&&
710 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
711 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
713 DPRINT("Use explicit SACL!\n");
714 Sacl
= ExplicitDescriptor
->Sacl
;
715 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
717 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
720 Control
|= SE_SACL_PRESENT
;
722 else if (ParentDescriptor
!= NULL
&&
723 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
725 DPRINT("Use parent SACL!\n");
727 Sacl
= ParentDescriptor
->Sacl
;
728 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
730 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
732 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
735 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
738 /* Allocate and initialize the new security descriptor */
739 Length
= sizeof(SECURITY_DESCRIPTOR
) +
740 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
742 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
743 sizeof(SECURITY_DESCRIPTOR
),
749 Descriptor
= ExAllocatePool(PagedPool
,
751 if (Descriptor
== NULL
)
753 DPRINT1("ExAlloctePool() failed\n");
754 /* FIXME: Unlock subject context */
755 return STATUS_INSUFFICIENT_RESOURCES
;
758 RtlZeroMemory( Descriptor
, Length
);
759 RtlCreateSecurityDescriptor(Descriptor
,
760 SECURITY_DESCRIPTOR_REVISION
);
762 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
764 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
768 RtlCopyMemory((PVOID
)Current
,
771 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
772 Current
+= SaclLength
;
777 RtlCopyMemory((PVOID
)Current
,
780 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
781 Current
+= DaclLength
;
784 if (OwnerLength
!= 0)
786 RtlCopyMemory((PVOID
)Current
,
789 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
790 Current
+= OwnerLength
;
791 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
794 DPRINT("Owner of %x is zero length\n", Descriptor
);
796 if (GroupLength
!= 0)
798 memmove((PVOID
)Current
,
801 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
804 /* Unlock subject context */
805 SeUnlockSubjectContext(SubjectContext
);
807 *NewDescriptor
= Descriptor
;
809 DPRINT("Descrptor %x\n", Descriptor
);
810 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
812 return STATUS_SUCCESS
;
817 SepSidInToken(PACCESS_TOKEN _Token
,
821 PTOKEN Token
= (PTOKEN
)_Token
;
825 if (Token
->UserAndGroupCount
== 0)
830 for (i
=0; i
<Token
->UserAndGroupCount
; i
++)
832 if (RtlEqualSid(Sid
, Token
->UserAndGroups
[i
].Sid
))
834 if (Token
->UserAndGroups
[i
].Attributes
& SE_GROUP_ENABLED
)
848 * FUNCTION: Determines whether the requested access rights can be granted
849 * to an object protected by a security descriptor and an object owner
851 * SecurityDescriptor = Security descriptor protecting the object
852 * SubjectSecurityContext = Subject's captured security context
853 * SubjectContextLocked = Indicates the user's subject context is locked
854 * DesiredAccess = Access rights the caller is trying to acquire
855 * PreviouslyGrantedAccess = Specified the access rights already granted
857 * GenericMapping = Generic mapping associated with the object
858 * AccessMode = Access mode used for the check
859 * GrantedAccess (OUT) = On return specifies the access granted
860 * AccessStatus (OUT) = Status indicating why access was denied
861 * RETURNS: If access was granted, returns TRUE
866 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
867 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
,
868 IN BOOLEAN SubjectContextLocked
,
869 IN ACCESS_MASK DesiredAccess
,
870 IN ACCESS_MASK PreviouslyGrantedAccess
,
871 OUT PPRIVILEGE_SET
* Privileges
,
872 IN PGENERIC_MAPPING GenericMapping
,
873 IN KPROCESSOR_MODE AccessMode
,
874 OUT PACCESS_MASK GrantedAccess
,
875 OUT PNTSTATUS AccessStatus
)
877 LUID_AND_ATTRIBUTES Privilege
;
878 ACCESS_MASK CurrentAccess
;
890 /* Check if we didn't get an SD */
891 if (!SecurityDescriptor
)
893 /* Automatic failure */
894 *AccessStatus
= STATUS_ACCESS_DENIED
;
898 CurrentAccess
= PreviouslyGrantedAccess
;
900 if (SubjectContextLocked
== FALSE
)
902 SeLockSubjectContext(SubjectSecurityContext
);
905 Token
= SubjectSecurityContext
->ClientToken
?
906 SubjectSecurityContext
->ClientToken
: SubjectSecurityContext
->PrimaryToken
;
909 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
913 if (!NT_SUCCESS(Status
))
915 if (SubjectContextLocked
== FALSE
)
917 SeUnlockSubjectContext(SubjectSecurityContext
);
920 *AccessStatus
= Status
;
924 /* RULE 1: Grant desired access if the object is unprotected */
925 if (Present
== TRUE
&& Dacl
== NULL
)
927 if (SubjectContextLocked
== FALSE
)
929 SeUnlockSubjectContext(SubjectSecurityContext
);
932 *GrantedAccess
= DesiredAccess
;
933 *AccessStatus
= STATUS_SUCCESS
;
937 CurrentAccess
= PreviouslyGrantedAccess
;
939 /* RULE 2: Check token for 'take ownership' privilege */
940 Privilege
.Luid
= SeTakeOwnershipPrivilege
;
941 Privilege
.Attributes
= SE_PRIVILEGE_ENABLED
;
943 if (SepPrivilegeCheck(Token
,
946 PRIVILEGE_SET_ALL_NECESSARY
,
949 CurrentAccess
|= WRITE_OWNER
;
950 if (DesiredAccess
== CurrentAccess
)
952 if (SubjectContextLocked
== FALSE
)
954 SeUnlockSubjectContext(SubjectSecurityContext
);
957 *GrantedAccess
= CurrentAccess
;
958 *AccessStatus
= STATUS_SUCCESS
;
963 /* RULE 3: Check whether the token is the owner */
964 Status
= RtlGetOwnerSecurityDescriptor(SecurityDescriptor
,
967 if (!NT_SUCCESS(Status
))
969 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status
);
970 if (SubjectContextLocked
== FALSE
)
972 SeUnlockSubjectContext(SubjectSecurityContext
);
975 *AccessStatus
= Status
;
979 if (Sid
&& SepSidInToken(Token
, Sid
))
981 CurrentAccess
|= (READ_CONTROL
| WRITE_DAC
);
982 if (DesiredAccess
== CurrentAccess
)
984 if (SubjectContextLocked
== FALSE
)
986 SeUnlockSubjectContext(SubjectSecurityContext
);
989 *GrantedAccess
= CurrentAccess
;
990 *AccessStatus
= STATUS_SUCCESS
;
995 /* Fail if DACL is absent */
996 if (Present
== FALSE
)
998 if (SubjectContextLocked
== FALSE
)
1000 SeUnlockSubjectContext(SubjectSecurityContext
);
1004 *AccessStatus
= STATUS_ACCESS_DENIED
;
1008 /* RULE 4: Grant rights according to the DACL */
1009 CurrentAce
= (PACE
)(Dacl
+ 1);
1010 for (i
= 0; i
< Dacl
->AceCount
; i
++)
1012 Sid
= (PSID
)(CurrentAce
+ 1);
1013 if (CurrentAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
1015 if (SepSidInToken(Token
, Sid
))
1017 if (SubjectContextLocked
== FALSE
)
1019 SeUnlockSubjectContext(SubjectSecurityContext
);
1023 *AccessStatus
= STATUS_ACCESS_DENIED
;
1028 else if (CurrentAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
1030 if (SepSidInToken(Token
, Sid
))
1032 CurrentAccess
|= CurrentAce
->AccessMask
;
1036 DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce
->Header
.AceType
);
1037 CurrentAce
= (PACE
)((ULONG_PTR
)CurrentAce
+ CurrentAce
->Header
.AceSize
);
1040 if (SubjectContextLocked
== FALSE
)
1042 SeUnlockSubjectContext(SubjectSecurityContext
);
1045 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
1046 CurrentAccess
, DesiredAccess
);
1048 *GrantedAccess
= CurrentAccess
& DesiredAccess
;
1050 if (*GrantedAccess
== DesiredAccess
)
1052 *AccessStatus
= STATUS_SUCCESS
;
1057 *AccessStatus
= STATUS_ACCESS_DENIED
;
1058 DPRINT("FIX caller rights (granted 0x%lx, desired 0x%lx)!\n",
1059 *GrantedAccess
, DesiredAccess
);
1060 return TRUE
; /* FIXME: should be FALSE */
1066 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1067 IN HANDLE TokenHandle
,
1068 IN ACCESS_MASK DesiredAccess
,
1069 IN PGENERIC_MAPPING GenericMapping
,
1070 OUT PPRIVILEGE_SET PrivilegeSet
,
1071 OUT PULONG ReturnLength
,
1072 OUT PACCESS_MASK GrantedAccess
,
1073 OUT PNTSTATUS AccessStatus
)
1075 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
= {0};
1076 KPROCESSOR_MODE PreviousMode
;
1082 DPRINT("NtAccessCheck() called\n");
1084 PreviousMode
= KeGetPreviousMode();
1085 if (PreviousMode
== KernelMode
)
1087 *GrantedAccess
= DesiredAccess
;
1088 *AccessStatus
= STATUS_SUCCESS
;
1089 return STATUS_SUCCESS
;
1092 Status
= ObReferenceObjectByHandle(TokenHandle
,
1098 if (!NT_SUCCESS(Status
))
1100 DPRINT1("Failed to reference token (Status %lx)\n", Status
);
1104 /* Check token type */
1105 if (Token
->TokenType
!= TokenImpersonation
)
1107 DPRINT1("No impersonation token\n");
1108 ObDereferenceObject(Token
);
1109 return STATUS_ACCESS_VIOLATION
;
1112 /* Check impersonation level */
1113 if (Token
->ImpersonationLevel
< SecurityAnonymous
)
1115 DPRINT1("Invalid impersonation level\n");
1116 ObDereferenceObject(Token
);
1117 return STATUS_ACCESS_VIOLATION
;
1120 SubjectSecurityContext
.ClientToken
= Token
;
1121 SubjectSecurityContext
.ImpersonationLevel
= Token
->ImpersonationLevel
;
1123 /* Lock subject context */
1124 SeLockSubjectContext(&SubjectSecurityContext
);
1126 if (SeAccessCheck(SecurityDescriptor
,
1127 &SubjectSecurityContext
,
1137 Status
= *AccessStatus
;
1141 Status
= STATUS_ACCESS_DENIED
;
1144 /* Unlock subject context */
1145 SeUnlockSubjectContext(&SubjectSecurityContext
);
1147 ObDereferenceObject(Token
);
1149 DPRINT("NtAccessCheck() done\n");
1156 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1157 IN PSID PrincipalSelfSid
,
1158 IN HANDLE ClientToken
,
1159 IN ACCESS_MASK DesiredAccess
,
1160 IN POBJECT_TYPE_LIST ObjectTypeList
,
1161 IN ULONG ObjectTypeLength
,
1162 IN PGENERIC_MAPPING GenericMapping
,
1163 IN PPRIVILEGE_SET PrivilegeSet
,
1164 IN ULONG PrivilegeSetLength
,
1165 OUT PACCESS_MASK GrantedAccess
,
1166 OUT PNTSTATUS AccessStatus
)
1169 return STATUS_NOT_IMPLEMENTED
;
1174 NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName
,
1176 IN PUNICODE_STRING ObjectTypeName
,
1177 IN PUNICODE_STRING ObjectName
,
1178 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1179 IN PSID PrincipalSelfSid
,
1180 IN ACCESS_MASK DesiredAccess
,
1181 IN AUDIT_EVENT_TYPE AuditType
,
1183 IN POBJECT_TYPE_LIST ObjectTypeList
,
1184 IN ULONG ObjectTypeLength
,
1185 IN PGENERIC_MAPPING GenericMapping
,
1186 IN BOOLEAN ObjectCreation
,
1187 OUT PACCESS_MASK GrantedAccess
,
1188 OUT PNTSTATUS AccessStatus
,
1189 OUT PBOOLEAN GenerateOnClose
)
1192 return STATUS_NOT_IMPLEMENTED
;
1197 NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1198 IN PSID PrincipalSelfSid
,
1199 IN HANDLE ClientToken
,
1200 IN ACCESS_MASK DesiredAccess
,
1201 IN POBJECT_TYPE_LIST ObjectTypeList
,
1202 IN ULONG ObjectTypeLength
,
1203 IN PGENERIC_MAPPING GenericMapping
,
1204 IN PPRIVILEGE_SET PrivilegeSet
,
1205 IN ULONG PrivilegeSetLength
,
1206 OUT PACCESS_MASK GrantedAccess
,
1207 OUT PNTSTATUS AccessStatus
)
1210 return STATUS_NOT_IMPLEMENTED
;
1215 NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName
,
1217 IN PUNICODE_STRING ObjectTypeName
,
1218 IN PUNICODE_STRING ObjectName
,
1219 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1220 IN PSID PrincipalSelfSid
,
1221 IN ACCESS_MASK DesiredAccess
,
1222 IN AUDIT_EVENT_TYPE AuditType
,
1224 IN POBJECT_TYPE_LIST ObjectTypeList
,
1225 IN ULONG ObjectTypeLength
,
1226 IN PGENERIC_MAPPING GenericMapping
,
1227 IN BOOLEAN ObjectCreation
,
1228 OUT PACCESS_MASK GrantedAccess
,
1229 OUT PNTSTATUS AccessStatus
,
1230 OUT PBOOLEAN GenerateOnClose
)
1233 return STATUS_NOT_IMPLEMENTED
;
1238 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName
,
1240 IN HANDLE ClientToken
,
1241 IN PUNICODE_STRING ObjectTypeName
,
1242 IN PUNICODE_STRING ObjectName
,
1243 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1244 IN PSID PrincipalSelfSid
,
1245 IN ACCESS_MASK DesiredAccess
,
1246 IN AUDIT_EVENT_TYPE AuditType
,
1248 IN POBJECT_TYPE_LIST ObjectTypeList
,
1249 IN ULONG ObjectTypeLength
,
1250 IN PGENERIC_MAPPING GenericMapping
,
1251 IN BOOLEAN ObjectCreation
,
1252 OUT PACCESS_MASK GrantedAccess
,
1253 OUT PNTSTATUS AccessStatus
,
1254 OUT PBOOLEAN GenerateOnClose
)
1257 return STATUS_NOT_IMPLEMENTED
;
1261 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
1262 OUT PACCESS_MASK DesiredAccess
)
1264 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
|
1265 GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
1267 *DesiredAccess
|= READ_CONTROL
;
1269 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1271 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
1276 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
1277 OUT PACCESS_MASK DesiredAccess
)
1279 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
1281 *DesiredAccess
|= WRITE_OWNER
;
1283 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1285 *DesiredAccess
|= WRITE_DAC
;
1287 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1289 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;