[NTOSKRNL]
[reactos.git] / reactos / 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
78 SepExports.SeUndockPrivilege = SeUndockPrivilege;
79 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
80 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
81
82 SeExports = &SepExports;
83 return TRUE;
84 }
85
86
87 BOOLEAN
88 NTAPI
89 INIT_FUNCTION
90 SepInitializationPhase0(VOID)
91 {
92 PAGED_CODE();
93
94 ExpInitLuid();
95 if (!SepInitSecurityIDs()) return FALSE;
96 if (!SepInitDACLs()) return FALSE;
97 if (!SepInitSDs()) return FALSE;
98 SepInitPrivileges();
99 if (!SepInitExports()) return FALSE;
100
101 /* Initialize the subject context lock */
102 ExInitializeResource(&SepSubjectContextLock);
103
104 /* Initialize token objects */
105 SepInitializeTokenImplementation();
106
107 /* Clear impersonation info for the idle thread */
108 PsGetCurrentThread()->ImpersonationInfo = NULL;
109 PspClearCrossThreadFlag(PsGetCurrentThread(),
110 CT_ACTIVE_IMPERSONATION_INFO_BIT);
111
112 /* Initialize the boot token */
113 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
114 ObInitializeFastReference(&PsGetCurrentProcess()->Token,
115 SepCreateSystemProcessToken());
116 return TRUE;
117 }
118
119 BOOLEAN
120 NTAPI
121 INIT_FUNCTION
122 SepInitializationPhase1(VOID)
123 {
124 OBJECT_ATTRIBUTES ObjectAttributes;
125 UNICODE_STRING Name;
126 HANDLE SecurityHandle;
127 HANDLE EventHandle;
128 NTSTATUS Status;
129
130 PAGED_CODE();
131
132 /* Insert the system token into the tree */
133 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
134 ~MAX_FAST_REFS),
135 NULL,
136 0,
137 0,
138 NULL,
139 NULL);
140 ASSERT(NT_SUCCESS(Status));
141
142 /* TODO: Create a security desscriptor for the directory */
143
144 /* Create '\Security' directory */
145 RtlInitUnicodeString(&Name, L"\\Security");
146 InitializeObjectAttributes(&ObjectAttributes,
147 &Name,
148 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
149 0,
150 NULL);
151
152 Status = ZwCreateDirectoryObject(&SecurityHandle,
153 DIRECTORY_ALL_ACCESS,
154 &ObjectAttributes);
155 ASSERT(NT_SUCCESS(Status));
156
157 /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */
158 RtlInitUnicodeString(&Name, L"LSA_AUTHENTICATION_INITIALIZED");
159 InitializeObjectAttributes(&ObjectAttributes,
160 &Name,
161 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
162 SecurityHandle,
163 SePublicDefaultSd);
164
165 Status = ZwCreateEvent(&EventHandle,
166 GENERIC_WRITE,
167 &ObjectAttributes,
168 NotificationEvent,
169 FALSE);
170 ASSERT(NT_SUCCESS(Status));
171
172 Status = ZwClose(EventHandle);
173 ASSERT(NT_SUCCESS(Status));
174
175 Status = ZwClose(SecurityHandle);
176 ASSERT(NT_SUCCESS(Status));
177
178 return TRUE;
179 }
180
181 BOOLEAN
182 NTAPI
183 INIT_FUNCTION
184 SeInitSystem(VOID)
185 {
186 /* Check the initialization phase */
187 switch (ExpInitializationPhase)
188 {
189 case 0:
190
191 /* Do Phase 0 */
192 return SepInitializationPhase0();
193
194 case 1:
195
196 /* Do Phase 1 */
197 return SepInitializationPhase1();
198
199 default:
200
201 /* Don't know any other phase! Bugcheck! */
202 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
203 0,
204 ExpInitializationPhase,
205 0,
206 0);
207 return FALSE;
208 }
209 }
210
211 NTSTATUS
212 NTAPI
213 SeDefaultObjectMethod(IN PVOID Object,
214 IN SECURITY_OPERATION_CODE OperationType,
215 IN PSECURITY_INFORMATION SecurityInformation,
216 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
217 IN OUT PULONG ReturnLength OPTIONAL,
218 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
219 IN POOL_TYPE PoolType,
220 IN PGENERIC_MAPPING GenericMapping)
221 {
222 PAGED_CODE();
223
224 /* Select the operation type */
225 switch (OperationType)
226 {
227 /* Setting a new descriptor */
228 case SetSecurityDescriptor:
229
230 /* Sanity check */
231 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
232
233 /* Set the information */
234 return ObSetSecurityDescriptorInfo(Object,
235 SecurityInformation,
236 SecurityDescriptor,
237 OldSecurityDescriptor,
238 PoolType,
239 GenericMapping);
240
241 case QuerySecurityDescriptor:
242
243 /* Query the information */
244 return ObQuerySecurityDescriptorInfo(Object,
245 SecurityInformation,
246 SecurityDescriptor,
247 ReturnLength,
248 OldSecurityDescriptor);
249
250 case DeleteSecurityDescriptor:
251
252 /* De-assign it */
253 return ObDeassignSecurity(OldSecurityDescriptor);
254
255 case AssignSecurityDescriptor:
256
257 /* Assign it */
258 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
259 return STATUS_SUCCESS;
260
261 default:
262
263 /* Bug check */
264 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
265 }
266
267 /* Should never reach here */
268 ASSERT(FALSE);
269 return STATUS_SUCCESS;
270 }
271
272 VOID
273 NTAPI
274 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
275 OUT PACCESS_MASK DesiredAccess)
276 {
277 *DesiredAccess = 0;
278
279 if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
280 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
281 {
282 *DesiredAccess |= READ_CONTROL;
283 }
284
285 if (SecurityInformation & SACL_SECURITY_INFORMATION)
286 {
287 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
288 }
289 }
290
291 VOID
292 NTAPI
293 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
294 OUT PACCESS_MASK DesiredAccess)
295 {
296 *DesiredAccess = 0;
297
298 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
299 {
300 *DesiredAccess |= WRITE_OWNER;
301 }
302
303 if (SecurityInformation & DACL_SECURITY_INFORMATION)
304 {
305 *DesiredAccess |= WRITE_DAC;
306 }
307
308 if (SecurityInformation & SACL_SECURITY_INFORMATION)
309 {
310 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
311 }
312 }
313
314 NTSTATUS
315 NTAPI
316 SeReportSecurityEvent(
317 _In_ ULONG Flags,
318 _In_ PUNICODE_STRING SourceName,
319 _In_opt_ PSID UserSid,
320 _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters)
321 {
322 SECURITY_SUBJECT_CONTEXT SubjectContext;
323 PTOKEN EffectiveToken;
324 PISID Sid;
325 NTSTATUS Status;
326
327 /* Validate parameters */
328 if ((Flags != 0) ||
329 (SourceName == NULL) ||
330 (SourceName->Buffer == NULL) ||
331 (SourceName->Length == 0) ||
332 (AuditParameters == NULL) ||
333 (AuditParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS - 4))
334 {
335 return STATUS_INVALID_PARAMETER;
336 }
337
338 /* Validate the source name */
339 Status = RtlValidateUnicodeString(0, SourceName);
340 if (!NT_SUCCESS(Status))
341 {
342 return Status;
343 }
344
345 /* Check if we have a user SID */
346 if (UserSid != NULL)
347 {
348 /* Validate it */
349 if (!RtlValidSid(UserSid))
350 {
351 return STATUS_INVALID_PARAMETER;
352 }
353
354 /* Use the user SID */
355 Sid = UserSid;
356 }
357 else
358 {
359 /* No user SID, capture the security subject context */
360 SeCaptureSubjectContext(&SubjectContext);
361
362 /* Extract the effective token */
363 EffectiveToken = SubjectContext.ClientToken ?
364 SubjectContext.ClientToken : SubjectContext.PrimaryToken;
365
366 /* Use the user-and-groups SID */
367 Sid = EffectiveToken->UserAndGroups->Sid;
368 }
369
370 UNIMPLEMENTED;
371
372 /* Check if we captured the subject context */
373 if (Sid != UserSid)
374 {
375 /* Release it */
376 SeReleaseSubjectContext(&SubjectContext);
377 }
378
379 /* Return success */
380 return STATUS_SUCCESS;
381 }
382
383 _Const_
384 NTSTATUS
385 NTAPI
386 SeSetAuditParameter(
387 _Inout_ PSE_ADT_PARAMETER_ARRAY AuditParameters,
388 _In_ SE_ADT_PARAMETER_TYPE Type,
389 _In_range_(<, SE_MAX_AUDIT_PARAMETERS) ULONG Index,
390 _In_reads_(_Inexpressible_("depends on SE_ADT_PARAMETER_TYPE")) PVOID Data)
391 {
392 UNIMPLEMENTED;
393 return STATUS_SUCCESS;
394 }
395
396 /* EOF */