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