xref: /reactos/ntoskrnl/se/semgr.c (revision f4d29a74)
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     /* Free the DACL */
209     ExFreePoolWithTag(Dacl, TAG_SE);
210 
211     /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */
212     RtlInitUnicodeString(&Name, L"LSA_AUTHENTICATION_INITIALIZED");
213     InitializeObjectAttributes(&ObjectAttributes,
214                                &Name,
215                                OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
216                                SecurityHandle,
217                                SePublicDefaultSd);
218 
219     Status = ZwCreateEvent(&EventHandle,
220                            GENERIC_WRITE,
221                            &ObjectAttributes,
222                            NotificationEvent,
223                            FALSE);
224     ASSERT(NT_SUCCESS(Status));
225 
226     Status = ZwClose(EventHandle);
227     ASSERT(NT_SUCCESS(Status));
228 
229     Status = ZwClose(SecurityHandle);
230     ASSERT(NT_SUCCESS(Status));
231 
232     return TRUE;
233 }
234 
235 BOOLEAN
236 NTAPI
237 INIT_FUNCTION
238 SeInitSystem(VOID)
239 {
240     /* Check the initialization phase */
241     switch (ExpInitializationPhase)
242     {
243         case 0:
244 
245             /* Do Phase 0 */
246             return SepInitializationPhase0();
247 
248         case 1:
249 
250             /* Do Phase 1 */
251             return SepInitializationPhase1();
252 
253         default:
254 
255             /* Don't know any other phase! Bugcheck! */
256             KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
257                          0,
258                          ExpInitializationPhase,
259                          0,
260                          0);
261             return FALSE;
262     }
263 }
264 
265 NTSTATUS
266 NTAPI
267 SeDefaultObjectMethod(IN PVOID Object,
268                       IN SECURITY_OPERATION_CODE OperationType,
269                       IN PSECURITY_INFORMATION SecurityInformation,
270                       IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
271                       IN OUT PULONG ReturnLength OPTIONAL,
272                       IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
273                       IN POOL_TYPE PoolType,
274                       IN PGENERIC_MAPPING GenericMapping)
275 {
276     PAGED_CODE();
277 
278     /* Select the operation type */
279     switch (OperationType)
280     {
281             /* Setting a new descriptor */
282         case SetSecurityDescriptor:
283 
284             /* Sanity check */
285             ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
286 
287             /* Set the information */
288             return ObSetSecurityDescriptorInfo(Object,
289                                                SecurityInformation,
290                                                SecurityDescriptor,
291                                                OldSecurityDescriptor,
292                                                PoolType,
293                                                GenericMapping);
294 
295         case QuerySecurityDescriptor:
296 
297             /* Query the information */
298             return ObQuerySecurityDescriptorInfo(Object,
299                                                  SecurityInformation,
300                                                  SecurityDescriptor,
301                                                  ReturnLength,
302                                                  OldSecurityDescriptor);
303 
304         case DeleteSecurityDescriptor:
305 
306             /* De-assign it */
307             return ObDeassignSecurity(OldSecurityDescriptor);
308 
309         case AssignSecurityDescriptor:
310 
311             /* Assign it */
312             ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
313             return STATUS_SUCCESS;
314 
315         default:
316 
317             /* Bug check */
318             KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
319     }
320 
321     /* Should never reach here */
322     ASSERT(FALSE);
323     return STATUS_SUCCESS;
324 }
325 
326 VOID
327 NTAPI
328 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
329                           OUT PACCESS_MASK DesiredAccess)
330 {
331     *DesiredAccess = 0;
332 
333     if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
334                                GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
335     {
336         *DesiredAccess |= READ_CONTROL;
337     }
338 
339     if (SecurityInformation & SACL_SECURITY_INFORMATION)
340     {
341         *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
342     }
343 }
344 
345 VOID
346 NTAPI
347 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
348                         OUT PACCESS_MASK DesiredAccess)
349 {
350     *DesiredAccess = 0;
351 
352     if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
353     {
354         *DesiredAccess |= WRITE_OWNER;
355     }
356 
357     if (SecurityInformation & DACL_SECURITY_INFORMATION)
358     {
359         *DesiredAccess |= WRITE_DAC;
360     }
361 
362     if (SecurityInformation & SACL_SECURITY_INFORMATION)
363     {
364         *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
365     }
366 }
367 
368 NTSTATUS
369 NTAPI
370 SeReportSecurityEvent(
371     _In_ ULONG Flags,
372     _In_ PUNICODE_STRING SourceName,
373     _In_opt_ PSID UserSid,
374     _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters)
375 {
376     SECURITY_SUBJECT_CONTEXT SubjectContext;
377     PTOKEN EffectiveToken;
378     PISID Sid;
379     NTSTATUS Status;
380 
381     /* Validate parameters */
382     if ((Flags != 0) ||
383         (SourceName == NULL) ||
384         (SourceName->Buffer == NULL) ||
385         (SourceName->Length == 0) ||
386         (AuditParameters == NULL) ||
387         (AuditParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS - 4))
388     {
389         return STATUS_INVALID_PARAMETER;
390     }
391 
392     /* Validate the source name */
393     Status = RtlValidateUnicodeString(0, SourceName);
394     if (!NT_SUCCESS(Status))
395     {
396         return Status;
397     }
398 
399     /* Check if we have a user SID */
400     if (UserSid != NULL)
401     {
402         /* Validate it */
403         if (!RtlValidSid(UserSid))
404         {
405             return STATUS_INVALID_PARAMETER;
406         }
407 
408         /* Use the user SID */
409         Sid = UserSid;
410     }
411     else
412     {
413         /* No user SID, capture the security subject context */
414         SeCaptureSubjectContext(&SubjectContext);
415 
416         /* Extract the effective token */
417         EffectiveToken = SubjectContext.ClientToken ?
418             SubjectContext.ClientToken : SubjectContext.PrimaryToken;
419 
420         /* Use the user-and-groups SID */
421         Sid = EffectiveToken->UserAndGroups->Sid;
422     }
423 
424     UNIMPLEMENTED;
425 
426     /* Check if we captured the subject context */
427     if (Sid != UserSid)
428     {
429         /* Release it */
430         SeReleaseSubjectContext(&SubjectContext);
431     }
432 
433     /* Return success */
434     return STATUS_SUCCESS;
435 }
436 
437 _Const_
438 NTSTATUS
439 NTAPI
440 SeSetAuditParameter(
441     _Inout_ PSE_ADT_PARAMETER_ARRAY AuditParameters,
442     _In_ SE_ADT_PARAMETER_TYPE Type,
443     _In_range_(<, SE_MAX_AUDIT_PARAMETERS) ULONG Index,
444     _In_reads_(_Inexpressible_("depends on SE_ADT_PARAMETER_TYPE")) PVOID Data)
445 {
446     UNIMPLEMENTED;
447     return STATUS_SUCCESS;
448 }
449 
450 /* EOF */
451