4bf89b6b9499486be8c8e4f3e89767ded4d706b1
[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 BOOLEAN
28 INIT_FUNCTION
29 SepInitExports(VOID)
30 {
31 SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
32 SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
33 SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
34 SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
35 SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
36 SepExports.SeTcbPrivilege = SeTcbPrivilege;
37 SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
38 SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
39 SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
40 SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
41 SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
42 SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
43 SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
44 SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
45 SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
46 SepExports.SeBackupPrivilege = SeBackupPrivilege;
47 SepExports.SeRestorePrivilege = SeRestorePrivilege;
48 SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
49 SepExports.SeDebugPrivilege = SeDebugPrivilege;
50 SepExports.SeAuditPrivilege = SeAuditPrivilege;
51 SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
52 SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
53 SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
54
55 SepExports.SeNullSid = SeNullSid;
56 SepExports.SeWorldSid = SeWorldSid;
57 SepExports.SeLocalSid = SeLocalSid;
58 SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
59 SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
60 SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
61 SepExports.SeDialupSid = SeDialupSid;
62 SepExports.SeNetworkSid = SeNetworkSid;
63 SepExports.SeBatchSid = SeBatchSid;
64 SepExports.SeInteractiveSid = SeInteractiveSid;
65 SepExports.SeLocalSystemSid = SeLocalSystemSid;
66 SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
67 SepExports.SeAliasUsersSid = SeAliasUsersSid;
68 SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
69 SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
70 SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
71 SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
72 SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
73 SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
74 SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
75 SepExports.SeRestrictedSid = SeRestrictedSid;
76 SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
77 SepExports.SeLocalServiceSid = SeLocalServiceSid;
78 SepExports.SeNetworkServiceSid = SeNetworkServiceSid;
79
80 SepExports.SeUndockPrivilege = SeUndockPrivilege;
81 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
82 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
83 SepExports.SeManageVolumePrivilege = SeManageVolumePrivilege;
84 SepExports.SeImpersonatePrivilege = SeImpersonatePrivilege;
85 SepExports.SeCreateGlobalPrivilege = SeCreateGlobalPrivilege;
86
87 SeExports = &SepExports;
88 return TRUE;
89 }
90
91
92 BOOLEAN
93 NTAPI
94 INIT_FUNCTION
95 SepInitializationPhase0(VOID)
96 {
97 PAGED_CODE();
98
99 ExpInitLuid();
100 if (!SepInitSecurityIDs()) return FALSE;
101 if (!SepInitDACLs()) return FALSE;
102 if (!SepInitSDs()) return FALSE;
103 SepInitPrivileges();
104 if (!SepInitExports()) return FALSE;
105
106 /* Initialize the subject context lock */
107 ExInitializeResource(&SepSubjectContextLock);
108
109 /* Initialize token objects */
110 SepInitializeTokenImplementation();
111
112 /* Initialize logon sessions */
113 if (!SeRmInitPhase0()) return FALSE;
114
115 /* Clear impersonation info for the idle thread */
116 PsGetCurrentThread()->ImpersonationInfo = NULL;
117 PspClearCrossThreadFlag(PsGetCurrentThread(),
118 CT_ACTIVE_IMPERSONATION_INFO_BIT);
119
120 /* Initialize the boot token */
121 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
122 ObInitializeFastReference(&PsGetCurrentProcess()->Token,
123 SepCreateSystemProcessToken());
124 return TRUE;
125 }
126
127 BOOLEAN
128 NTAPI
129 INIT_FUNCTION
130 SepInitializationPhase1(VOID)
131 {
132 OBJECT_ATTRIBUTES ObjectAttributes;
133 UNICODE_STRING Name;
134 HANDLE SecurityHandle;
135 HANDLE EventHandle;
136 NTSTATUS Status;
137 SECURITY_DESCRIPTOR SecurityDescriptor;
138 PACL Dacl;
139 ULONG DaclLength;
140
141 PAGED_CODE();
142
143 /* Insert the system token into the tree */
144 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
145 ~MAX_FAST_REFS),
146 NULL,
147 0,
148 0,
149 NULL,
150 NULL);
151 ASSERT(NT_SUCCESS(Status));
152
153 /* Create a security descriptor for the directory */
154 RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
155
156 /* Setup the ACL */
157 DaclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
158 RtlLengthSid(SeLocalSystemSid) +
159 RtlLengthSid(SeAliasAdminsSid) +
160 RtlLengthSid(SeWorldSid);
161 Dacl = ExAllocatePoolWithTag(NonPagedPool, DaclLength, TAG_SE);
162 if (Dacl == NULL)
163 {
164 return FALSE;
165 }
166
167 Status = RtlCreateAcl(Dacl, DaclLength, ACL_REVISION);
168 ASSERT(NT_SUCCESS(Status));
169
170 /* Grant full access to SYSTEM */
171 Status = RtlAddAccessAllowedAce(Dacl,
172 ACL_REVISION,
173 DIRECTORY_ALL_ACCESS,
174 SeLocalSystemSid);
175 ASSERT(NT_SUCCESS(Status));
176
177 /* Allow admins to traverse and query */
178 Status = RtlAddAccessAllowedAce(Dacl,
179 ACL_REVISION,
180 READ_CONTROL | DIRECTORY_TRAVERSE | DIRECTORY_QUERY,
181 SeAliasAdminsSid);
182 ASSERT(NT_SUCCESS(Status));
183
184 /* Allow anyone to traverse */
185 Status = RtlAddAccessAllowedAce(Dacl,
186 ACL_REVISION,
187 DIRECTORY_TRAVERSE,
188 SeWorldSid);
189 ASSERT(NT_SUCCESS(Status));
190
191 /* And link ACL and SD */
192 Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE);
193 ASSERT(NT_SUCCESS(Status));
194
195 /* Create '\Security' directory */
196 RtlInitUnicodeString(&Name, L"\\Security");
197 InitializeObjectAttributes(&ObjectAttributes,
198 &Name,
199 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
200 0,
201 &SecurityDescriptor);
202
203 Status = ZwCreateDirectoryObject(&SecurityHandle,
204 DIRECTORY_ALL_ACCESS,
205 &ObjectAttributes);
206 ASSERT(NT_SUCCESS(Status));
207
208 /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */
209 RtlInitUnicodeString(&Name, L"LSA_AUTHENTICATION_INITIALIZED");
210 InitializeObjectAttributes(&ObjectAttributes,
211 &Name,
212 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
213 SecurityHandle,
214 SePublicDefaultSd);
215
216 Status = ZwCreateEvent(&EventHandle,
217 GENERIC_WRITE,
218 &ObjectAttributes,
219 NotificationEvent,
220 FALSE);
221 ASSERT(NT_SUCCESS(Status));
222
223 Status = ZwClose(EventHandle);
224 ASSERT(NT_SUCCESS(Status));
225
226 Status = ZwClose(SecurityHandle);
227 ASSERT(NT_SUCCESS(Status));
228
229 return TRUE;
230 }
231
232 BOOLEAN
233 NTAPI
234 INIT_FUNCTION
235 SeInitSystem(VOID)
236 {
237 /* Check the initialization phase */
238 switch (ExpInitializationPhase)
239 {
240 case 0:
241
242 /* Do Phase 0 */
243 return SepInitializationPhase0();
244
245 case 1:
246
247 /* Do Phase 1 */
248 return SepInitializationPhase1();
249
250 default:
251
252 /* Don't know any other phase! Bugcheck! */
253 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
254 0,
255 ExpInitializationPhase,
256 0,
257 0);
258 return FALSE;
259 }
260 }
261
262 NTSTATUS
263 NTAPI
264 SeDefaultObjectMethod(IN PVOID Object,
265 IN SECURITY_OPERATION_CODE OperationType,
266 IN PSECURITY_INFORMATION SecurityInformation,
267 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
268 IN OUT PULONG ReturnLength OPTIONAL,
269 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
270 IN POOL_TYPE PoolType,
271 IN PGENERIC_MAPPING GenericMapping)
272 {
273 PAGED_CODE();
274
275 /* Select the operation type */
276 switch (OperationType)
277 {
278 /* Setting a new descriptor */
279 case SetSecurityDescriptor:
280
281 /* Sanity check */
282 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
283
284 /* Set the information */
285 return ObSetSecurityDescriptorInfo(Object,
286 SecurityInformation,
287 SecurityDescriptor,
288 OldSecurityDescriptor,
289 PoolType,
290 GenericMapping);
291
292 case QuerySecurityDescriptor:
293
294 /* Query the information */
295 return ObQuerySecurityDescriptorInfo(Object,
296 SecurityInformation,
297 SecurityDescriptor,
298 ReturnLength,
299 OldSecurityDescriptor);
300
301 case DeleteSecurityDescriptor:
302
303 /* De-assign it */
304 return ObDeassignSecurity(OldSecurityDescriptor);
305
306 case AssignSecurityDescriptor:
307
308 /* Assign it */
309 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
310 return STATUS_SUCCESS;
311
312 default:
313
314 /* Bug check */
315 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
316 }
317
318 /* Should never reach here */
319 ASSERT(FALSE);
320 return STATUS_SUCCESS;
321 }
322
323 VOID
324 NTAPI
325 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
326 OUT PACCESS_MASK DesiredAccess)
327 {
328 *DesiredAccess = 0;
329
330 if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
331 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
332 {
333 *DesiredAccess |= READ_CONTROL;
334 }
335
336 if (SecurityInformation & SACL_SECURITY_INFORMATION)
337 {
338 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
339 }
340 }
341
342 VOID
343 NTAPI
344 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
345 OUT PACCESS_MASK DesiredAccess)
346 {
347 *DesiredAccess = 0;
348
349 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
350 {
351 *DesiredAccess |= WRITE_OWNER;
352 }
353
354 if (SecurityInformation & DACL_SECURITY_INFORMATION)
355 {
356 *DesiredAccess |= WRITE_DAC;
357 }
358
359 if (SecurityInformation & SACL_SECURITY_INFORMATION)
360 {
361 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
362 }
363 }
364
365 NTSTATUS
366 NTAPI
367 SeReportSecurityEvent(
368 _In_ ULONG Flags,
369 _In_ PUNICODE_STRING SourceName,
370 _In_opt_ PSID UserSid,
371 _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters)
372 {
373 SECURITY_SUBJECT_CONTEXT SubjectContext;
374 PTOKEN EffectiveToken;
375 PISID Sid;
376 NTSTATUS Status;
377
378 /* Validate parameters */
379 if ((Flags != 0) ||
380 (SourceName == NULL) ||
381 (SourceName->Buffer == NULL) ||
382 (SourceName->Length == 0) ||
383 (AuditParameters == NULL) ||
384 (AuditParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS - 4))
385 {
386 return STATUS_INVALID_PARAMETER;
387 }
388
389 /* Validate the source name */
390 Status = RtlValidateUnicodeString(0, SourceName);
391 if (!NT_SUCCESS(Status))
392 {
393 return Status;
394 }
395
396 /* Check if we have a user SID */
397 if (UserSid != NULL)
398 {
399 /* Validate it */
400 if (!RtlValidSid(UserSid))
401 {
402 return STATUS_INVALID_PARAMETER;
403 }
404
405 /* Use the user SID */
406 Sid = UserSid;
407 }
408 else
409 {
410 /* No user SID, capture the security subject context */
411 SeCaptureSubjectContext(&SubjectContext);
412
413 /* Extract the effective token */
414 EffectiveToken = SubjectContext.ClientToken ?
415 SubjectContext.ClientToken : SubjectContext.PrimaryToken;
416
417 /* Use the user-and-groups SID */
418 Sid = EffectiveToken->UserAndGroups->Sid;
419 }
420
421 UNIMPLEMENTED;
422
423 /* Check if we captured the subject context */
424 if (Sid != UserSid)
425 {
426 /* Release it */
427 SeReleaseSubjectContext(&SubjectContext);
428 }
429
430 /* Return success */
431 return STATUS_SUCCESS;
432 }
433
434 _Const_
435 NTSTATUS
436 NTAPI
437 SeSetAuditParameter(
438 _Inout_ PSE_ADT_PARAMETER_ARRAY AuditParameters,
439 _In_ SE_ADT_PARAMETER_TYPE Type,
440 _In_range_(<, SE_MAX_AUDIT_PARAMETERS) ULONG Index,
441 _In_reads_(_Inexpressible_("depends on SE_ADT_PARAMETER_TYPE")) PVOID Data)
442 {
443 UNIMPLEMENTED;
444 return STATUS_SUCCESS;
445 }
446
447 /* EOF */