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