branch update for HEAD-2003091401
[reactos.git] / ntoskrnl / se / semgr.c
1 /* $Id$
2  *
3  * COPYRIGHT:         See COPYING in the top level directory
4  * PROJECT:           ReactOS kernel
5  * PURPOSE:           Security manager
6  * FILE:              kernel/se/semgr.c
7  * PROGRAMER:         ?
8  * REVISION HISTORY:
9  *                 26/07/98: Added stubs for security functions
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16 #include <internal/se.h>
17
18 #include <internal/debug.h>
19
20 #define TAG_SXPT   TAG('S', 'X', 'P', 'T')
21
22
23 /* GLOBALS ******************************************************************/
24
25 PSE_EXPORTS EXPORTED SeExports = NULL;
26
27
28 /* PROTOTYPES ***************************************************************/
29
30 static BOOLEAN SepInitExports(VOID);
31
32 /* FUNCTIONS ****************************************************************/
33
34 BOOLEAN
35 SeInit1(VOID)
36 {
37   SepInitLuid();
38
39   if (!SepInitSecurityIDs())
40     return(FALSE);
41
42 #ifndef LIBCAPTIVE
43   if (!SepInitDACLs())
44     return(FALSE);
45 #endif /* LIBCAPTIVE */
46
47   if (!SepInitSDs())
48     return(FALSE);
49
50   SepInitPrivileges();
51
52   if (!SepInitExports())
53     return(FALSE);
54
55   return(TRUE);
56 }
57
58
59 BOOLEAN
60 SeInit2(VOID)
61 {
62   SepInitializeTokenImplementation();
63
64   return(TRUE);
65 }
66
67
68 BOOLEAN
69 SeInitSRM(VOID)
70 {
71   OBJECT_ATTRIBUTES ObjectAttributes;
72   UNICODE_STRING Name;
73   HANDLE DirectoryHandle;
74 #ifndef LIBCAPTIVE
75   HANDLE EventHandle;
76 #endif /* LIBCAPTIVE */
77   NTSTATUS Status;
78
79   /* Create '\Security' directory */
80   RtlInitUnicodeString(&Name,
81                        REACTOS_UCS2(L"\\Security"));
82   InitializeObjectAttributes(&ObjectAttributes,
83                              &Name,
84                              OBJ_PERMANENT,
85                              0,
86                              NULL);
87   Status = NtCreateDirectoryObject(&DirectoryHandle,
88                                    DIRECTORY_ALL_ACCESS,
89                                    &ObjectAttributes);
90   if (!NT_SUCCESS(Status))
91     {
92       DPRINT1("Failed to create 'Security' directory!\n");
93       return(FALSE);
94     }
95
96 #ifndef LIBCAPTIVE
97   /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
98   RtlInitUnicodeString(&Name,
99                        REACTOS_UCS2(L"\\LSA_AUTHENTICATION_INITALIZED"));
100   InitializeObjectAttributes(&ObjectAttributes,
101                              &Name,
102                              OBJ_PERMANENT,
103                              DirectoryHandle,
104                              SePublicDefaultSd);
105   Status = NtCreateEvent(&EventHandle,
106                          EVENT_ALL_ACCESS,
107                          &ObjectAttributes,
108                          FALSE,
109                          FALSE);
110   if (!NT_SUCCESS(Status))
111     {
112       DPRINT1("Failed to create 'Security' directory!\n");
113       NtClose(DirectoryHandle);
114       return(FALSE);
115     }
116
117   NtClose(EventHandle);
118   NtClose(DirectoryHandle);
119 #endif /* LIBCAPTIVE */
120
121   /* FIXME: Create SRM port and listener thread */
122
123   return(TRUE);
124 }
125
126
127 static BOOLEAN
128 SepInitExports(VOID)
129 {
130   SeExports = ExAllocatePoolWithTag(NonPagedPool,
131                                     sizeof(SE_EXPORTS),
132                                     TAG_SXPT);
133   if (SeExports == NULL)
134     return(FALSE);
135
136   SeExports->SeCreateTokenPrivilege = SeCreateTokenPrivilege;
137   SeExports->SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
138   SeExports->SeLockMemoryPrivilege = SeLockMemoryPrivilege;
139   SeExports->SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
140   SeExports->SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
141   SeExports->SeTcbPrivilege = SeTcbPrivilege;
142   SeExports->SeSecurityPrivilege = SeSecurityPrivilege;
143   SeExports->SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
144   SeExports->SeLoadDriverPrivilege = SeLoadDriverPrivilege;
145   SeExports->SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
146   SeExports->SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
147   SeExports->SeSystemProfilePrivilege = SeSystemProfilePrivilege;
148   SeExports->SeSystemtimePrivilege = SeSystemtimePrivilege;
149   SeExports->SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
150   SeExports->SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
151   SeExports->SeBackupPrivilege = SeBackupPrivilege;
152   SeExports->SeRestorePrivilege = SeRestorePrivilege;
153   SeExports->SeShutdownPrivilege = SeShutdownPrivilege;
154   SeExports->SeDebugPrivilege = SeDebugPrivilege;
155   SeExports->SeAuditPrivilege = SeAuditPrivilege;
156   SeExports->SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
157   SeExports->SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
158   SeExports->SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
159
160   SeExports->SeNullSid = SeNullSid;
161   SeExports->SeWorldSid = SeWorldSid;
162   SeExports->SeLocalSid = SeLocalSid;
163   SeExports->SeCreatorOwnerSid = SeCreatorOwnerSid;
164   SeExports->SeCreatorGroupSid = SeCreatorGroupSid;
165   SeExports->SeNtAuthoritySid = SeNtAuthoritySid;
166   SeExports->SeDialupSid = SeDialupSid;
167   SeExports->SeNetworkSid = SeNetworkSid;
168   SeExports->SeBatchSid = SeBatchSid;
169   SeExports->SeInteractiveSid = SeInteractiveSid;
170   SeExports->SeLocalSystemSid = SeLocalSystemSid;
171   SeExports->SeAliasAdminsSid = SeAliasAdminsSid;
172   SeExports->SeAliasUsersSid = SeAliasUsersSid;
173   SeExports->SeAliasGuestsSid = SeAliasGuestsSid;
174   SeExports->SeAliasPowerUsersSid = SeAliasPowerUsersSid;
175   SeExports->SeAliasAccountOpsSid = SeAliasAccountOpsSid;
176   SeExports->SeAliasSystemOpsSid = SeAliasSystemOpsSid;
177   SeExports->SeAliasPrintOpsSid = SeAliasPrintOpsSid;
178   SeExports->SeAliasBackupOpsSid = SeAliasBackupOpsSid;
179
180   return(TRUE);
181 }
182
183 #ifndef LIBCAPTIVE
184
185 VOID SepReferenceLogonSession(PLUID AuthenticationId)
186 {
187    UNIMPLEMENTED;
188 }
189
190 VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
191 {
192    UNIMPLEMENTED;
193 }
194
195
196
197 /*
198  * @unimplemented
199  */
200 NTSTATUS STDCALL
201 NtAllocateUuids(PULARGE_INTEGER Time,
202                 PULONG Range,
203                 PULONG Sequence)
204 {
205   UNIMPLEMENTED;
206 }
207
208
209 NTSTATUS STDCALL
210 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
211               IN HANDLE ClientToken,
212               IN ACCESS_MASK DesiredAccess,
213               IN PGENERIC_MAPPING GenericMapping,
214               OUT PPRIVILEGE_SET PrivilegeSet,
215               OUT PULONG ReturnLength,
216               OUT PULONG GrantedAccess,
217               OUT PBOOLEAN AccessStatus)
218 {
219   UNIMPLEMENTED;
220 }
221
222
223 NTSTATUS STDCALL
224 NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
225                          IN PVOID HandleId,
226                          IN BOOLEAN GenerateOnClose)
227 {
228   UNIMPLEMENTED;
229 }
230
231
232 #endif /* LIBCAPTIVE */
233
234 /*
235  * @implemented
236  */
237 VOID STDCALL SeReleaseSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
238 {
239    ObDereferenceObject(SubjectContext->PrimaryToken);
240    if (SubjectContext->ClientToken != NULL)
241      {
242         ObDereferenceObject(SubjectContext->ClientToken);
243      }   
244 }
245
246 /*
247  * @implemented
248  */
249 VOID STDCALL SeCaptureSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
250 {
251    PEPROCESS Process;
252    ULONG a;
253    ULONG b;
254    
255    Process = PsGetCurrentThread()->ThreadsProcess;
256    
257    SubjectContext->ProcessAuditId = Process;
258    SubjectContext->ClientToken = 
259      PsReferenceImpersonationToken(PsGetCurrentThread(),
260                                    &a,
261                                    &b,
262                                    &SubjectContext->ImpersonationLevel);
263    SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
264 }
265
266
267 /*
268  * @implemented
269  */
270 NTSTATUS STDCALL
271 SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
272 {
273   if ((*SecurityDescriptor) != NULL)
274     {
275       ExFreePool(*SecurityDescriptor);
276       (*SecurityDescriptor) = NULL;
277     }
278   return(STATUS_SUCCESS);
279 }
280
281 #ifndef LIBCAPTIVE
282
283 #if 0
284 VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
285                                   PSID* Owner,
286                                   PSID* PrimaryGroup,
287                                   PSID* ProcessOwner,
288                                   PSID* ProcessPrimaryGroup,
289                                   PACL* DefaultDacl)
290 {
291    PACCESS_TOKEN Token;
292    
293    if (SubjectContext->ClientToken != NULL)
294      {
295         Token = SubjectContext->ClientToken;
296      }
297    else
298      {
299         Token = SubjectContext->PrimaryToken;
300      }
301    *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
302    *PrimaryGroup = Token->PrimaryGroup;
303    *DefaultDacl = Token->DefaultDacl;
304    *ProcessOwner = SubjectContext->PrimaryToken->
305      UserAndGroups[Token->DefaultOwnerIndex].Sid;
306    *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
307 }
308
309 NTSTATUS SepInheritAcl(PACL Acl,
310                        BOOLEAN IsDirectoryObject,
311                        PSID Owner,
312                        PSID PrimaryGroup,
313                        PACL DefaultAcl,
314                        PSID ProcessOwner,
315                        PSID ProcessGroup,
316                        PGENERIC_MAPPING GenericMapping)
317 {
318    if (Acl == NULL)
319      {
320         return(STATUS_UNSUCCESSFUL);
321      }
322    if (Acl->AclRevision != 2 &&
323        Acl->AclRevision != 3 )
324      {
325         return(STATUS_UNSUCCESSFUL);
326      }
327    
328 }
329 #endif
330
331 /*
332  * @unimplemented
333  */
334 NTSTATUS STDCALL
335 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
336                  PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
337                  PSECURITY_DESCRIPTOR* NewDescriptor,
338                  BOOLEAN IsDirectoryObject,
339                  PSECURITY_SUBJECT_CONTEXT SubjectContext,
340                  PGENERIC_MAPPING GenericMapping,
341                  POOL_TYPE PoolType)
342 {
343 #if 0
344    PSECURITY_DESCRIPTOR Descriptor;
345    PSID Owner;
346    PSID PrimaryGroup;
347    PACL DefaultDacl;
348    PSID ProcessOwner;
349    PSID ProcessPrimaryGroup;
350    PACL Sacl;
351    
352    if (ExplicitDescriptor == NULL)
353      {
354         RtlCreateSecurityDescriptor(&Descriptor, 1);
355      }
356    else
357      {
358         Descriptor = ExplicitDescriptor;
359      }
360    SeLockSubjectContext(SubjectContext);
361    SepGetDefaultsSubjectContext(SubjectContext,
362                                 &Owner,
363                                 &PrimaryGroup,
364                                 &DefaultDacl,
365                                 &ProcessOwner,
366                                 &ProcessPrimaryGroup);
367    if (Descriptor->Control & SE_SACL_PRESENT ||
368        Descriptor->Control & SE_SACL_DEFAULTED)
369      {
370         if (ParentDescriptor == NULL)
371           {
372           }
373         if (Descriptor->Control & SE_SACL_PRESENT ||
374             Descriptor->Sacl == NULL ||)
375           {
376              Sacl = NULL;            
377           }
378         else
379           {
380              Sacl = Descriptor->Sacl;
381              if (Descriptor->Control & SE_SELF_RELATIVE)
382                {
383                   Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
384                }
385           }
386         SepInheritAcl(Sacl,
387                       IsDirectoryObject,
388                       Owner,
389                       PrimaryGroup,
390                       DefaultDacl,
391                       ProcessOwner,
392                       GenericMapping);
393      }
394 #else
395   UNIMPLEMENTED;
396 #endif
397 }
398
399 BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
400                       PSID Sid)
401 {
402    ULONG i;
403    
404    if (Token->UserAndGroupCount == 0)
405      {
406         return(FALSE);
407      }
408    
409    for (i=0; i<Token->UserAndGroupCount; i++)
410      {
411         if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
412           {
413              if (i == 0 ||
414                  (!(Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)))
415                {
416                   return(TRUE);
417                }
418              return(FALSE);
419           }
420      }
421    return(FALSE);
422 }
423
424
425 /*
426  * @implemented
427  */
428 BOOLEAN STDCALL
429 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
430               IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
431               IN BOOLEAN SubjectContextLocked,
432               IN ACCESS_MASK DesiredAccess,
433               IN ACCESS_MASK PreviouslyGrantedAccess,
434               OUT PPRIVILEGE_SET* Privileges,
435               IN PGENERIC_MAPPING GenericMapping,
436               IN KPROCESSOR_MODE AccessMode,
437               OUT PACCESS_MODE GrantedAccess,
438               OUT PNTSTATUS AccessStatus)
439 /*
440  * FUNCTION: Determines whether the requested access rights can be granted
441  * to an object protected by a security descriptor and an object owner
442  * ARGUMENTS:
443  *      SecurityDescriptor = Security descriptor protecting the object
444  *      SubjectSecurityContext = Subject's captured security context
445  *      SubjectContextLocked = Indicates the user's subject context is locked
446  *      DesiredAccess = Access rights the caller is trying to acquire
447  *      PreviouslyGrantedAccess = Specified the access rights already granted
448  *      Privileges = ?
449  *      GenericMapping = Generic mapping associated with the object
450  *      AccessMode = Access mode used for the check
451  *      GrantedAccess (OUT) = On return specifies the access granted
452  *      AccessStatus (OUT) = Status indicating why access was denied
453  * RETURNS: If access was granted, returns TRUE
454  */
455 {
456    ULONG i;
457    PACL Dacl;
458    BOOLEAN Present;
459    BOOLEAN Defaulted;
460    NTSTATUS Status;
461    PACE CurrentAce;
462    PSID Sid;
463    ACCESS_MASK CurrentAccess;
464    
465    CurrentAccess = PreviouslyGrantedAccess;
466    
467    /*    
468     * Ignore the SACL for now
469     */
470    
471    /*
472     * Check the DACL
473     */
474    Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
475                                          &Present,
476                                          &Dacl,
477                                          &Defaulted);
478    if (!NT_SUCCESS(Status))
479      {
480         return(Status);
481      }
482    
483    CurrentAce = (PACE)(Dacl + 1);
484    for (i = 0; i < Dacl->AceCount; i++)
485      {
486         Sid = (PSID)(CurrentAce + 1);
487         if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
488           {
489              if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
490                {
491                   *AccessStatus = STATUS_ACCESS_DENIED;
492                   *GrantedAccess = 0;
493                   return(STATUS_SUCCESS);
494                }
495           }
496         if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
497           {
498              if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
499                {
500                   CurrentAccess = CurrentAccess | 
501                     CurrentAce->AccessMask;
502                }
503           }
504      }
505    if (!(CurrentAccess & DesiredAccess) &&
506        !((~CurrentAccess) & DesiredAccess))
507      {
508         *AccessStatus = STATUS_ACCESS_DENIED;   
509      }
510    else
511      {
512         *AccessStatus = STATUS_SUCCESS;
513      }
514    *GrantedAccess = CurrentAccess;
515    
516    return(STATUS_SUCCESS);
517 }
518
519 #endif /* LIBCAPTIVE */
520
521 /* EOF */