2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/semgr.c
5 * PURPOSE: Security manager
7 * PROGRAMMERS: No programmer listed.
10 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 PSE_EXPORTS SeExports
= NULL
;
19 SE_EXPORTS SepExports
;
20 ULONG SidInTokenCalls
= 0;
22 extern ULONG ExpInitializationPhase
;
23 extern ERESOURCE SepSubjectContextLock
;
25 /* PRIVATE FUNCTIONS **********************************************************/
32 SepExports
.SeCreateTokenPrivilege
= SeCreateTokenPrivilege
;
33 SepExports
.SeAssignPrimaryTokenPrivilege
= SeAssignPrimaryTokenPrivilege
;
34 SepExports
.SeLockMemoryPrivilege
= SeLockMemoryPrivilege
;
35 SepExports
.SeIncreaseQuotaPrivilege
= SeIncreaseQuotaPrivilege
;
36 SepExports
.SeUnsolicitedInputPrivilege
= SeUnsolicitedInputPrivilege
;
37 SepExports
.SeTcbPrivilege
= SeTcbPrivilege
;
38 SepExports
.SeSecurityPrivilege
= SeSecurityPrivilege
;
39 SepExports
.SeTakeOwnershipPrivilege
= SeTakeOwnershipPrivilege
;
40 SepExports
.SeLoadDriverPrivilege
= SeLoadDriverPrivilege
;
41 SepExports
.SeCreatePagefilePrivilege
= SeCreatePagefilePrivilege
;
42 SepExports
.SeIncreaseBasePriorityPrivilege
= SeIncreaseBasePriorityPrivilege
;
43 SepExports
.SeSystemProfilePrivilege
= SeSystemProfilePrivilege
;
44 SepExports
.SeSystemtimePrivilege
= SeSystemtimePrivilege
;
45 SepExports
.SeProfileSingleProcessPrivilege
= SeProfileSingleProcessPrivilege
;
46 SepExports
.SeCreatePermanentPrivilege
= SeCreatePermanentPrivilege
;
47 SepExports
.SeBackupPrivilege
= SeBackupPrivilege
;
48 SepExports
.SeRestorePrivilege
= SeRestorePrivilege
;
49 SepExports
.SeShutdownPrivilege
= SeShutdownPrivilege
;
50 SepExports
.SeDebugPrivilege
= SeDebugPrivilege
;
51 SepExports
.SeAuditPrivilege
= SeAuditPrivilege
;
52 SepExports
.SeSystemEnvironmentPrivilege
= SeSystemEnvironmentPrivilege
;
53 SepExports
.SeChangeNotifyPrivilege
= SeChangeNotifyPrivilege
;
54 SepExports
.SeRemoteShutdownPrivilege
= SeRemoteShutdownPrivilege
;
56 SepExports
.SeNullSid
= SeNullSid
;
57 SepExports
.SeWorldSid
= SeWorldSid
;
58 SepExports
.SeLocalSid
= SeLocalSid
;
59 SepExports
.SeCreatorOwnerSid
= SeCreatorOwnerSid
;
60 SepExports
.SeCreatorGroupSid
= SeCreatorGroupSid
;
61 SepExports
.SeNtAuthoritySid
= SeNtAuthoritySid
;
62 SepExports
.SeDialupSid
= SeDialupSid
;
63 SepExports
.SeNetworkSid
= SeNetworkSid
;
64 SepExports
.SeBatchSid
= SeBatchSid
;
65 SepExports
.SeInteractiveSid
= SeInteractiveSid
;
66 SepExports
.SeLocalSystemSid
= SeLocalSystemSid
;
67 SepExports
.SeAliasAdminsSid
= SeAliasAdminsSid
;
68 SepExports
.SeAliasUsersSid
= SeAliasUsersSid
;
69 SepExports
.SeAliasGuestsSid
= SeAliasGuestsSid
;
70 SepExports
.SeAliasPowerUsersSid
= SeAliasPowerUsersSid
;
71 SepExports
.SeAliasAccountOpsSid
= SeAliasAccountOpsSid
;
72 SepExports
.SeAliasSystemOpsSid
= SeAliasSystemOpsSid
;
73 SepExports
.SeAliasPrintOpsSid
= SeAliasPrintOpsSid
;
74 SepExports
.SeAliasBackupOpsSid
= SeAliasBackupOpsSid
;
75 SepExports
.SeAuthenticatedUsersSid
= SeAuthenticatedUsersSid
;
76 SepExports
.SeRestrictedSid
= SeRestrictedSid
;
77 SepExports
.SeAnonymousLogonSid
= SeAnonymousLogonSid
;
78 SepExports
.SeLocalServiceSid
= SeLocalServiceSid
;
79 SepExports
.SeNetworkServiceSid
= SeNetworkServiceSid
;
81 SepExports
.SeUndockPrivilege
= SeUndockPrivilege
;
82 SepExports
.SeSyncAgentPrivilege
= SeSyncAgentPrivilege
;
83 SepExports
.SeEnableDelegationPrivilege
= SeEnableDelegationPrivilege
;
84 SepExports
.SeManageVolumePrivilege
= SeManageVolumePrivilege
;
85 SepExports
.SeImpersonatePrivilege
= SeImpersonatePrivilege
;
86 SepExports
.SeCreateGlobalPrivilege
= SeCreateGlobalPrivilege
;
88 SeExports
= &SepExports
;
96 SepInitializationPhase0(VOID
)
100 if (!ExLuidInitialization()) return FALSE
;
101 if (!SepInitSecurityIDs()) return FALSE
;
102 if (!SepInitDACLs()) return FALSE
;
103 if (!SepInitSDs()) return FALSE
;
105 if (!SepInitExports()) return FALSE
;
107 /* Initialize the subject context lock */
108 ExInitializeResource(&SepSubjectContextLock
);
110 /* Initialize token objects */
111 SepInitializeTokenImplementation();
113 /* Initialize logon sessions */
114 if (!SeRmInitPhase0()) return FALSE
;
116 /* Clear impersonation info for the idle thread */
117 PsGetCurrentThread()->ImpersonationInfo
= NULL
;
118 PspClearCrossThreadFlag(PsGetCurrentThread(),
119 CT_ACTIVE_IMPERSONATION_INFO_BIT
);
121 /* Initialize the boot token */
122 ObInitializeFastReference(&PsGetCurrentProcess()->Token
, NULL
);
123 ObInitializeFastReference(&PsGetCurrentProcess()->Token
,
124 SepCreateSystemProcessToken());
131 SepInitializationPhase1(VOID
)
133 OBJECT_ATTRIBUTES ObjectAttributes
;
135 HANDLE SecurityHandle
;
138 SECURITY_DESCRIPTOR SecurityDescriptor
;
144 /* Insert the system token into the tree */
145 Status
= ObInsertObject((PVOID
)(PsGetCurrentProcess()->Token
.Value
&
152 ASSERT(NT_SUCCESS(Status
));
154 /* Create a security descriptor for the directory */
155 RtlCreateSecurityDescriptor(&SecurityDescriptor
, SECURITY_DESCRIPTOR_REVISION
);
158 DaclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
159 RtlLengthSid(SeLocalSystemSid
) +
160 RtlLengthSid(SeAliasAdminsSid
) +
161 RtlLengthSid(SeWorldSid
);
162 Dacl
= ExAllocatePoolWithTag(NonPagedPool
, DaclLength
, TAG_SE
);
168 Status
= RtlCreateAcl(Dacl
, DaclLength
, ACL_REVISION
);
169 ASSERT(NT_SUCCESS(Status
));
171 /* Grant full access to SYSTEM */
172 Status
= RtlAddAccessAllowedAce(Dacl
,
174 DIRECTORY_ALL_ACCESS
,
176 ASSERT(NT_SUCCESS(Status
));
178 /* Allow admins to traverse and query */
179 Status
= RtlAddAccessAllowedAce(Dacl
,
181 READ_CONTROL
| DIRECTORY_TRAVERSE
| DIRECTORY_QUERY
,
183 ASSERT(NT_SUCCESS(Status
));
185 /* Allow anyone to traverse */
186 Status
= RtlAddAccessAllowedAce(Dacl
,
190 ASSERT(NT_SUCCESS(Status
));
192 /* And link ACL and SD */
193 Status
= RtlSetDaclSecurityDescriptor(&SecurityDescriptor
, TRUE
, Dacl
, FALSE
);
194 ASSERT(NT_SUCCESS(Status
));
196 /* Create '\Security' directory */
197 RtlInitUnicodeString(&Name
, L
"\\Security");
198 InitializeObjectAttributes(&ObjectAttributes
,
200 OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
202 &SecurityDescriptor
);
204 Status
= ZwCreateDirectoryObject(&SecurityHandle
,
205 DIRECTORY_ALL_ACCESS
,
207 ASSERT(NT_SUCCESS(Status
));
210 ExFreePoolWithTag(Dacl
, TAG_SE
);
212 /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */
213 RtlInitUnicodeString(&Name
, L
"LSA_AUTHENTICATION_INITIALIZED");
214 InitializeObjectAttributes(&ObjectAttributes
,
216 OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
220 Status
= ZwCreateEvent(&EventHandle
,
225 ASSERT(NT_SUCCESS(Status
));
227 Status
= ZwClose(EventHandle
);
228 ASSERT(NT_SUCCESS(Status
));
230 Status
= ZwClose(SecurityHandle
);
231 ASSERT(NT_SUCCESS(Status
));
241 /* Check the initialization phase */
242 switch (ExpInitializationPhase
)
247 return SepInitializationPhase0();
252 return SepInitializationPhase1();
256 /* Don't know any other phase! Bugcheck! */
257 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL
,
259 ExpInitializationPhase
,
268 SeDefaultObjectMethod(IN PVOID Object
,
269 IN SECURITY_OPERATION_CODE OperationType
,
270 IN PSECURITY_INFORMATION SecurityInformation
,
271 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
272 IN OUT PULONG ReturnLength OPTIONAL
,
273 IN OUT PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
274 IN POOL_TYPE PoolType
,
275 IN PGENERIC_MAPPING GenericMapping
)
279 /* Select the operation type */
280 switch (OperationType
)
282 /* Setting a new descriptor */
283 case SetSecurityDescriptor
:
286 ASSERT((PoolType
== PagedPool
) || (PoolType
== NonPagedPool
));
288 /* Set the information */
289 return ObSetSecurityDescriptorInfo(Object
,
292 OldSecurityDescriptor
,
296 case QuerySecurityDescriptor
:
298 /* Query the information */
299 return ObQuerySecurityDescriptorInfo(Object
,
303 OldSecurityDescriptor
);
305 case DeleteSecurityDescriptor
:
308 return ObDeassignSecurity(OldSecurityDescriptor
);
310 case AssignSecurityDescriptor
:
313 ObAssignObjectSecurityDescriptor(Object
, SecurityDescriptor
, PoolType
);
314 return STATUS_SUCCESS
;
319 KeBugCheckEx(SECURITY_SYSTEM
, 0, STATUS_INVALID_PARAMETER
, 0, 0);
322 /* Should never reach here */
324 return STATUS_SUCCESS
;
329 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
330 OUT PACCESS_MASK DesiredAccess
)
334 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
|
335 GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
337 *DesiredAccess
|= READ_CONTROL
;
340 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
342 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
348 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation
,
349 OUT PACCESS_MASK DesiredAccess
)
353 if (SecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
355 *DesiredAccess
|= WRITE_OWNER
;
358 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
360 *DesiredAccess
|= WRITE_DAC
;
363 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
365 *DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
371 SeReportSecurityEvent(
373 _In_ PUNICODE_STRING SourceName
,
374 _In_opt_ PSID UserSid
,
375 _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters
)
377 SECURITY_SUBJECT_CONTEXT SubjectContext
;
378 PTOKEN EffectiveToken
;
382 /* Validate parameters */
384 (SourceName
== NULL
) ||
385 (SourceName
->Buffer
== NULL
) ||
386 (SourceName
->Length
== 0) ||
387 (AuditParameters
== NULL
) ||
388 (AuditParameters
->ParameterCount
> SE_MAX_AUDIT_PARAMETERS
- 4))
390 return STATUS_INVALID_PARAMETER
;
393 /* Validate the source name */
394 Status
= RtlValidateUnicodeString(0, SourceName
);
395 if (!NT_SUCCESS(Status
))
400 /* Check if we have a user SID */
404 if (!RtlValidSid(UserSid
))
406 return STATUS_INVALID_PARAMETER
;
409 /* Use the user SID */
414 /* No user SID, capture the security subject context */
415 SeCaptureSubjectContext(&SubjectContext
);
417 /* Extract the effective token */
418 EffectiveToken
= SubjectContext
.ClientToken
?
419 SubjectContext
.ClientToken
: SubjectContext
.PrimaryToken
;
421 /* Use the user-and-groups SID */
422 Sid
= EffectiveToken
->UserAndGroups
->Sid
;
427 /* Check if we captured the subject context */
431 SeReleaseSubjectContext(&SubjectContext
);
435 return STATUS_SUCCESS
;
442 _Inout_ PSE_ADT_PARAMETER_ARRAY AuditParameters
,
443 _In_ SE_ADT_PARAMETER_TYPE Type
,
444 _In_range_(<, SE_MAX_AUDIT_PARAMETERS
) ULONG Index
,
445 _In_reads_(_Inexpressible_("depends on SE_ADT_PARAMETER_TYPE")) PVOID Data
)
448 return STATUS_SUCCESS
;