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