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