105c6426f42e883d3fad9cc6bee033b9126f1b52
[reactos.git] / reactos / ntoskrnl / se / semgr.c
1 /* $Id: semgr.c,v 1.37 2004/07/21 23:38:15 ekohl Exp $
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 #define NDEBUG
19 #include <internal/debug.h>
20
21 #define TAG_SXPT TAG('S', 'X', 'P', 'T')
22
23
24 /* GLOBALS ******************************************************************/
25
26 PSE_EXPORTS EXPORTED SeExports = NULL;
27
28
29 /* PROTOTYPES ***************************************************************/
30
31 static BOOLEAN SepInitExports(VOID);
32
33 /* FUNCTIONS ****************************************************************/
34
35
36 BOOLEAN INIT_FUNCTION
37 SeInit1(VOID)
38 {
39 SepInitLuid();
40
41 if (!SepInitSecurityIDs())
42 return FALSE;
43
44 if (!SepInitDACLs())
45 return FALSE;
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 INIT_FUNCTION
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 HANDLE EventHandle;
75 NTSTATUS Status;
76
77 /* Create '\Security' directory */
78 RtlInitUnicodeString(&Name,
79 L"\\Security");
80 InitializeObjectAttributes(&ObjectAttributes,
81 &Name,
82 OBJ_PERMANENT,
83 0,
84 NULL);
85 Status = NtCreateDirectoryObject(&DirectoryHandle,
86 DIRECTORY_ALL_ACCESS,
87 &ObjectAttributes);
88 if (!NT_SUCCESS(Status))
89 {
90 DPRINT1("Failed to create 'Security' directory!\n");
91 return FALSE;
92 }
93
94 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
95 RtlInitUnicodeString(&Name,
96 L"\\LSA_AUTHENTICATION_INITALIZED");
97 InitializeObjectAttributes(&ObjectAttributes,
98 &Name,
99 OBJ_PERMANENT,
100 DirectoryHandle,
101 SePublicDefaultSd);
102 Status = NtCreateEvent(&EventHandle,
103 EVENT_ALL_ACCESS,
104 &ObjectAttributes,
105 FALSE,
106 FALSE);
107 if (!NT_SUCCESS(Status))
108 {
109 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
110 NtClose(DirectoryHandle);
111 return FALSE;
112 }
113
114 NtClose(EventHandle);
115 NtClose(DirectoryHandle);
116
117 /* FIXME: Create SRM port and listener thread */
118
119 return TRUE;
120 }
121
122
123 static BOOLEAN INIT_FUNCTION
124 SepInitExports(VOID)
125 {
126 SeExports = ExAllocatePoolWithTag(NonPagedPool,
127 sizeof(SE_EXPORTS),
128 TAG_SXPT);
129 if (SeExports == NULL)
130 return FALSE;
131
132 SeExports->SeCreateTokenPrivilege = SeCreateTokenPrivilege;
133 SeExports->SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
134 SeExports->SeLockMemoryPrivilege = SeLockMemoryPrivilege;
135 SeExports->SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
136 SeExports->SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
137 SeExports->SeTcbPrivilege = SeTcbPrivilege;
138 SeExports->SeSecurityPrivilege = SeSecurityPrivilege;
139 SeExports->SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
140 SeExports->SeLoadDriverPrivilege = SeLoadDriverPrivilege;
141 SeExports->SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
142 SeExports->SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
143 SeExports->SeSystemProfilePrivilege = SeSystemProfilePrivilege;
144 SeExports->SeSystemtimePrivilege = SeSystemtimePrivilege;
145 SeExports->SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
146 SeExports->SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
147 SeExports->SeBackupPrivilege = SeBackupPrivilege;
148 SeExports->SeRestorePrivilege = SeRestorePrivilege;
149 SeExports->SeShutdownPrivilege = SeShutdownPrivilege;
150 SeExports->SeDebugPrivilege = SeDebugPrivilege;
151 SeExports->SeAuditPrivilege = SeAuditPrivilege;
152 SeExports->SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
153 SeExports->SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
154 SeExports->SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
155
156 SeExports->SeNullSid = SeNullSid;
157 SeExports->SeWorldSid = SeWorldSid;
158 SeExports->SeLocalSid = SeLocalSid;
159 SeExports->SeCreatorOwnerSid = SeCreatorOwnerSid;
160 SeExports->SeCreatorGroupSid = SeCreatorGroupSid;
161 SeExports->SeNtAuthoritySid = SeNtAuthoritySid;
162 SeExports->SeDialupSid = SeDialupSid;
163 SeExports->SeNetworkSid = SeNetworkSid;
164 SeExports->SeBatchSid = SeBatchSid;
165 SeExports->SeInteractiveSid = SeInteractiveSid;
166 SeExports->SeLocalSystemSid = SeLocalSystemSid;
167 SeExports->SeAliasAdminsSid = SeAliasAdminsSid;
168 SeExports->SeAliasUsersSid = SeAliasUsersSid;
169 SeExports->SeAliasGuestsSid = SeAliasGuestsSid;
170 SeExports->SeAliasPowerUsersSid = SeAliasPowerUsersSid;
171 SeExports->SeAliasAccountOpsSid = SeAliasAccountOpsSid;
172 SeExports->SeAliasSystemOpsSid = SeAliasSystemOpsSid;
173 SeExports->SeAliasPrintOpsSid = SeAliasPrintOpsSid;
174 SeExports->SeAliasBackupOpsSid = SeAliasBackupOpsSid;
175
176 return TRUE;
177 }
178
179
180 VOID SepReferenceLogonSession(PLUID AuthenticationId)
181 {
182 UNIMPLEMENTED;
183 }
184
185 VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
186 {
187 UNIMPLEMENTED;
188 }
189
190
191
192 /*
193 * @unimplemented
194 */
195 NTSTATUS STDCALL
196 NtAllocateUuids(PULARGE_INTEGER Time,
197 PULONG Range,
198 PULONG Sequence)
199 {
200 UNIMPLEMENTED;
201 return(STATUS_NOT_IMPLEMENTED);
202 }
203
204
205 /*
206 * @implemented
207 */
208 VOID STDCALL
209 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
210 {
211 PETHREAD Thread;
212 BOOLEAN CopyOnOpen;
213 BOOLEAN EffectiveOnly;
214
215 Thread = PsGetCurrentThread();
216 if (Thread == NULL)
217 {
218 SubjectContext->ProcessAuditId = 0;
219 SubjectContext->PrimaryToken = NULL;
220 SubjectContext->ClientToken = NULL;
221 SubjectContext->ImpersonationLevel = 0;
222 }
223 else
224 {
225 SubjectContext->ProcessAuditId = Thread->ThreadsProcess;
226 SubjectContext->ClientToken =
227 PsReferenceImpersonationToken(Thread,
228 &CopyOnOpen,
229 &EffectiveOnly,
230 &SubjectContext->ImpersonationLevel);
231 SubjectContext->PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
232 }
233 }
234
235
236 /*
237 * @unimplemented
238 */
239 VOID STDCALL
240 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
241 {
242 UNIMPLEMENTED;
243 }
244
245
246 /*
247 * @implemented
248 */
249 VOID STDCALL
250 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
251 {
252 if (SubjectContext->PrimaryToken != NULL)
253 {
254 ObDereferenceObject(SubjectContext->PrimaryToken);
255 }
256
257 if (SubjectContext->ClientToken != NULL)
258 {
259 ObDereferenceObject(SubjectContext->ClientToken);
260 }
261 }
262
263
264 /*
265 * @unimplemented
266 */
267 VOID STDCALL
268 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
269 {
270 UNIMPLEMENTED;
271 }
272
273
274 /*
275 * @implemented
276 */
277 NTSTATUS STDCALL
278 SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
279 {
280 if (*SecurityDescriptor != NULL)
281 {
282 ExFreePool(*SecurityDescriptor);
283 *SecurityDescriptor = NULL;
284 }
285
286 return STATUS_SUCCESS;
287 }
288
289
290 /*
291 * @unimplemented
292 */
293 NTSTATUS STDCALL
294 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
295 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
296 PSECURITY_DESCRIPTOR *NewDescriptor,
297 BOOLEAN IsDirectoryObject,
298 PSECURITY_SUBJECT_CONTEXT SubjectContext,
299 PGENERIC_MAPPING GenericMapping,
300 POOL_TYPE PoolType)
301 {
302 PSECURITY_DESCRIPTOR Descriptor;
303 PACCESS_TOKEN Token;
304 ULONG OwnerLength = 0;
305 ULONG GroupLength = 0;
306 ULONG DaclLength = 0;
307 ULONG SaclLength = 0;
308 ULONG Length = 0;
309 ULONG Control = 0;
310 ULONG Current;
311 PSID Owner = NULL;
312 PSID Group = NULL;
313 PACL Dacl = NULL;
314 PACL Sacl = NULL;
315
316 /* FIXME: Lock subject context */
317
318 if (SubjectContext->ClientToken != NULL)
319 {
320 Token = SubjectContext->ClientToken;
321 }
322 else
323 {
324 Token = SubjectContext->PrimaryToken;
325 }
326
327
328 /* Inherit the Owner SID */
329 if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
330 {
331 DPRINT("Use explicit owner sid!\n");
332 Owner = ExplicitDescriptor->Owner;
333 if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
334 {
335 Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
336 }
337 }
338 else
339 {
340 if (Token != NULL)
341 {
342 DPRINT("Use token owner sid!\n");
343 Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
344 }
345 else
346 {
347 DPRINT("Use default owner sid!\n");
348 Owner = SeLocalSystemSid;
349 }
350
351 Control |= SE_OWNER_DEFAULTED;
352 }
353
354 OwnerLength = RtlLengthSid(Owner);
355
356
357 /* Inherit the Group SID */
358 if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
359 {
360 DPRINT("Use explicit group sid!\n");
361 Group = ExplicitDescriptor->Group;
362 if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
363 {
364 Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
365 }
366 }
367 else
368 {
369 if (Token != NULL)
370 {
371 DPRINT("Use token group sid!\n");
372 Group = Token->PrimaryGroup;
373 }
374 else
375 {
376 DPRINT("Use default group sid!\n");
377 Group = SeLocalSystemSid;
378 }
379
380 Control |= SE_OWNER_DEFAULTED;
381 }
382
383 GroupLength = RtlLengthSid(Group);
384
385
386 /* Inherit the DACL */
387 if (ExplicitDescriptor != NULL &&
388 (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
389 !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
390 {
391 DPRINT("Use explicit DACL!\n");
392 Dacl = ExplicitDescriptor->Dacl;
393 if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
394 {
395 Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
396 }
397
398 Control |= SE_DACL_PRESENT;
399 }
400 else if (ParentDescriptor != NULL &&
401 (ParentDescriptor->Control & SE_DACL_PRESENT))
402 {
403 DPRINT("Use parent DACL!\n");
404 /* FIXME: Inherit */
405 Dacl = ParentDescriptor->Dacl;
406 if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
407 {
408 Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor);
409 }
410 Control |= SE_DACL_PRESENT;
411 }
412 else if (Token != NULL && Token->DefaultDacl != NULL)
413 {
414 DPRINT("Use token default DACL!\n");
415 /* FIXME: Inherit */
416 Dacl = Token->DefaultDacl;
417 Control |= SE_DACL_PRESENT;
418 }
419 else
420 {
421 DPRINT("Use NULL DACL!\n");
422 Dacl = NULL;
423 Control |= SE_DACL_PRESENT;
424 }
425
426 DaclLength = (Dacl != NULL) ? Dacl->AclSize : 0;
427
428
429
430 /* Inherit the SACL */
431 /* FIXME */
432 #if 0
433 if (ExplicitDescriptor != NULL && (ExplicitDescriptor->Control & SE_SACL_PRESENT))
434 {
435 DPRINT("Use explicit SACL!\n");
436 Sacl = ExplicitDescriptor->Sacl;
437 if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
438 {
439 Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
440 }
441
442 Control |= SE_SACL_PRESENT;
443 SaclLength = Sacl->AclSize;
444 }
445 else
446 {
447 DPRINT("No SACL!\n");
448 SaclLength = 0;
449 }
450 #endif
451
452
453 /* Allocate and initialize the new security descriptor */
454 Length = sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength;
455
456 Descriptor = ExAllocatePool(NonPagedPool,
457 Length);
458 if (Descriptor == NULL)
459 {
460 DPRINT1("ExAlloctePool() failed\n");
461 /* FIXME: Unlock subject context */
462 return STATUS_INSUFFICIENT_RESOURCES;
463 }
464
465 RtlCreateSecurityDescriptor(Descriptor,
466 SECURITY_DESCRIPTOR_REVISION);
467
468 Descriptor->Control = Control | SE_SELF_RELATIVE;
469
470 Current = (ULONG)Descriptor + sizeof(SECURITY_DESCRIPTOR);
471
472 if (SaclLength != 0)
473 {
474 RtlCopyMemory((PVOID)Current,
475 Sacl,
476 SaclLength);
477 Descriptor->Sacl = (PACL)((ULONG)Current - (ULONG)Descriptor);
478 Current += SaclLength;
479 }
480
481 if (DaclLength != 0)
482 {
483 RtlCopyMemory((PVOID)Current,
484 Dacl,
485 DaclLength);
486 Descriptor->Dacl = (PACL)((ULONG)Current - (ULONG)Descriptor);
487 Current += DaclLength;
488 }
489
490 if (OwnerLength != 0)
491 {
492 RtlCopyMemory((PVOID)Current,
493 Owner,
494 OwnerLength);
495 Descriptor->Owner = (PSID)((ULONG)Current - (ULONG)Descriptor);
496 Current += OwnerLength;
497 }
498
499 if (GroupLength != 0)
500 {
501 memmove((PVOID)Current,
502 Group,
503 GroupLength);
504 Descriptor->Group = (PSID)((ULONG)Current - (ULONG)Descriptor);
505 }
506
507 /* FIXME: Unlock subject context */
508
509 *NewDescriptor = Descriptor;
510
511 return STATUS_SUCCESS;
512 }
513
514
515 static BOOLEAN
516 SepSidInToken(PACCESS_TOKEN Token,
517 PSID Sid)
518 {
519 ULONG i;
520
521 if (Token->UserAndGroupCount == 0)
522 {
523 return FALSE;
524 }
525
526 for (i=0; i<Token->UserAndGroupCount; i++)
527 {
528 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
529 {
530 if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
531 {
532 return TRUE;
533 }
534
535 return FALSE;
536 }
537 }
538
539 return FALSE;
540 }
541
542
543 /*
544 * FUNCTION: Determines whether the requested access rights can be granted
545 * to an object protected by a security descriptor and an object owner
546 * ARGUMENTS:
547 * SecurityDescriptor = Security descriptor protecting the object
548 * SubjectSecurityContext = Subject's captured security context
549 * SubjectContextLocked = Indicates the user's subject context is locked
550 * DesiredAccess = Access rights the caller is trying to acquire
551 * PreviouslyGrantedAccess = Specified the access rights already granted
552 * Privileges = ?
553 * GenericMapping = Generic mapping associated with the object
554 * AccessMode = Access mode used for the check
555 * GrantedAccess (OUT) = On return specifies the access granted
556 * AccessStatus (OUT) = Status indicating why access was denied
557 * RETURNS: If access was granted, returns TRUE
558 *
559 * @implemented
560 */
561 BOOLEAN STDCALL
562 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
563 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
564 IN BOOLEAN SubjectContextLocked,
565 IN ACCESS_MASK DesiredAccess,
566 IN ACCESS_MASK PreviouslyGrantedAccess,
567 OUT PPRIVILEGE_SET* Privileges,
568 IN PGENERIC_MAPPING GenericMapping,
569 IN KPROCESSOR_MODE AccessMode,
570 OUT PACCESS_MASK GrantedAccess,
571 OUT PNTSTATUS AccessStatus)
572 {
573 LUID_AND_ATTRIBUTES Privilege;
574 ACCESS_MASK CurrentAccess;
575 PACCESS_TOKEN Token;
576 ULONG i;
577 PACL Dacl;
578 BOOLEAN Present;
579 BOOLEAN Defaulted;
580 PACE CurrentAce;
581 PSID Sid;
582 NTSTATUS Status;
583
584 CurrentAccess = PreviouslyGrantedAccess;
585
586 Token = SubjectSecurityContext->ClientToken ?
587 SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
588
589 /* Get the DACL */
590 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
591 &Present,
592 &Dacl,
593 &Defaulted);
594 if (!NT_SUCCESS(Status))
595 {
596 *AccessStatus = Status;
597 return FALSE;
598 }
599
600 /* RULE 1: Grant desired access if the object is unprotected */
601 if (Dacl == NULL)
602 {
603 *GrantedAccess = DesiredAccess;
604 *AccessStatus = STATUS_SUCCESS;
605 return TRUE;
606 }
607
608 CurrentAccess = PreviouslyGrantedAccess;
609
610 /* RULE 2: Check token for 'take ownership' privilege */
611 Privilege.Luid = SeTakeOwnershipPrivilege;
612 Privilege.Attributes = SE_PRIVILEGE_ENABLED;
613
614 if (SepPrivilegeCheck(Token,
615 &Privilege,
616 1,
617 PRIVILEGE_SET_ALL_NECESSARY,
618 AccessMode))
619 {
620 CurrentAccess |= WRITE_OWNER;
621 if (DesiredAccess == CurrentAccess)
622 {
623 *GrantedAccess = CurrentAccess;
624 *AccessStatus = STATUS_SUCCESS;
625 return TRUE;
626 }
627 }
628
629 /* RULE 3: Check whether the token is the owner */
630 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
631 &Sid,
632 &Defaulted);
633 if (!NT_SUCCESS(Status))
634 {
635 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
636 *AccessStatus = Status;
637 return FALSE;
638 }
639
640 if (SepSidInToken(Token, Sid))
641 {
642 CurrentAccess |= (READ_CONTROL | WRITE_DAC);
643 if (DesiredAccess == CurrentAccess)
644 {
645 *GrantedAccess = CurrentAccess;
646 *AccessStatus = STATUS_SUCCESS;
647 return TRUE;
648 }
649 }
650
651 /* RULE 4: Grant rights according to the DACL */
652 CurrentAce = (PACE)(Dacl + 1);
653 for (i = 0; i < Dacl->AceCount; i++)
654 {
655 Sid = (PSID)(CurrentAce + 1);
656 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
657 {
658 if (SepSidInToken(Token, Sid))
659 {
660 *GrantedAccess = 0;
661 *AccessStatus = STATUS_ACCESS_DENIED;
662 return TRUE;
663 }
664 }
665
666 if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
667 {
668 if (SepSidInToken(Token, Sid))
669 {
670 CurrentAccess |= CurrentAce->AccessMask;
671 }
672 }
673 }
674
675 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
676 CurrentAccess, DesiredAccess);
677
678 *GrantedAccess = CurrentAccess & DesiredAccess;
679
680 *AccessStatus =
681 (*GrantedAccess == DesiredAccess) ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
682
683 return TRUE;
684 }
685
686
687 NTSTATUS STDCALL
688 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
689 IN HANDLE TokenHandle,
690 IN ACCESS_MASK DesiredAccess,
691 IN PGENERIC_MAPPING GenericMapping,
692 OUT PPRIVILEGE_SET PrivilegeSet,
693 OUT PULONG ReturnLength,
694 OUT PACCESS_MASK GrantedAccess,
695 OUT PNTSTATUS AccessStatus)
696 {
697 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
698 KPROCESSOR_MODE PreviousMode;
699 PACCESS_TOKEN Token;
700 NTSTATUS Status;
701
702 DPRINT("NtAccessCheck() called\n");
703
704 PreviousMode = KeGetPreviousMode();
705 if (PreviousMode == KernelMode)
706 {
707 *GrantedAccess = DesiredAccess;
708 *AccessStatus = STATUS_SUCCESS;
709 return STATUS_SUCCESS;
710 }
711
712 Status = ObReferenceObjectByHandle(TokenHandle,
713 TOKEN_QUERY,
714 SepTokenObjectType,
715 PreviousMode,
716 (PVOID*)&Token,
717 NULL);
718 if (!NT_SUCCESS(Status))
719 {
720 DPRINT1("Failed to reference token (Status %lx)\n", Status);
721 return Status;
722 }
723
724 /* Check token type */
725 if (Token->TokenType != TokenImpersonation)
726 {
727 DPRINT1("No impersonation token\n");
728 ObDereferenceObject(Token);
729 return STATUS_ACCESS_VIOLATION;
730 }
731
732 /* Check impersonation level */
733 if (Token->ImpersonationLevel < SecurityAnonymous)
734 {
735 DPRINT1("Invalid impersonation level\n");
736 ObDereferenceObject(Token);
737 return STATUS_ACCESS_VIOLATION;
738 }
739
740 RtlZeroMemory(&SubjectSecurityContext,
741 sizeof(SECURITY_SUBJECT_CONTEXT));
742 SubjectSecurityContext.ClientToken = Token;
743 SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
744
745 /* FIXME: Lock subject context */
746
747 if (!SeAccessCheck(SecurityDescriptor,
748 &SubjectSecurityContext,
749 TRUE,
750 DesiredAccess,
751 0,
752 &PrivilegeSet,
753 GenericMapping,
754 PreviousMode,
755 GrantedAccess,
756 AccessStatus))
757 {
758 Status = *AccessStatus;
759 }
760 else
761 {
762 Status = STATUS_SUCCESS;
763 }
764
765 /* FIXME: Unlock subject context */
766
767 ObDereferenceObject(Token);
768
769 DPRINT("NtAccessCheck() done\n");
770
771 return Status;
772 }
773
774 /* EOF */