Sync to trunk (r44371)
[reactos.git] / reactos / ntoskrnl / se / semgr.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/semgr.c
5 * PURPOSE: Security manager
6 *
7 * PROGRAMMERS: No programmer listed.
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 PSE_EXPORTS SeExports = NULL;
19 SE_EXPORTS SepExports;
20
21 extern ULONG ExpInitializationPhase;
22 extern ERESOURCE SepSubjectContextLock;
23
24 /* PRIVATE FUNCTIONS **********************************************************/
25
26 static BOOLEAN INIT_FUNCTION
27 SepInitExports(VOID)
28 {
29 SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
30 SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
31 SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
32 SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
33 SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
34 SepExports.SeTcbPrivilege = SeTcbPrivilege;
35 SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
36 SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
37 SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
38 SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
39 SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
40 SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
41 SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
42 SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
43 SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
44 SepExports.SeBackupPrivilege = SeBackupPrivilege;
45 SepExports.SeRestorePrivilege = SeRestorePrivilege;
46 SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
47 SepExports.SeDebugPrivilege = SeDebugPrivilege;
48 SepExports.SeAuditPrivilege = SeAuditPrivilege;
49 SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
50 SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
51 SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
52
53 SepExports.SeNullSid = SeNullSid;
54 SepExports.SeWorldSid = SeWorldSid;
55 SepExports.SeLocalSid = SeLocalSid;
56 SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
57 SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
58 SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
59 SepExports.SeDialupSid = SeDialupSid;
60 SepExports.SeNetworkSid = SeNetworkSid;
61 SepExports.SeBatchSid = SeBatchSid;
62 SepExports.SeInteractiveSid = SeInteractiveSid;
63 SepExports.SeLocalSystemSid = SeLocalSystemSid;
64 SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
65 SepExports.SeAliasUsersSid = SeAliasUsersSid;
66 SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
67 SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
68 SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
69 SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
70 SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
71 SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
72 SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
73 SepExports.SeRestrictedSid = SeRestrictedSid;
74 SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
75
76 SepExports.SeUndockPrivilege = SeUndockPrivilege;
77 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
78 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
79
80 SeExports = &SepExports;
81 return TRUE;
82 }
83
84
85 BOOLEAN
86 NTAPI
87 SepInitializationPhase0(VOID)
88 {
89 PAGED_CODE();
90
91 ExpInitLuid();
92 if (!SepInitSecurityIDs()) return FALSE;
93 if (!SepInitDACLs()) return FALSE;
94 if (!SepInitSDs()) return FALSE;
95 SepInitPrivileges();
96 if (!SepInitExports()) return FALSE;
97
98 /* Initialize the subject context lock */
99 ExInitializeResource(&SepSubjectContextLock);
100
101 /* Initialize token objects */
102 SepInitializeTokenImplementation();
103
104 /* Clear impersonation info for the idle thread */
105 PsGetCurrentThread()->ImpersonationInfo = NULL;
106 PspClearCrossThreadFlag(PsGetCurrentThread(),
107 CT_ACTIVE_IMPERSONATION_INFO_BIT);
108
109 /* Initialize the boot token */
110 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
111 ObInitializeFastReference(&PsGetCurrentProcess()->Token,
112 SepCreateSystemProcessToken());
113 return TRUE;
114 }
115
116 BOOLEAN
117 NTAPI
118 SepInitializationPhase1(VOID)
119 {
120 NTSTATUS Status;
121 PAGED_CODE();
122
123 /* Insert the system token into the tree */
124 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
125 ~MAX_FAST_REFS),
126 NULL,
127 0,
128 0,
129 NULL,
130 NULL);
131 ASSERT(NT_SUCCESS(Status));
132
133 /* FIXME: TODO \\ Security directory */
134 return TRUE;
135 }
136
137 BOOLEAN
138 NTAPI
139 SeInitSystem(VOID)
140 {
141 /* Check the initialization phase */
142 switch (ExpInitializationPhase)
143 {
144 case 0:
145
146 /* Do Phase 0 */
147 return SepInitializationPhase0();
148
149 case 1:
150
151 /* Do Phase 1 */
152 return SepInitializationPhase1();
153
154 default:
155
156 /* Don't know any other phase! Bugcheck! */
157 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
158 0,
159 ExpInitializationPhase,
160 0,
161 0);
162 return FALSE;
163 }
164 }
165
166 BOOLEAN
167 NTAPI
168 SeInitSRM(VOID)
169 {
170 OBJECT_ATTRIBUTES ObjectAttributes;
171 UNICODE_STRING Name;
172 HANDLE DirectoryHandle;
173 HANDLE EventHandle;
174 NTSTATUS Status;
175
176 /* Create '\Security' directory */
177 RtlInitUnicodeString(&Name,
178 L"\\Security");
179 InitializeObjectAttributes(&ObjectAttributes,
180 &Name,
181 OBJ_PERMANENT,
182 0,
183 NULL);
184 Status = ZwCreateDirectoryObject(&DirectoryHandle,
185 DIRECTORY_ALL_ACCESS,
186 &ObjectAttributes);
187 if (!NT_SUCCESS(Status))
188 {
189 DPRINT1("Failed to create 'Security' directory!\n");
190 return FALSE;
191 }
192
193 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
194 RtlInitUnicodeString(&Name,
195 L"\\LSA_AUTHENTICATION_INITALIZED");
196 InitializeObjectAttributes(&ObjectAttributes,
197 &Name,
198 OBJ_PERMANENT,
199 DirectoryHandle,
200 SePublicDefaultSd);
201 Status = ZwCreateEvent(&EventHandle,
202 EVENT_ALL_ACCESS,
203 &ObjectAttributes,
204 SynchronizationEvent,
205 FALSE);
206 if (!NT_SUCCESS(Status))
207 {
208 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
209 NtClose(DirectoryHandle);
210 return FALSE;
211 }
212
213 ZwClose(EventHandle);
214 ZwClose(DirectoryHandle);
215
216 /* FIXME: Create SRM port and listener thread */
217
218 return TRUE;
219 }
220
221 NTSTATUS
222 NTAPI
223 SeDefaultObjectMethod(IN PVOID Object,
224 IN SECURITY_OPERATION_CODE OperationType,
225 IN PSECURITY_INFORMATION SecurityInformation,
226 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
227 IN OUT PULONG ReturnLength OPTIONAL,
228 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
229 IN POOL_TYPE PoolType,
230 IN PGENERIC_MAPPING GenericMapping)
231 {
232 PAGED_CODE();
233
234 /* Select the operation type */
235 switch (OperationType)
236 {
237 /* Setting a new descriptor */
238 case SetSecurityDescriptor:
239
240 /* Sanity check */
241 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
242
243 /* Set the information */
244 return ObSetSecurityDescriptorInfo(Object,
245 SecurityInformation,
246 SecurityDescriptor,
247 OldSecurityDescriptor,
248 PoolType,
249 GenericMapping);
250
251 case QuerySecurityDescriptor:
252
253 /* Query the information */
254 return ObQuerySecurityDescriptorInfo(Object,
255 SecurityInformation,
256 SecurityDescriptor,
257 ReturnLength,
258 OldSecurityDescriptor);
259
260 case DeleteSecurityDescriptor:
261
262 /* De-assign it */
263 return ObDeassignSecurity(OldSecurityDescriptor);
264
265 case AssignSecurityDescriptor:
266
267 /* Assign it */
268 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
269 return STATUS_SUCCESS;
270
271 default:
272
273 /* Bug check */
274 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
275 }
276
277 /* Should never reach here */
278 ASSERT(FALSE);
279 return STATUS_SUCCESS;
280 }
281
282
283 static BOOLEAN
284 SepSidInToken(PACCESS_TOKEN _Token,
285 PSID Sid)
286 {
287 ULONG i;
288 PTOKEN Token = (PTOKEN)_Token;
289
290 PAGED_CODE();
291
292 if (Token->UserAndGroupCount == 0)
293 {
294 return FALSE;
295 }
296
297 for (i=0; i<Token->UserAndGroupCount; i++)
298 {
299 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
300 {
301 if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
302 {
303 return TRUE;
304 }
305
306 return FALSE;
307 }
308 }
309
310 return FALSE;
311 }
312
313
314 VOID NTAPI
315 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
316 OUT PACCESS_MASK DesiredAccess)
317 {
318 *DesiredAccess = 0;
319
320 if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
321 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
322 {
323 *DesiredAccess |= READ_CONTROL;
324 }
325 if (SecurityInformation & SACL_SECURITY_INFORMATION)
326 {
327 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
328 }
329 }
330
331 VOID NTAPI
332 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
333 OUT PACCESS_MASK DesiredAccess)
334 {
335 *DesiredAccess = 0;
336
337 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
338 {
339 *DesiredAccess |= WRITE_OWNER;
340 }
341 if (SecurityInformation & DACL_SECURITY_INFORMATION)
342 {
343 *DesiredAccess |= WRITE_DAC;
344 }
345 if (SecurityInformation & SACL_SECURITY_INFORMATION)
346 {
347 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
348 }
349 }
350
351 BOOLEAN NTAPI
352 SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
353 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
354 IN BOOLEAN SubjectContextLocked,
355 IN ACCESS_MASK DesiredAccess,
356 IN ACCESS_MASK PreviouslyGrantedAccess,
357 OUT PPRIVILEGE_SET* Privileges,
358 IN PGENERIC_MAPPING GenericMapping,
359 IN KPROCESSOR_MODE AccessMode,
360 OUT PACCESS_MASK GrantedAccess,
361 OUT PNTSTATUS AccessStatus,
362 SECURITY_IMPERSONATION_LEVEL LowestImpersonationLevel)
363 {
364 LUID_AND_ATTRIBUTES Privilege;
365 ACCESS_MASK CurrentAccess, AccessMask;
366 PACCESS_TOKEN Token;
367 ULONG i;
368 PACL Dacl;
369 BOOLEAN Present;
370 BOOLEAN Defaulted;
371 PACE CurrentAce;
372 PSID Sid;
373 NTSTATUS Status;
374 PAGED_CODE();
375
376 /* Check if this is kernel mode */
377 if (AccessMode == KernelMode)
378 {
379 /* Check if kernel wants everything */
380 if (DesiredAccess & MAXIMUM_ALLOWED)
381 {
382 /* Give it */
383 *GrantedAccess = GenericMapping->GenericAll;
384 *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
385 *GrantedAccess |= PreviouslyGrantedAccess;
386 }
387 else
388 {
389 /* Give the desired and previous access */
390 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
391 }
392
393 /* Success */
394 *AccessStatus = STATUS_SUCCESS;
395 return TRUE;
396 }
397
398 /* Check if we didn't get an SD */
399 if (!SecurityDescriptor)
400 {
401 /* Automatic failure */
402 *AccessStatus = STATUS_ACCESS_DENIED;
403 return FALSE;
404 }
405
406 /* Check for invalid impersonation */
407 if ((SubjectSecurityContext->ClientToken) &&
408 (SubjectSecurityContext->ImpersonationLevel < LowestImpersonationLevel))
409 {
410 *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL;
411 return FALSE;
412 }
413
414 /* Check for no access desired */
415 if (!DesiredAccess)
416 {
417 /* Check if we had no previous access */
418 if (!PreviouslyGrantedAccess)
419 {
420 /* Then there's nothing to give */
421 *AccessStatus = STATUS_ACCESS_DENIED;
422 return FALSE;
423 }
424
425 /* Return the previous access only */
426 *GrantedAccess = PreviouslyGrantedAccess;
427 *AccessStatus = STATUS_SUCCESS;
428 *Privileges = NULL;
429 return TRUE;
430 }
431
432 /* Acquire the lock if needed */
433 if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext);
434
435 /* Map given accesses */
436 RtlMapGenericMask(&DesiredAccess, GenericMapping);
437 if (PreviouslyGrantedAccess)
438 RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping);
439
440
441
442 CurrentAccess = PreviouslyGrantedAccess;
443
444
445
446 Token = SubjectSecurityContext->ClientToken ?
447 SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
448
449 /* Get the DACL */
450 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
451 &Present,
452 &Dacl,
453 &Defaulted);
454 if (!NT_SUCCESS(Status))
455 {
456 if (SubjectContextLocked == FALSE)
457 {
458 SeUnlockSubjectContext(SubjectSecurityContext);
459 }
460
461 *AccessStatus = Status;
462 return FALSE;
463 }
464
465 /* RULE 1: Grant desired access if the object is unprotected */
466 if (Present == TRUE && Dacl == NULL)
467 {
468 if (SubjectContextLocked == FALSE)
469 {
470 SeUnlockSubjectContext(SubjectSecurityContext);
471 }
472
473 *GrantedAccess = DesiredAccess;
474 *AccessStatus = STATUS_SUCCESS;
475 return TRUE;
476 }
477
478 CurrentAccess = PreviouslyGrantedAccess;
479
480 /* RULE 2: Check token for 'take ownership' privilege */
481 Privilege.Luid = SeTakeOwnershipPrivilege;
482 Privilege.Attributes = SE_PRIVILEGE_ENABLED;
483
484 if (SepPrivilegeCheck(Token,
485 &Privilege,
486 1,
487 PRIVILEGE_SET_ALL_NECESSARY,
488 AccessMode))
489 {
490 CurrentAccess |= WRITE_OWNER;
491 if ((DesiredAccess & ~VALID_INHERIT_FLAGS) ==
492 (CurrentAccess & ~VALID_INHERIT_FLAGS))
493 {
494 if (SubjectContextLocked == FALSE)
495 {
496 SeUnlockSubjectContext(SubjectSecurityContext);
497 }
498
499 *GrantedAccess = CurrentAccess;
500 *AccessStatus = STATUS_SUCCESS;
501 return TRUE;
502 }
503 }
504
505 /* RULE 3: Check whether the token is the owner */
506 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
507 &Sid,
508 &Defaulted);
509 if (!NT_SUCCESS(Status))
510 {
511 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
512 if (SubjectContextLocked == FALSE)
513 {
514 SeUnlockSubjectContext(SubjectSecurityContext);
515 }
516
517 *AccessStatus = Status;
518 return FALSE;
519 }
520
521 if (Sid && SepSidInToken(Token, Sid))
522 {
523 CurrentAccess |= (READ_CONTROL | WRITE_DAC);
524 if ((DesiredAccess & ~VALID_INHERIT_FLAGS) ==
525 (CurrentAccess & ~VALID_INHERIT_FLAGS))
526 {
527 if (SubjectContextLocked == FALSE)
528 {
529 SeUnlockSubjectContext(SubjectSecurityContext);
530 }
531
532 *GrantedAccess = CurrentAccess;
533 *AccessStatus = STATUS_SUCCESS;
534 return TRUE;
535 }
536 }
537
538 /* Fail if DACL is absent */
539 if (Present == FALSE)
540 {
541 if (SubjectContextLocked == FALSE)
542 {
543 SeUnlockSubjectContext(SubjectSecurityContext);
544 }
545
546 *GrantedAccess = 0;
547 *AccessStatus = STATUS_ACCESS_DENIED;
548 return FALSE;
549 }
550
551 /* RULE 4: Grant rights according to the DACL */
552 CurrentAce = (PACE)(Dacl + 1);
553 for (i = 0; i < Dacl->AceCount; i++)
554 {
555 Sid = (PSID)(CurrentAce + 1);
556 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
557 {
558 if (SepSidInToken(Token, Sid))
559 {
560 if (SubjectContextLocked == FALSE)
561 {
562 SeUnlockSubjectContext(SubjectSecurityContext);
563 }
564
565 *GrantedAccess = 0;
566 *AccessStatus = STATUS_ACCESS_DENIED;
567 return FALSE;
568 }
569 }
570
571 else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
572 {
573 if (SepSidInToken(Token, Sid))
574 {
575 AccessMask = CurrentAce->AccessMask;
576 RtlMapGenericMask(&AccessMask, GenericMapping);
577 CurrentAccess |= AccessMask;
578 }
579 }
580 else
581 {
582 DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType);
583 }
584 CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
585 }
586
587 if (SubjectContextLocked == FALSE)
588 {
589 SeUnlockSubjectContext(SubjectSecurityContext);
590 }
591
592 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
593 CurrentAccess, DesiredAccess);
594
595 *GrantedAccess = CurrentAccess & DesiredAccess;
596
597 if (DesiredAccess & MAXIMUM_ALLOWED)
598 {
599 *GrantedAccess = CurrentAccess;
600 *AccessStatus = STATUS_SUCCESS;
601 return TRUE;
602 }
603 else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) ==
604 (DesiredAccess & ~VALID_INHERIT_FLAGS))
605 {
606 *AccessStatus = STATUS_SUCCESS;
607 return TRUE;
608 }
609 else
610 {
611 DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n",
612 *GrantedAccess, DesiredAccess, GenericMapping);
613 //*AccessStatus = STATUS_ACCESS_DENIED;
614 //return FALSE;
615 *AccessStatus = STATUS_SUCCESS;
616 return TRUE;
617 }
618 }
619
620 /* PUBLIC FUNCTIONS ***********************************************************/
621
622 /*
623 * @implemented
624 */
625 BOOLEAN NTAPI
626 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
627 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
628 IN BOOLEAN SubjectContextLocked,
629 IN ACCESS_MASK DesiredAccess,
630 IN ACCESS_MASK PreviouslyGrantedAccess,
631 OUT PPRIVILEGE_SET* Privileges,
632 IN PGENERIC_MAPPING GenericMapping,
633 IN KPROCESSOR_MODE AccessMode,
634 OUT PACCESS_MASK GrantedAccess,
635 OUT PNTSTATUS AccessStatus)
636 {
637 /* Call the internal function */
638 return SepAccessCheck(SecurityDescriptor,
639 SubjectSecurityContext,
640 SubjectContextLocked,
641 DesiredAccess,
642 PreviouslyGrantedAccess,
643 Privileges,
644 GenericMapping,
645 AccessMode,
646 GrantedAccess,
647 AccessStatus,
648 SecurityImpersonation);
649 }
650
651 /* SYSTEM CALLS ***************************************************************/
652
653 /*
654 * @implemented
655 */
656 NTSTATUS
657 NTAPI
658 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
659 IN HANDLE TokenHandle,
660 IN ACCESS_MASK DesiredAccess,
661 IN PGENERIC_MAPPING GenericMapping,
662 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
663 IN OUT PULONG PrivilegeSetLength,
664 OUT PACCESS_MASK GrantedAccess,
665 OUT PNTSTATUS AccessStatus)
666 {
667 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
668 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
669 PTOKEN Token;
670 NTSTATUS Status;
671 PAGED_CODE();
672
673 /* Check if this is kernel mode */
674 if (PreviousMode == KernelMode)
675 {
676 /* Check if kernel wants everything */
677 if (DesiredAccess & MAXIMUM_ALLOWED)
678 {
679 /* Give it */
680 *GrantedAccess = GenericMapping->GenericAll;
681 *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
682 }
683 else
684 {
685 /* Just give the desired access */
686 *GrantedAccess = DesiredAccess;
687 }
688
689 /* Success */
690 *AccessStatus = STATUS_SUCCESS;
691 return STATUS_SUCCESS;
692 }
693
694 /* Reference the token */
695 Status = ObReferenceObjectByHandle(TokenHandle,
696 TOKEN_QUERY,
697 SepTokenObjectType,
698 PreviousMode,
699 (PVOID*)&Token,
700 NULL);
701 if (!NT_SUCCESS(Status))
702 {
703 DPRINT1("Failed to reference token (Status %lx)\n", Status);
704 return Status;
705 }
706
707 /* Check token type */
708 if (Token->TokenType != TokenImpersonation)
709 {
710 DPRINT1("No impersonation token\n");
711 ObDereferenceObject(Token);
712 return STATUS_ACCESS_DENIED;
713 }
714
715 /* Set up the subject context, and lock it */
716 SubjectSecurityContext.ClientToken = Token;
717 SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
718 SubjectSecurityContext.PrimaryToken = NULL;
719 SubjectSecurityContext.ProcessAuditId = NULL;
720 SeLockSubjectContext(&SubjectSecurityContext);
721
722 /* Now perform the access check */
723 SepAccessCheck(SecurityDescriptor,
724 &SubjectSecurityContext,
725 TRUE,
726 DesiredAccess,
727 0,
728 &PrivilegeSet, //FIXME
729 GenericMapping,
730 PreviousMode,
731 GrantedAccess,
732 AccessStatus,
733 SecurityIdentification);
734
735 /* Unlock subject context and dereference the token */
736 SeUnlockSubjectContext(&SubjectSecurityContext);
737 ObDereferenceObject(Token);
738
739 /* Check succeeded */
740 return STATUS_SUCCESS;
741 }
742
743
744 NTSTATUS
745 NTAPI
746 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
747 IN PSID PrincipalSelfSid,
748 IN HANDLE ClientToken,
749 IN ACCESS_MASK DesiredAccess,
750 IN POBJECT_TYPE_LIST ObjectTypeList,
751 IN ULONG ObjectTypeLength,
752 IN PGENERIC_MAPPING GenericMapping,
753 IN PPRIVILEGE_SET PrivilegeSet,
754 IN ULONG PrivilegeSetLength,
755 OUT PACCESS_MASK GrantedAccess,
756 OUT PNTSTATUS AccessStatus)
757 {
758 UNIMPLEMENTED;
759 return STATUS_NOT_IMPLEMENTED;
760 }
761
762 NTSTATUS
763 NTAPI
764 NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
765 IN HANDLE HandleId,
766 IN PUNICODE_STRING ObjectTypeName,
767 IN PUNICODE_STRING ObjectName,
768 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
769 IN PSID PrincipalSelfSid,
770 IN ACCESS_MASK DesiredAccess,
771 IN AUDIT_EVENT_TYPE AuditType,
772 IN ULONG Flags,
773 IN POBJECT_TYPE_LIST ObjectTypeList,
774 IN ULONG ObjectTypeLength,
775 IN PGENERIC_MAPPING GenericMapping,
776 IN BOOLEAN ObjectCreation,
777 OUT PACCESS_MASK GrantedAccess,
778 OUT PNTSTATUS AccessStatus,
779 OUT PBOOLEAN GenerateOnClose)
780 {
781 UNIMPLEMENTED;
782 return STATUS_NOT_IMPLEMENTED;
783 }
784
785 NTSTATUS
786 NTAPI
787 NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
788 IN PSID PrincipalSelfSid,
789 IN HANDLE ClientToken,
790 IN ACCESS_MASK DesiredAccess,
791 IN POBJECT_TYPE_LIST ObjectTypeList,
792 IN ULONG ObjectTypeLength,
793 IN PGENERIC_MAPPING GenericMapping,
794 IN PPRIVILEGE_SET PrivilegeSet,
795 IN ULONG PrivilegeSetLength,
796 OUT PACCESS_MASK GrantedAccess,
797 OUT PNTSTATUS AccessStatus)
798 {
799 UNIMPLEMENTED;
800 return STATUS_NOT_IMPLEMENTED;
801 }
802
803 NTSTATUS
804 NTAPI
805 NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
806 IN HANDLE HandleId,
807 IN PUNICODE_STRING ObjectTypeName,
808 IN PUNICODE_STRING ObjectName,
809 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
810 IN PSID PrincipalSelfSid,
811 IN ACCESS_MASK DesiredAccess,
812 IN AUDIT_EVENT_TYPE AuditType,
813 IN ULONG Flags,
814 IN POBJECT_TYPE_LIST ObjectTypeList,
815 IN ULONG ObjectTypeLength,
816 IN PGENERIC_MAPPING GenericMapping,
817 IN BOOLEAN ObjectCreation,
818 OUT PACCESS_MASK GrantedAccess,
819 OUT PNTSTATUS AccessStatus,
820 OUT PBOOLEAN GenerateOnClose)
821 {
822 UNIMPLEMENTED;
823 return STATUS_NOT_IMPLEMENTED;
824 }
825
826 NTSTATUS
827 NTAPI
828 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName,
829 IN HANDLE HandleId,
830 IN HANDLE ClientToken,
831 IN PUNICODE_STRING ObjectTypeName,
832 IN PUNICODE_STRING ObjectName,
833 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
834 IN PSID PrincipalSelfSid,
835 IN ACCESS_MASK DesiredAccess,
836 IN AUDIT_EVENT_TYPE AuditType,
837 IN ULONG Flags,
838 IN POBJECT_TYPE_LIST ObjectTypeList,
839 IN ULONG ObjectTypeLength,
840 IN PGENERIC_MAPPING GenericMapping,
841 IN BOOLEAN ObjectCreation,
842 OUT PACCESS_MASK GrantedAccess,
843 OUT PNTSTATUS AccessStatus,
844 OUT PBOOLEAN GenerateOnClose)
845 {
846 UNIMPLEMENTED;
847 return STATUS_NOT_IMPLEMENTED;
848 }
849
850 /* EOF */