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