3156e64227c510f56b80f02e377610e5533ab394
[reactos.git] / ntoskrnl / se / semgr.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/semgr.c
5 * PURPOSE: Security manager
6 *
7 * PROGRAMMERS: No programmer listed.
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 PSE_EXPORTS SeExports = NULL;
19 SE_EXPORTS SepExports;
20 ULONG SidInTokenCalls = 0;
21
22 extern ULONG ExpInitializationPhase;
23 extern ERESOURCE SepSubjectContextLock;
24
25 /* PRIVATE FUNCTIONS **********************************************************/
26
27 static
28 INIT_FUNCTION
29 BOOLEAN
30 SepInitExports(VOID)
31 {
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;
55
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;
80
81 SepExports.SeUndockPrivilege = SeUndockPrivilege;
82 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
83 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
84 SepExports.SeManageVolumePrivilege = SeManageVolumePrivilege;
85 SepExports.SeImpersonatePrivilege = SeImpersonatePrivilege;
86 SepExports.SeCreateGlobalPrivilege = SeCreateGlobalPrivilege;
87
88 SeExports = &SepExports;
89 return TRUE;
90 }
91
92
93 INIT_FUNCTION
94 BOOLEAN
95 NTAPI
96 SepInitializationPhase0(VOID)
97 {
98 PAGED_CODE();
99
100 ExpInitLuid();
101 if (!SepInitSecurityIDs()) return FALSE;
102 if (!SepInitDACLs()) return FALSE;
103 if (!SepInitSDs()) return FALSE;
104 SepInitPrivileges();
105 if (!SepInitExports()) return FALSE;
106
107 /* Initialize the subject context lock */
108 ExInitializeResource(&SepSubjectContextLock);
109
110 /* Initialize token objects */
111 SepInitializeTokenImplementation();
112
113 /* Initialize logon sessions */
114 if (!SeRmInitPhase0()) return FALSE;
115
116 /* Clear impersonation info for the idle thread */
117 PsGetCurrentThread()->ImpersonationInfo = NULL;
118 PspClearCrossThreadFlag(PsGetCurrentThread(),
119 CT_ACTIVE_IMPERSONATION_INFO_BIT);
120
121 /* Initialize the boot token */
122 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
123 ObInitializeFastReference(&PsGetCurrentProcess()->Token,
124 SepCreateSystemProcessToken());
125 return TRUE;
126 }
127
128 INIT_FUNCTION
129 BOOLEAN
130 NTAPI
131 SepInitializationPhase1(VOID)
132 {
133 OBJECT_ATTRIBUTES ObjectAttributes;
134 UNICODE_STRING Name;
135 HANDLE SecurityHandle;
136 HANDLE EventHandle;
137 NTSTATUS Status;
138 SECURITY_DESCRIPTOR SecurityDescriptor;
139 PACL Dacl;
140 ULONG DaclLength;
141
142 PAGED_CODE();
143
144 /* Insert the system token into the tree */
145 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
146 ~MAX_FAST_REFS),
147 NULL,
148 0,
149 0,
150 NULL,
151 NULL);
152 ASSERT(NT_SUCCESS(Status));
153
154 /* Create a security descriptor for the directory */
155 RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
156
157 /* Setup the ACL */
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);
163 if (Dacl == NULL)
164 {
165 return FALSE;
166 }
167
168 Status = RtlCreateAcl(Dacl, DaclLength, ACL_REVISION);
169 ASSERT(NT_SUCCESS(Status));
170
171 /* Grant full access to SYSTEM */
172 Status = RtlAddAccessAllowedAce(Dacl,
173 ACL_REVISION,
174 DIRECTORY_ALL_ACCESS,
175 SeLocalSystemSid);
176 ASSERT(NT_SUCCESS(Status));
177
178 /* Allow admins to traverse and query */
179 Status = RtlAddAccessAllowedAce(Dacl,
180 ACL_REVISION,
181 READ_CONTROL | DIRECTORY_TRAVERSE | DIRECTORY_QUERY,
182 SeAliasAdminsSid);
183 ASSERT(NT_SUCCESS(Status));
184
185 /* Allow anyone to traverse */
186 Status = RtlAddAccessAllowedAce(Dacl,
187 ACL_REVISION,
188 DIRECTORY_TRAVERSE,
189 SeWorldSid);
190 ASSERT(NT_SUCCESS(Status));
191
192 /* And link ACL and SD */
193 Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE);
194 ASSERT(NT_SUCCESS(Status));
195
196 /* Create '\Security' directory */
197 RtlInitUnicodeString(&Name, L"\\Security");
198 InitializeObjectAttributes(&ObjectAttributes,
199 &Name,
200 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
201 0,
202 &SecurityDescriptor);
203
204 Status = ZwCreateDirectoryObject(&SecurityHandle,
205 DIRECTORY_ALL_ACCESS,
206 &ObjectAttributes);
207 ASSERT(NT_SUCCESS(Status));
208
209 /* Free the DACL */
210 ExFreePoolWithTag(Dacl, TAG_SE);
211
212 /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */
213 RtlInitUnicodeString(&Name, L"LSA_AUTHENTICATION_INITIALIZED");
214 InitializeObjectAttributes(&ObjectAttributes,
215 &Name,
216 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
217 SecurityHandle,
218 SePublicDefaultSd);
219
220 Status = ZwCreateEvent(&EventHandle,
221 GENERIC_WRITE,
222 &ObjectAttributes,
223 NotificationEvent,
224 FALSE);
225 ASSERT(NT_SUCCESS(Status));
226
227 Status = ZwClose(EventHandle);
228 ASSERT(NT_SUCCESS(Status));
229
230 Status = ZwClose(SecurityHandle);
231 ASSERT(NT_SUCCESS(Status));
232
233 return TRUE;
234 }
235
236 INIT_FUNCTION
237 BOOLEAN
238 NTAPI
239 SeInitSystem(VOID)
240 {
241 /* Check the initialization phase */
242 switch (ExpInitializationPhase)
243 {
244 case 0:
245
246 /* Do Phase 0 */
247 return SepInitializationPhase0();
248
249 case 1:
250
251 /* Do Phase 1 */
252 return SepInitializationPhase1();
253
254 default:
255
256 /* Don't know any other phase! Bugcheck! */
257 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
258 0,
259 ExpInitializationPhase,
260 0,
261 0);
262 return FALSE;
263 }
264 }
265
266 NTSTATUS
267 NTAPI
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)
276 {
277 PAGED_CODE();
278
279 /* Select the operation type */
280 switch (OperationType)
281 {
282 /* Setting a new descriptor */
283 case SetSecurityDescriptor:
284
285 /* Sanity check */
286 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
287
288 /* Set the information */
289 return ObSetSecurityDescriptorInfo(Object,
290 SecurityInformation,
291 SecurityDescriptor,
292 OldSecurityDescriptor,
293 PoolType,
294 GenericMapping);
295
296 case QuerySecurityDescriptor:
297
298 /* Query the information */
299 return ObQuerySecurityDescriptorInfo(Object,
300 SecurityInformation,
301 SecurityDescriptor,
302 ReturnLength,
303 OldSecurityDescriptor);
304
305 case DeleteSecurityDescriptor:
306
307 /* De-assign it */
308 return ObDeassignSecurity(OldSecurityDescriptor);
309
310 case AssignSecurityDescriptor:
311
312 /* Assign it */
313 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
314 return STATUS_SUCCESS;
315
316 default:
317
318 /* Bug check */
319 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
320 }
321
322 /* Should never reach here */
323 ASSERT(FALSE);
324 return STATUS_SUCCESS;
325 }
326
327 VOID
328 NTAPI
329 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
330 OUT PACCESS_MASK DesiredAccess)
331 {
332 *DesiredAccess = 0;
333
334 if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
335 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
336 {
337 *DesiredAccess |= READ_CONTROL;
338 }
339
340 if (SecurityInformation & SACL_SECURITY_INFORMATION)
341 {
342 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
343 }
344 }
345
346 VOID
347 NTAPI
348 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
349 OUT PACCESS_MASK DesiredAccess)
350 {
351 *DesiredAccess = 0;
352
353 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
354 {
355 *DesiredAccess |= WRITE_OWNER;
356 }
357
358 if (SecurityInformation & DACL_SECURITY_INFORMATION)
359 {
360 *DesiredAccess |= WRITE_DAC;
361 }
362
363 if (SecurityInformation & SACL_SECURITY_INFORMATION)
364 {
365 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
366 }
367 }
368
369 NTSTATUS
370 NTAPI
371 SeReportSecurityEvent(
372 _In_ ULONG Flags,
373 _In_ PUNICODE_STRING SourceName,
374 _In_opt_ PSID UserSid,
375 _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters)
376 {
377 SECURITY_SUBJECT_CONTEXT SubjectContext;
378 PTOKEN EffectiveToken;
379 PISID Sid;
380 NTSTATUS Status;
381
382 /* Validate parameters */
383 if ((Flags != 0) ||
384 (SourceName == NULL) ||
385 (SourceName->Buffer == NULL) ||
386 (SourceName->Length == 0) ||
387 (AuditParameters == NULL) ||
388 (AuditParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS - 4))
389 {
390 return STATUS_INVALID_PARAMETER;
391 }
392
393 /* Validate the source name */
394 Status = RtlValidateUnicodeString(0, SourceName);
395 if (!NT_SUCCESS(Status))
396 {
397 return Status;
398 }
399
400 /* Check if we have a user SID */
401 if (UserSid != NULL)
402 {
403 /* Validate it */
404 if (!RtlValidSid(UserSid))
405 {
406 return STATUS_INVALID_PARAMETER;
407 }
408
409 /* Use the user SID */
410 Sid = UserSid;
411 }
412 else
413 {
414 /* No user SID, capture the security subject context */
415 SeCaptureSubjectContext(&SubjectContext);
416
417 /* Extract the effective token */
418 EffectiveToken = SubjectContext.ClientToken ?
419 SubjectContext.ClientToken : SubjectContext.PrimaryToken;
420
421 /* Use the user-and-groups SID */
422 Sid = EffectiveToken->UserAndGroups->Sid;
423 }
424
425 UNIMPLEMENTED;
426
427 /* Check if we captured the subject context */
428 if (Sid != UserSid)
429 {
430 /* Release it */
431 SeReleaseSubjectContext(&SubjectContext);
432 }
433
434 /* Return success */
435 return STATUS_SUCCESS;
436 }
437
438 _Const_
439 NTSTATUS
440 NTAPI
441 SeSetAuditParameter(
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)
446 {
447 UNIMPLEMENTED;
448 return STATUS_SUCCESS;
449 }
450
451 /* EOF */