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