branch update for HEAD-2003050101
[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 NTSTATUS STDCALL
196 NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName,
197                               IN PUNICODE_STRING ServiceName,
198                               IN HANDLE ClientToken,
199                               IN PPRIVILEGE_SET Privileges,
200                               IN BOOLEAN AccessGranted)
201 {
202   UNIMPLEMENTED;
203 }
204
205
206 NTSTATUS STDCALL
207 NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
208                             IN PVOID HandleId,
209                             IN HANDLE ClientToken,
210                             IN ULONG DesiredAccess,
211                             IN PPRIVILEGE_SET Privileges,
212                             IN BOOLEAN AccessGranted)
213 {
214   UNIMPLEMENTED;
215 }
216
217
218 NTSTATUS STDCALL
219 NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
220                        IN PVOID HandleId,
221                        IN POBJECT_ATTRIBUTES ObjectAttributes,
222                        IN HANDLE ClientToken,
223                        IN ULONG DesiredAccess,
224                        IN ULONG GrantedAccess,
225                        IN PPRIVILEGE_SET Privileges,
226                        IN BOOLEAN ObjectCreation,
227                        IN BOOLEAN AccessGranted,
228                        OUT PBOOLEAN GenerateOnClose)
229 {
230   UNIMPLEMENTED;
231 }
232
233
234 NTSTATUS STDCALL
235 NtAccessCheckAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
236                            IN PHANDLE ObjectHandle,
237                            IN POBJECT_ATTRIBUTES ObjectAttributes,
238                            IN ACCESS_MASK DesiredAccess,
239                            IN PGENERIC_MAPPING GenericMapping,
240                            IN BOOLEAN ObjectCreation,
241                            OUT PULONG GrantedAccess,
242                            OUT PBOOLEAN AccessStatus,
243                            OUT PBOOLEAN GenerateOnClose
244         )
245 {
246   UNIMPLEMENTED;
247 }
248
249
250 NTSTATUS STDCALL
251 NtAllocateUuids(PULARGE_INTEGER Time,
252                 PULONG Range,
253                 PULONG Sequence)
254 {
255   UNIMPLEMENTED;
256 }
257
258
259 NTSTATUS STDCALL
260 NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
261                         IN PVOID HandleId,
262                         IN BOOLEAN GenerateOnClose)
263 {
264   UNIMPLEMENTED;
265 }
266
267
268 NTSTATUS STDCALL
269 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
270               IN HANDLE ClientToken,
271               IN ACCESS_MASK DesiredAccess,
272               IN PGENERIC_MAPPING GenericMapping,
273               OUT PPRIVILEGE_SET PrivilegeSet,
274               OUT PULONG ReturnLength,
275               OUT PULONG GrantedAccess,
276               OUT PBOOLEAN AccessStatus)
277 {
278   UNIMPLEMENTED;
279 }
280
281
282 NTSTATUS STDCALL
283 NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
284                          IN PVOID HandleId,
285                          IN BOOLEAN GenerateOnClose)
286 {
287   UNIMPLEMENTED;
288 }
289
290
291 #endif /* LIBCAPTIVE */
292
293 VOID STDCALL SeReleaseSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
294 {
295    ObDereferenceObject(SubjectContext->PrimaryToken);
296    if (SubjectContext->ClientToken != NULL)
297      {
298         ObDereferenceObject(SubjectContext->ClientToken);
299      }   
300 }
301
302
303 VOID STDCALL SeCaptureSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
304 {
305    PEPROCESS Process;
306    ULONG a;
307    ULONG b;
308    
309    Process = PsGetCurrentThread()->ThreadsProcess;
310    
311    SubjectContext->ProcessAuditId = Process;
312    SubjectContext->ClientToken = 
313      PsReferenceImpersonationToken(PsGetCurrentThread(),
314                                    &a,
315                                    &b,
316                                    &SubjectContext->ImpersonationLevel);
317    SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
318 }
319
320
321 NTSTATUS STDCALL
322 SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
323 {
324   if ((*SecurityDescriptor) != NULL)
325     {
326       ExFreePool(*SecurityDescriptor);
327       (*SecurityDescriptor) = NULL;
328     }
329   return(STATUS_SUCCESS);
330 }
331
332 #ifndef LIBCAPTIVE
333
334 #if 0
335 VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
336                                   PSID* Owner,
337                                   PSID* PrimaryGroup,
338                                   PSID* ProcessOwner,
339                                   PSID* ProcessPrimaryGroup,
340                                   PACL* DefaultDacl)
341 {
342    PACCESS_TOKEN Token;
343    
344    if (SubjectContext->ClientToken != NULL)
345      {
346         Token = SubjectContext->ClientToken;
347      }
348    else
349      {
350         Token = SubjectContext->PrimaryToken;
351      }
352    *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
353    *PrimaryGroup = Token->PrimaryGroup;
354    *DefaultDacl = Token->DefaultDacl;
355    *ProcessOwner = SubjectContext->PrimaryToken->
356      UserAndGroups[Token->DefaultOwnerIndex].Sid;
357    *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
358 }
359
360 NTSTATUS SepInheritAcl(PACL Acl,
361                        BOOLEAN IsDirectoryObject,
362                        PSID Owner,
363                        PSID PrimaryGroup,
364                        PACL DefaultAcl,
365                        PSID ProcessOwner,
366                        PSID ProcessGroup,
367                        PGENERIC_MAPPING GenericMapping)
368 {
369    if (Acl == NULL)
370      {
371         return(STATUS_UNSUCCESSFUL);
372      }
373    if (Acl->AclRevision != 2 &&
374        Acl->AclRevision != 3 )
375      {
376         return(STATUS_UNSUCCESSFUL);
377      }
378    
379 }
380 #endif
381
382 NTSTATUS STDCALL
383 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
384                  PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
385                  PSECURITY_DESCRIPTOR* NewDescriptor,
386                  BOOLEAN IsDirectoryObject,
387                  PSECURITY_SUBJECT_CONTEXT SubjectContext,
388                  PGENERIC_MAPPING GenericMapping,
389                  POOL_TYPE PoolType)
390 {
391 #if 0
392    PSECURITY_DESCRIPTOR Descriptor;
393    PSID Owner;
394    PSID PrimaryGroup;
395    PACL DefaultDacl;
396    PSID ProcessOwner;
397    PSID ProcessPrimaryGroup;
398    PACL Sacl;
399    
400    if (ExplicitDescriptor == NULL)
401      {
402         RtlCreateSecurityDescriptor(&Descriptor, 1);
403      }
404    else
405      {
406         Descriptor = ExplicitDescriptor;
407      }
408    SeLockSubjectContext(SubjectContext);
409    SepGetDefaultsSubjectContext(SubjectContext,
410                                 &Owner,
411                                 &PrimaryGroup,
412                                 &DefaultDacl,
413                                 &ProcessOwner,
414                                 &ProcessPrimaryGroup);
415    if (Descriptor->Control & SE_SACL_PRESENT ||
416        Descriptor->Control & SE_SACL_DEFAULTED)
417      {
418         if (ParentDescriptor == NULL)
419           {
420           }
421         if (Descriptor->Control & SE_SACL_PRESENT ||
422             Descriptor->Sacl == NULL ||)
423           {
424              Sacl = NULL;            
425           }
426         else
427           {
428              Sacl = Descriptor->Sacl;
429              if (Descriptor->Control & SE_SELF_RELATIVE)
430                {
431                   Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
432                }
433           }
434         SepInheritAcl(Sacl,
435                       IsDirectoryObject,
436                       Owner,
437                       PrimaryGroup,
438                       DefaultDacl,
439                       ProcessOwner,
440                       GenericMapping);
441      }
442 #else
443   UNIMPLEMENTED;
444 #endif
445 }
446
447 BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
448                       PSID Sid)
449 {
450    ULONG i;
451    
452    if (Token->UserAndGroupCount == 0)
453      {
454         return(FALSE);
455      }
456    
457    for (i=0; i<Token->UserAndGroupCount; i++)
458      {
459         if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
460           {
461              if (i == 0 ||
462                  (!(Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)))
463                {
464                   return(TRUE);
465                }
466              return(FALSE);
467           }
468      }
469    return(FALSE);
470 }
471
472
473 BOOLEAN STDCALL
474 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
475               IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
476               IN BOOLEAN SubjectContextLocked,
477               IN ACCESS_MASK DesiredAccess,
478               IN ACCESS_MASK PreviouslyGrantedAccess,
479               OUT PPRIVILEGE_SET* Privileges,
480               IN PGENERIC_MAPPING GenericMapping,
481               IN KPROCESSOR_MODE AccessMode,
482               OUT PACCESS_MODE GrantedAccess,
483               OUT PNTSTATUS AccessStatus)
484 /*
485  * FUNCTION: Determines whether the requested access rights can be granted
486  * to an object protected by a security descriptor and an object owner
487  * ARGUMENTS:
488  *      SecurityDescriptor = Security descriptor protecting the object
489  *      SubjectSecurityContext = Subject's captured security context
490  *      SubjectContextLocked = Indicates the user's subject context is locked
491  *      DesiredAccess = Access rights the caller is trying to acquire
492  *      PreviouslyGrantedAccess = Specified the access rights already granted
493  *      Privileges = ?
494  *      GenericMapping = Generic mapping associated with the object
495  *      AccessMode = Access mode used for the check
496  *      GrantedAccess (OUT) = On return specifies the access granted
497  *      AccessStatus (OUT) = Status indicating why access was denied
498  * RETURNS: If access was granted, returns TRUE
499  */
500 {
501    ULONG i;
502    PACL Dacl;
503    BOOLEAN Present;
504    BOOLEAN Defaulted;
505    NTSTATUS Status;
506    PACE CurrentAce;
507    PSID Sid;
508    ACCESS_MASK CurrentAccess;
509    
510    CurrentAccess = PreviouslyGrantedAccess;
511    
512    /*    
513     * Ignore the SACL for now
514     */
515    
516    /*
517     * Check the DACL
518     */
519    Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
520                                          &Present,
521                                          &Dacl,
522                                          &Defaulted);
523    if (!NT_SUCCESS(Status))
524      {
525         return(Status);
526      }
527    
528    CurrentAce = (PACE)(Dacl + 1);
529    for (i = 0; i < Dacl->AceCount; i++)
530      {
531         Sid = (PSID)(CurrentAce + 1);
532         if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
533           {
534              if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
535                {
536                   *AccessStatus = STATUS_ACCESS_DENIED;
537                   *GrantedAccess = 0;
538                   return(STATUS_SUCCESS);
539                }
540           }
541         if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
542           {
543              if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
544                {
545                   CurrentAccess = CurrentAccess | 
546                     CurrentAce->AccessMask;
547                }
548           }
549      }
550    if (!(CurrentAccess & DesiredAccess) &&
551        !((~CurrentAccess) & DesiredAccess))
552      {
553         *AccessStatus = STATUS_ACCESS_DENIED;   
554      }
555    else
556      {
557         *AccessStatus = STATUS_SUCCESS;
558      }
559    *GrantedAccess = CurrentAccess;
560    
561    return(STATUS_SUCCESS);
562 }
563
564 #endif /* LIBCAPTIVE */
565
566 /* EOF */