xref: /reactos/ntoskrnl/se/semgr.c (revision 01e5cb0c)
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 */
452