Mask values that control inheritability of the handle, and don't affect access.
[reactos.git] / reactos / ntoskrnl / se / semgr.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/semgr.c
6 * PURPOSE: Security manager
7 *
8 * PROGRAMMERS: No programmer listed.
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS ******************************************************************/
18
19 PSE_EXPORTS SeExports = NULL;
20 SE_EXPORTS SepExports;
21
22 static ERESOURCE SepSubjectContextLock;
23 extern ULONG ExpInitializationPhase;
24
25
26 /* PROTOTYPES ***************************************************************/
27
28 static BOOLEAN SepInitExports(VOID);
29
30 /* FUNCTIONS ****************************************************************/
31
32 BOOLEAN
33 NTAPI
34 SepInitializationPhase0(VOID)
35 {
36 SepInitLuid();
37 if (!SepInitSecurityIDs()) return FALSE;
38 if (!SepInitDACLs()) return FALSE;
39 if (!SepInitSDs()) return FALSE;
40 SepInitPrivileges();
41 if (!SepInitExports()) return FALSE;
42
43 /* Initialize the subject context lock */
44 ExInitializeResource(&SepSubjectContextLock);
45
46 /* Initialize token objects */
47 SepInitializeTokenImplementation();
48
49 /* Clear impersonation info for the idle thread */
50 PsGetCurrentThread()->ImpersonationInfo = NULL;
51 PspClearCrossThreadFlag(PsGetCurrentThread(),
52 CT_ACTIVE_IMPERSONATION_INFO_BIT);
53
54 /* Initialize the boot token */
55 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
56 ObInitializeFastReference(&PsGetCurrentProcess()->Token,
57 SepCreateSystemProcessToken());
58 return TRUE;
59 }
60
61 BOOLEAN
62 NTAPI
63 SepInitializationPhase1(VOID)
64 {
65 NTSTATUS Status;
66 PAGED_CODE();
67
68 /* Insert the system token into the tree */
69 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
70 ~MAX_FAST_REFS),
71 NULL,
72 0,
73 0,
74 NULL,
75 NULL);
76 ASSERT(NT_SUCCESS(Status));
77
78 /* FIXME: TODO \\ Security directory */
79 return TRUE;
80 }
81
82 BOOLEAN
83 NTAPI
84 SeInit(VOID)
85 {
86 /* Check the initialization phase */
87 switch (ExpInitializationPhase)
88 {
89 case 0:
90
91 /* Do Phase 0 */
92 return SepInitializationPhase0();
93
94 case 1:
95
96 /* Do Phase 1 */
97 return SepInitializationPhase1();
98
99 default:
100
101 /* Don't know any other phase! Bugcheck! */
102 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
103 0,
104 ExpInitializationPhase,
105 0,
106 0);
107 return FALSE;
108 }
109 }
110
111 BOOLEAN
112 NTAPI
113 SeInitSRM(VOID)
114 {
115 OBJECT_ATTRIBUTES ObjectAttributes;
116 UNICODE_STRING Name;
117 HANDLE DirectoryHandle;
118 HANDLE EventHandle;
119 NTSTATUS Status;
120
121 /* Create '\Security' directory */
122 RtlInitUnicodeString(&Name,
123 L"\\Security");
124 InitializeObjectAttributes(&ObjectAttributes,
125 &Name,
126 OBJ_PERMANENT,
127 0,
128 NULL);
129 Status = ZwCreateDirectoryObject(&DirectoryHandle,
130 DIRECTORY_ALL_ACCESS,
131 &ObjectAttributes);
132 if (!NT_SUCCESS(Status))
133 {
134 DPRINT1("Failed to create 'Security' directory!\n");
135 return FALSE;
136 }
137
138 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
139 RtlInitUnicodeString(&Name,
140 L"\\LSA_AUTHENTICATION_INITALIZED");
141 InitializeObjectAttributes(&ObjectAttributes,
142 &Name,
143 OBJ_PERMANENT,
144 DirectoryHandle,
145 SePublicDefaultSd);
146 Status = ZwCreateEvent(&EventHandle,
147 EVENT_ALL_ACCESS,
148 &ObjectAttributes,
149 SynchronizationEvent,
150 FALSE);
151 if (!NT_SUCCESS(Status))
152 {
153 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
154 NtClose(DirectoryHandle);
155 return FALSE;
156 }
157
158 ZwClose(EventHandle);
159 ZwClose(DirectoryHandle);
160
161 /* FIXME: Create SRM port and listener thread */
162
163 return TRUE;
164 }
165
166
167 static BOOLEAN INIT_FUNCTION
168 SepInitExports(VOID)
169 {
170 SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
171 SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
172 SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
173 SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
174 SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
175 SepExports.SeTcbPrivilege = SeTcbPrivilege;
176 SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
177 SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
178 SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
179 SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
180 SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
181 SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
182 SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
183 SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
184 SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
185 SepExports.SeBackupPrivilege = SeBackupPrivilege;
186 SepExports.SeRestorePrivilege = SeRestorePrivilege;
187 SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
188 SepExports.SeDebugPrivilege = SeDebugPrivilege;
189 SepExports.SeAuditPrivilege = SeAuditPrivilege;
190 SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
191 SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
192 SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
193
194 SepExports.SeNullSid = SeNullSid;
195 SepExports.SeWorldSid = SeWorldSid;
196 SepExports.SeLocalSid = SeLocalSid;
197 SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
198 SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
199 SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
200 SepExports.SeDialupSid = SeDialupSid;
201 SepExports.SeNetworkSid = SeNetworkSid;
202 SepExports.SeBatchSid = SeBatchSid;
203 SepExports.SeInteractiveSid = SeInteractiveSid;
204 SepExports.SeLocalSystemSid = SeLocalSystemSid;
205 SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
206 SepExports.SeAliasUsersSid = SeAliasUsersSid;
207 SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
208 SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
209 SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
210 SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
211 SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
212 SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
213 SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
214 SepExports.SeRestrictedSid = SeRestrictedSid;
215 SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
216
217 SepExports.SeUndockPrivilege = SeUndockPrivilege;
218 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
219 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
220
221 SeExports = &SepExports;
222 return TRUE;
223 }
224
225
226 VOID SepReferenceLogonSession(PLUID AuthenticationId)
227 {
228 UNIMPLEMENTED;
229 }
230
231 VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
232 {
233 UNIMPLEMENTED;
234 }
235
236 NTSTATUS
237 STDCALL
238 SeDefaultObjectMethod(PVOID Object,
239 SECURITY_OPERATION_CODE OperationType,
240 PSECURITY_INFORMATION _SecurityInformation,
241 PSECURITY_DESCRIPTOR _SecurityDescriptor,
242 PULONG ReturnLength,
243 PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
244 POOL_TYPE PoolType,
245 PGENERIC_MAPPING GenericMapping)
246 {
247 PISECURITY_DESCRIPTOR ObjectSd;
248 PISECURITY_DESCRIPTOR NewSd;
249 PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
250 POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Object);
251 PSID Owner = 0;
252 PSID Group = 0;
253 PACL Dacl = 0;
254 PACL Sacl = 0;
255 ULONG OwnerLength = 0;
256 ULONG GroupLength = 0;
257 ULONG DaclLength = 0;
258 ULONG SaclLength = 0;
259 ULONG Control = 0;
260 ULONG_PTR Current;
261 NTSTATUS Status;
262 SECURITY_INFORMATION SecurityInformation;
263
264 if (OperationType == SetSecurityDescriptor)
265 {
266 ObjectSd = Header->SecurityDescriptor;
267 SecurityInformation = *_SecurityInformation;
268
269 /* Get owner and owner size */
270 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
271 {
272 if (SecurityDescriptor->Owner != NULL)
273 {
274 if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
275 Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
276 (ULONG_PTR)SecurityDescriptor);
277 else
278 Owner = (PSID)SecurityDescriptor->Owner;
279 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
280 }
281 Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
282 }
283 else
284 {
285 if (ObjectSd->Owner != NULL)
286 {
287 Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
288 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
289 }
290 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
291 }
292
293 /* Get group and group size */
294 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
295 {
296 if (SecurityDescriptor->Group != NULL)
297 {
298 if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
299 Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
300 (ULONG_PTR)SecurityDescriptor);
301 else
302 Group = (PSID)SecurityDescriptor->Group;
303 GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
304 }
305 Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
306 }
307 else
308 {
309 if (ObjectSd->Group != NULL)
310 {
311 Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
312 GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
313 }
314 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
315 }
316
317 /* Get DACL and DACL size */
318 if (SecurityInformation & DACL_SECURITY_INFORMATION)
319 {
320 if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
321 (SecurityDescriptor->Dacl != NULL))
322 {
323 if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
324 Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
325 (ULONG_PTR)SecurityDescriptor);
326 else
327 Dacl = (PACL)SecurityDescriptor->Dacl;
328
329 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
330 }
331 Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
332 }
333 else
334 {
335 if ((ObjectSd->Control & SE_DACL_PRESENT) &&
336 (ObjectSd->Dacl != NULL))
337 {
338 Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
339 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
340 }
341 Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
342 }
343
344 /* Get SACL and SACL size */
345 if (SecurityInformation & SACL_SECURITY_INFORMATION)
346 {
347 if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
348 (SecurityDescriptor->Sacl != NULL))
349 {
350 if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
351 Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
352 (ULONG_PTR)SecurityDescriptor);
353 else
354 Sacl = (PACL)SecurityDescriptor->Sacl;
355 SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
356 }
357 Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
358 }
359 else
360 {
361 if ((ObjectSd->Control & SE_SACL_PRESENT) &&
362 (ObjectSd->Sacl != NULL))
363 {
364 Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
365 SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
366 }
367 Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
368 }
369
370 NewSd = ExAllocatePool(NonPagedPool,
371 sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
372 DaclLength + SaclLength);
373 if (NewSd == NULL)
374 {
375 ObDereferenceObject(Object);
376 return STATUS_INSUFFICIENT_RESOURCES;
377 }
378
379 RtlCreateSecurityDescriptor(NewSd,
380 SECURITY_DESCRIPTOR_REVISION1);
381 /* We always build a self-relative descriptor */
382 NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE;
383
384 Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
385
386 if (OwnerLength != 0)
387 {
388 RtlCopyMemory((PVOID)Current,
389 Owner,
390 OwnerLength);
391 NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
392 Current += OwnerLength;
393 }
394
395 if (GroupLength != 0)
396 {
397 RtlCopyMemory((PVOID)Current,
398 Group,
399 GroupLength);
400 NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
401 Current += GroupLength;
402 }
403
404 if (DaclLength != 0)
405 {
406 RtlCopyMemory((PVOID)Current,
407 Dacl,
408 DaclLength);
409 NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
410 Current += DaclLength;
411 }
412
413 if (SaclLength != 0)
414 {
415 RtlCopyMemory((PVOID)Current,
416 Sacl,
417 SaclLength);
418 NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
419 Current += SaclLength;
420 }
421
422 /* Add the new SD */
423 Status = ObpAddSecurityDescriptor(NewSd,
424 &Header->SecurityDescriptor);
425 if (NT_SUCCESS(Status))
426 {
427 /* Remove the old security descriptor */
428 ObpRemoveSecurityDescriptor(ObjectSd);
429 }
430 else
431 {
432 /* Restore the old security descriptor */
433 Header->SecurityDescriptor = ObjectSd;
434 }
435
436 ExFreePool(NewSd);
437 }
438 else if (OperationType == QuerySecurityDescriptor)
439 {
440 Status = SeQuerySecurityDescriptorInfo(_SecurityInformation,
441 SecurityDescriptor,
442 ReturnLength,
443 &Header->SecurityDescriptor);
444 }
445 else if (OperationType == AssignSecurityDescriptor)
446 {
447 /* Assign the security descriptor to the object header */
448 Status = ObpAddSecurityDescriptor(SecurityDescriptor,
449 &Header->SecurityDescriptor);
450 }
451
452
453 return STATUS_SUCCESS;
454 }
455
456 VOID
457 NTAPI
458 SeCaptureSubjectContextEx(IN PETHREAD Thread,
459 IN PEPROCESS Process,
460 OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
461 {
462 BOOLEAN CopyOnOpen, EffectiveOnly;
463 PAGED_CODE();
464
465 /* Save the unique ID */
466 SubjectContext->ProcessAuditId = Process->UniqueProcessId;
467
468 /* Check if we have a thread */
469 if (!Thread)
470 {
471 /* We don't, so no token */
472 SubjectContext->ClientToken = NULL;
473 }
474 else
475 {
476 /* Get the impersonation token */
477 SubjectContext->ClientToken =
478 PsReferenceImpersonationToken(Thread,
479 &CopyOnOpen,
480 &EffectiveOnly,
481 &SubjectContext->ImpersonationLevel);
482 }
483
484 /* Get the primary token */
485 SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
486 }
487
488 /*
489 * @implemented
490 */
491 VOID
492 NTAPI
493 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
494 {
495 /* Call the internal API */
496 SeCaptureSubjectContextEx(PsGetCurrentThread(),
497 PsGetCurrentProcess(),
498 SubjectContext);
499 }
500
501
502 /*
503 * @implemented
504 */
505 VOID STDCALL
506 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
507 {
508 PAGED_CODE();
509
510 KeEnterCriticalRegion();
511 ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
512 }
513
514
515 /*
516 * @implemented
517 */
518 VOID STDCALL
519 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
520 {
521 PAGED_CODE();
522
523 ExReleaseResourceLite(&SepSubjectContextLock);
524 KeLeaveCriticalRegion();
525 }
526
527
528 /*
529 * @implemented
530 */
531 VOID STDCALL
532 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
533 {
534 PAGED_CODE();
535
536 if (SubjectContext->PrimaryToken != NULL)
537 {
538 ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken);
539 }
540
541 if (SubjectContext->ClientToken != NULL)
542 {
543 ObDereferenceObject(SubjectContext->ClientToken);
544 }
545 }
546
547
548 /*
549 * @implemented
550 */
551 NTSTATUS STDCALL
552 SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
553 {
554 PAGED_CODE();
555
556 if (*SecurityDescriptor != NULL)
557 {
558 ExFreePool(*SecurityDescriptor);
559 *SecurityDescriptor = NULL;
560 }
561
562 return STATUS_SUCCESS;
563 }
564
565
566 /*
567 * @unimplemented
568 */
569 NTSTATUS STDCALL
570 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
571 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
572 OUT PSECURITY_DESCRIPTOR *NewDescriptor,
573 IN GUID *ObjectType OPTIONAL,
574 IN BOOLEAN IsDirectoryObject,
575 IN ULONG AutoInheritFlags,
576 IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
577 IN PGENERIC_MAPPING GenericMapping,
578 IN POOL_TYPE PoolType)
579 {
580 UNIMPLEMENTED;
581 return STATUS_NOT_IMPLEMENTED;
582 }
583
584
585 /*
586 * FUNCTION: Creates a security descriptor for a new object.
587 * ARGUMENTS:
588 * ParentDescriptor =
589 * ExplicitDescriptor =
590 * NewDescriptor =
591 * IsDirectoryObject =
592 * SubjectContext =
593 * GeneralMapping =
594 * PoolType =
595 * RETURNS: Status
596 *
597 * @implemented
598 */
599 NTSTATUS STDCALL
600 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
601 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL,
602 PSECURITY_DESCRIPTOR *NewDescriptor,
603 BOOLEAN IsDirectoryObject,
604 PSECURITY_SUBJECT_CONTEXT SubjectContext,
605 PGENERIC_MAPPING GenericMapping,
606 POOL_TYPE PoolType)
607 {
608 PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
609 PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
610 PISECURITY_DESCRIPTOR Descriptor;
611 PTOKEN Token;
612 ULONG OwnerLength = 0;
613 ULONG GroupLength = 0;
614 ULONG DaclLength = 0;
615 ULONG SaclLength = 0;
616 ULONG Length = 0;
617 ULONG Control = 0;
618 ULONG_PTR Current;
619 PSID Owner = NULL;
620 PSID Group = NULL;
621 PACL Dacl = NULL;
622 PACL Sacl = NULL;
623
624 PAGED_CODE();
625
626 /* Lock subject context */
627 SeLockSubjectContext(SubjectContext);
628
629 if (SubjectContext->ClientToken != NULL)
630 {
631 Token = SubjectContext->ClientToken;
632 }
633 else
634 {
635 Token = SubjectContext->PrimaryToken;
636 }
637
638
639 /* Inherit the Owner SID */
640 if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
641 {
642 DPRINT("Use explicit owner sid!\n");
643 Owner = ExplicitDescriptor->Owner;
644
645 if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
646 {
647 Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
648
649 }
650 }
651 else
652 {
653 if (Token != NULL)
654 {
655 DPRINT("Use token owner sid!\n");
656 Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
657 }
658 else
659 {
660 DPRINT("Use default owner sid!\n");
661 Owner = SeLocalSystemSid;
662 }
663
664 Control |= SE_OWNER_DEFAULTED;
665 }
666
667 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
668
669
670 /* Inherit the Group SID */
671 if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
672 {
673 DPRINT("Use explicit group sid!\n");
674 Group = ExplicitDescriptor->Group;
675 if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
676 {
677 Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
678 }
679 }
680 else
681 {
682 if (Token != NULL)
683 {
684 DPRINT("Use token group sid!\n");
685 Group = Token->PrimaryGroup;
686 }
687 else
688 {
689 DPRINT("Use default group sid!\n");
690 Group = SeLocalSystemSid;
691 }
692
693 Control |= SE_OWNER_DEFAULTED;
694 }
695
696 GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
697
698
699 /* Inherit the DACL */
700 if (ExplicitDescriptor != NULL &&
701 (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
702 !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
703 {
704 DPRINT("Use explicit DACL!\n");
705 Dacl = ExplicitDescriptor->Dacl;
706 if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
707 {
708 Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
709 }
710
711 Control |= SE_DACL_PRESENT;
712 }
713 else if (ParentDescriptor != NULL &&
714 (ParentDescriptor->Control & SE_DACL_PRESENT))
715 {
716 DPRINT("Use parent DACL!\n");
717 /* FIXME: Inherit */
718 Dacl = ParentDescriptor->Dacl;
719 if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
720 {
721 Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor);
722 }
723 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
724 }
725 else if (Token != NULL && Token->DefaultDacl != NULL)
726 {
727 DPRINT("Use token default DACL!\n");
728 /* FIXME: Inherit */
729 Dacl = Token->DefaultDacl;
730 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
731 }
732 else
733 {
734 DPRINT("Use NULL DACL!\n");
735 Dacl = NULL;
736 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
737 }
738
739 DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
740
741
742 /* Inherit the SACL */
743 if (ExplicitDescriptor != NULL &&
744 (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
745 !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
746 {
747 DPRINT("Use explicit SACL!\n");
748 Sacl = ExplicitDescriptor->Sacl;
749 if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
750 {
751 Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
752 }
753
754 Control |= SE_SACL_PRESENT;
755 }
756 else if (ParentDescriptor != NULL &&
757 (ParentDescriptor->Control & SE_SACL_PRESENT))
758 {
759 DPRINT("Use parent SACL!\n");
760 /* FIXME: Inherit */
761 Sacl = ParentDescriptor->Sacl;
762 if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
763 {
764 Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor);
765 }
766 Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
767 }
768
769 SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
770
771
772 /* Allocate and initialize the new security descriptor */
773 Length = sizeof(SECURITY_DESCRIPTOR) +
774 OwnerLength + GroupLength + DaclLength + SaclLength;
775
776 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
777 sizeof(SECURITY_DESCRIPTOR),
778 OwnerLength,
779 GroupLength,
780 DaclLength,
781 SaclLength);
782
783 Descriptor = ExAllocatePool(PagedPool,
784 Length);
785 if (Descriptor == NULL)
786 {
787 DPRINT1("ExAlloctePool() failed\n");
788 /* FIXME: Unlock subject context */
789 return STATUS_INSUFFICIENT_RESOURCES;
790 }
791
792 RtlZeroMemory( Descriptor, Length );
793 RtlCreateSecurityDescriptor(Descriptor,
794 SECURITY_DESCRIPTOR_REVISION);
795
796 Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE;
797
798 Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
799
800 if (SaclLength != 0)
801 {
802 RtlCopyMemory((PVOID)Current,
803 Sacl,
804 SaclLength);
805 Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
806 Current += SaclLength;
807 }
808
809 if (DaclLength != 0)
810 {
811 RtlCopyMemory((PVOID)Current,
812 Dacl,
813 DaclLength);
814 Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
815 Current += DaclLength;
816 }
817
818 if (OwnerLength != 0)
819 {
820 RtlCopyMemory((PVOID)Current,
821 Owner,
822 OwnerLength);
823 Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
824 Current += OwnerLength;
825 DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
826 }
827 else
828 DPRINT("Owner of %x is zero length\n", Descriptor);
829
830 if (GroupLength != 0)
831 {
832 memmove((PVOID)Current,
833 Group,
834 GroupLength);
835 Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
836 }
837
838 /* Unlock subject context */
839 SeUnlockSubjectContext(SubjectContext);
840
841 *NewDescriptor = Descriptor;
842
843 DPRINT("Descrptor %x\n", Descriptor);
844 ASSERT(RtlLengthSecurityDescriptor(Descriptor));
845
846 return STATUS_SUCCESS;
847 }
848
849
850 static BOOLEAN
851 SepSidInToken(PACCESS_TOKEN _Token,
852 PSID Sid)
853 {
854 ULONG i;
855 PTOKEN Token = (PTOKEN)_Token;
856
857 PAGED_CODE();
858
859 if (Token->UserAndGroupCount == 0)
860 {
861 return FALSE;
862 }
863
864 for (i=0; i<Token->UserAndGroupCount; i++)
865 {
866 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
867 {
868 if (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)
869 {
870 return TRUE;
871 }
872
873 return FALSE;
874 }
875 }
876
877 return FALSE;
878 }
879
880
881 /*
882 * FUNCTION: Determines whether the requested access rights can be granted
883 * to an object protected by a security descriptor and an object owner
884 * ARGUMENTS:
885 * SecurityDescriptor = Security descriptor protecting the object
886 * SubjectSecurityContext = Subject's captured security context
887 * SubjectContextLocked = Indicates the user's subject context is locked
888 * DesiredAccess = Access rights the caller is trying to acquire
889 * PreviouslyGrantedAccess = Specified the access rights already granted
890 * Privileges = ?
891 * GenericMapping = Generic mapping associated with the object
892 * AccessMode = Access mode used for the check
893 * GrantedAccess (OUT) = On return specifies the access granted
894 * AccessStatus (OUT) = Status indicating why access was denied
895 * RETURNS: If access was granted, returns TRUE
896 *
897 * @implemented
898 */
899 BOOLEAN STDCALL
900 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
901 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
902 IN BOOLEAN SubjectContextLocked,
903 IN ACCESS_MASK DesiredAccess,
904 IN ACCESS_MASK PreviouslyGrantedAccess,
905 OUT PPRIVILEGE_SET* Privileges,
906 IN PGENERIC_MAPPING GenericMapping,
907 IN KPROCESSOR_MODE AccessMode,
908 OUT PACCESS_MASK GrantedAccess,
909 OUT PNTSTATUS AccessStatus)
910 {
911 LUID_AND_ATTRIBUTES Privilege;
912 ACCESS_MASK CurrentAccess, AccessMask;
913 PACCESS_TOKEN Token;
914 ULONG i;
915 PACL Dacl;
916 BOOLEAN Present;
917 BOOLEAN Defaulted;
918 PACE CurrentAce;
919 PSID Sid;
920 NTSTATUS Status;
921 PAGED_CODE();
922
923 /* Check if this is kernel mode */
924 if (AccessMode == KernelMode)
925 {
926 /* Check if kernel wants everything */
927 if (DesiredAccess & MAXIMUM_ALLOWED)
928 {
929 /* Give it */
930 *GrantedAccess = GenericMapping->GenericAll;
931 *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED);
932 *GrantedAccess |= PreviouslyGrantedAccess;
933 }
934 else
935 {
936 /* Give the desired and previous access */
937 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
938 }
939
940 /* Success */
941 *AccessStatus = STATUS_SUCCESS;
942 return TRUE;
943 }
944
945 /* Check if we didn't get an SD */
946 if (!SecurityDescriptor)
947 {
948 /* Automatic failure */
949 *AccessStatus = STATUS_ACCESS_DENIED;
950 return FALSE;
951 }
952
953 /* Check for invalid impersonation */
954 if ((SubjectSecurityContext->ClientToken) &&
955 (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation))
956 {
957 *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL;
958 return FALSE;
959 }
960
961 /* Check for no access desired */
962 if (!DesiredAccess)
963 {
964 /* Check if we had no previous access */
965 if (!PreviouslyGrantedAccess)
966 {
967 /* Then there's nothing to give */
968 *AccessStatus = STATUS_ACCESS_DENIED;
969 return FALSE;
970 }
971
972 /* Return the previous access only */
973 *GrantedAccess = PreviouslyGrantedAccess;
974 *AccessStatus = STATUS_SUCCESS;
975 *Privileges = NULL;
976 return TRUE;
977 }
978
979 /* Acquire the lock if needed */
980 if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext);
981
982 /* Map given accesses */
983 RtlMapGenericMask(&DesiredAccess, GenericMapping);
984 if (PreviouslyGrantedAccess)
985 RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping);
986
987
988
989 CurrentAccess = PreviouslyGrantedAccess;
990
991
992
993 Token = SubjectSecurityContext->ClientToken ?
994 SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
995
996 /* Get the DACL */
997 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
998 &Present,
999 &Dacl,
1000 &Defaulted);
1001 if (!NT_SUCCESS(Status))
1002 {
1003 if (SubjectContextLocked == FALSE)
1004 {
1005 SeUnlockSubjectContext(SubjectSecurityContext);
1006 }
1007
1008 *AccessStatus = Status;
1009 return FALSE;
1010 }
1011
1012 /* RULE 1: Grant desired access if the object is unprotected */
1013 if (Present == TRUE && Dacl == NULL)
1014 {
1015 if (SubjectContextLocked == FALSE)
1016 {
1017 SeUnlockSubjectContext(SubjectSecurityContext);
1018 }
1019
1020 *GrantedAccess = DesiredAccess;
1021 *AccessStatus = STATUS_SUCCESS;
1022 return TRUE;
1023 }
1024
1025 CurrentAccess = PreviouslyGrantedAccess;
1026
1027 /* RULE 2: Check token for 'take ownership' privilege */
1028 Privilege.Luid = SeTakeOwnershipPrivilege;
1029 Privilege.Attributes = SE_PRIVILEGE_ENABLED;
1030
1031 if (SepPrivilegeCheck(Token,
1032 &Privilege,
1033 1,
1034 PRIVILEGE_SET_ALL_NECESSARY,
1035 AccessMode))
1036 {
1037 CurrentAccess |= WRITE_OWNER;
1038 if ((DesiredAccess & ~VALID_INHERIT_FLAGS) ==
1039 (CurrentAccess & ~VALID_INHERIT_FLAGS))
1040 {
1041 if (SubjectContextLocked == FALSE)
1042 {
1043 SeUnlockSubjectContext(SubjectSecurityContext);
1044 }
1045
1046 *GrantedAccess = CurrentAccess;
1047 *AccessStatus = STATUS_SUCCESS;
1048 return TRUE;
1049 }
1050 }
1051
1052 /* RULE 3: Check whether the token is the owner */
1053 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
1054 &Sid,
1055 &Defaulted);
1056 if (!NT_SUCCESS(Status))
1057 {
1058 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status);
1059 if (SubjectContextLocked == FALSE)
1060 {
1061 SeUnlockSubjectContext(SubjectSecurityContext);
1062 }
1063
1064 *AccessStatus = Status;
1065 return FALSE;
1066 }
1067
1068 if (Sid && SepSidInToken(Token, Sid))
1069 {
1070 CurrentAccess |= (READ_CONTROL | WRITE_DAC);
1071 if ((DesiredAccess & ~VALID_INHERIT_FLAGS) ==
1072 (CurrentAccess & ~VALID_INHERIT_FLAGS))
1073 {
1074 if (SubjectContextLocked == FALSE)
1075 {
1076 SeUnlockSubjectContext(SubjectSecurityContext);
1077 }
1078
1079 *GrantedAccess = CurrentAccess;
1080 *AccessStatus = STATUS_SUCCESS;
1081 return TRUE;
1082 }
1083 }
1084
1085 /* Fail if DACL is absent */
1086 if (Present == FALSE)
1087 {
1088 if (SubjectContextLocked == FALSE)
1089 {
1090 SeUnlockSubjectContext(SubjectSecurityContext);
1091 }
1092
1093 *GrantedAccess = 0;
1094 *AccessStatus = STATUS_ACCESS_DENIED;
1095 return FALSE;
1096 }
1097
1098 /* RULE 4: Grant rights according to the DACL */
1099 CurrentAce = (PACE)(Dacl + 1);
1100 for (i = 0; i < Dacl->AceCount; i++)
1101 {
1102 Sid = (PSID)(CurrentAce + 1);
1103 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
1104 {
1105 if (SepSidInToken(Token, Sid))
1106 {
1107 if (SubjectContextLocked == FALSE)
1108 {
1109 SeUnlockSubjectContext(SubjectSecurityContext);
1110 }
1111
1112 *GrantedAccess = 0;
1113 *AccessStatus = STATUS_ACCESS_DENIED;
1114 return FALSE;
1115 }
1116 }
1117
1118 else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
1119 {
1120 if (SepSidInToken(Token, Sid))
1121 {
1122 AccessMask = CurrentAce->AccessMask;
1123 RtlMapGenericMask(&AccessMask, GenericMapping);
1124 CurrentAccess |= AccessMask;
1125 }
1126 }
1127 else
1128 {
1129 DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType);
1130 }
1131 CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
1132 }
1133
1134 if (SubjectContextLocked == FALSE)
1135 {
1136 SeUnlockSubjectContext(SubjectSecurityContext);
1137 }
1138
1139 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
1140 CurrentAccess, DesiredAccess);
1141
1142 *GrantedAccess = CurrentAccess & DesiredAccess;
1143
1144 if (DesiredAccess & MAXIMUM_ALLOWED)
1145 {
1146 *GrantedAccess = CurrentAccess;
1147 *AccessStatus = STATUS_SUCCESS;
1148 return TRUE;
1149 }
1150 else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) ==
1151 (DesiredAccess & ~VALID_INHERIT_FLAGS))
1152 {
1153 *AccessStatus = STATUS_SUCCESS;
1154 return TRUE;
1155 }
1156 else
1157 {
1158 DPRINT1("Denying access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p)\n",
1159 *GrantedAccess, DesiredAccess, GenericMapping);
1160 *AccessStatus = STATUS_ACCESS_DENIED;
1161 return FALSE;
1162 }
1163 }
1164
1165
1166 NTSTATUS STDCALL
1167 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1168 IN HANDLE TokenHandle,
1169 IN ACCESS_MASK DesiredAccess,
1170 IN PGENERIC_MAPPING GenericMapping,
1171 OUT PPRIVILEGE_SET PrivilegeSet,
1172 OUT PULONG ReturnLength,
1173 OUT PACCESS_MASK GrantedAccess,
1174 OUT PNTSTATUS AccessStatus)
1175 {
1176 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext = {0};
1177 KPROCESSOR_MODE PreviousMode;
1178 PTOKEN Token;
1179 NTSTATUS Status;
1180
1181 PAGED_CODE();
1182
1183 DPRINT("NtAccessCheck() called\n");
1184
1185 PreviousMode = KeGetPreviousMode();
1186 if (PreviousMode == KernelMode)
1187 {
1188 *GrantedAccess = DesiredAccess;
1189 *AccessStatus = STATUS_SUCCESS;
1190 return STATUS_SUCCESS;
1191 }
1192
1193 Status = ObReferenceObjectByHandle(TokenHandle,
1194 TOKEN_QUERY,
1195 SepTokenObjectType,
1196 PreviousMode,
1197 (PVOID*)&Token,
1198 NULL);
1199 if (!NT_SUCCESS(Status))
1200 {
1201 DPRINT1("Failed to reference token (Status %lx)\n", Status);
1202 return Status;
1203 }
1204
1205 /* Check token type */
1206 if (Token->TokenType != TokenImpersonation)
1207 {
1208 DPRINT1("No impersonation token\n");
1209 ObDereferenceObject(Token);
1210 return STATUS_ACCESS_VIOLATION;
1211 }
1212
1213 /* Check impersonation level */
1214 if (Token->ImpersonationLevel < SecurityAnonymous)
1215 {
1216 DPRINT1("Invalid impersonation level\n");
1217 ObDereferenceObject(Token);
1218 return STATUS_ACCESS_VIOLATION;
1219 }
1220
1221 SubjectSecurityContext.ClientToken = Token;
1222 SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel;
1223
1224 /* Lock subject context */
1225 SeLockSubjectContext(&SubjectSecurityContext);
1226
1227 if (SeAccessCheck(SecurityDescriptor,
1228 &SubjectSecurityContext,
1229 TRUE,
1230 DesiredAccess,
1231 0,
1232 &PrivilegeSet,
1233 GenericMapping,
1234 PreviousMode,
1235 GrantedAccess,
1236 AccessStatus))
1237 {
1238 Status = *AccessStatus;
1239 }
1240 else
1241 {
1242 Status = STATUS_ACCESS_DENIED;
1243 }
1244
1245 /* Unlock subject context */
1246 SeUnlockSubjectContext(&SubjectSecurityContext);
1247
1248 ObDereferenceObject(Token);
1249
1250 DPRINT("NtAccessCheck() done\n");
1251
1252 return Status;
1253 }
1254
1255 NTSTATUS
1256 NTAPI
1257 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1258 IN PSID PrincipalSelfSid,
1259 IN HANDLE ClientToken,
1260 IN ACCESS_MASK DesiredAccess,
1261 IN POBJECT_TYPE_LIST ObjectTypeList,
1262 IN ULONG ObjectTypeLength,
1263 IN PGENERIC_MAPPING GenericMapping,
1264 IN PPRIVILEGE_SET PrivilegeSet,
1265 IN ULONG PrivilegeSetLength,
1266 OUT PACCESS_MASK GrantedAccess,
1267 OUT PNTSTATUS AccessStatus)
1268 {
1269 UNIMPLEMENTED;
1270 return STATUS_NOT_IMPLEMENTED;
1271 }
1272
1273 NTSTATUS
1274 NTAPI
1275 NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
1276 IN HANDLE HandleId,
1277 IN PUNICODE_STRING ObjectTypeName,
1278 IN PUNICODE_STRING ObjectName,
1279 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1280 IN PSID PrincipalSelfSid,
1281 IN ACCESS_MASK DesiredAccess,
1282 IN AUDIT_EVENT_TYPE AuditType,
1283 IN ULONG Flags,
1284 IN POBJECT_TYPE_LIST ObjectTypeList,
1285 IN ULONG ObjectTypeLength,
1286 IN PGENERIC_MAPPING GenericMapping,
1287 IN BOOLEAN ObjectCreation,
1288 OUT PACCESS_MASK GrantedAccess,
1289 OUT PNTSTATUS AccessStatus,
1290 OUT PBOOLEAN GenerateOnClose)
1291 {
1292 UNIMPLEMENTED;
1293 return STATUS_NOT_IMPLEMENTED;
1294 }
1295
1296 NTSTATUS
1297 NTAPI
1298 NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1299 IN PSID PrincipalSelfSid,
1300 IN HANDLE ClientToken,
1301 IN ACCESS_MASK DesiredAccess,
1302 IN POBJECT_TYPE_LIST ObjectTypeList,
1303 IN ULONG ObjectTypeLength,
1304 IN PGENERIC_MAPPING GenericMapping,
1305 IN PPRIVILEGE_SET PrivilegeSet,
1306 IN ULONG PrivilegeSetLength,
1307 OUT PACCESS_MASK GrantedAccess,
1308 OUT PNTSTATUS AccessStatus)
1309 {
1310 UNIMPLEMENTED;
1311 return STATUS_NOT_IMPLEMENTED;
1312 }
1313
1314 NTSTATUS
1315 NTAPI
1316 NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
1317 IN HANDLE HandleId,
1318 IN PUNICODE_STRING ObjectTypeName,
1319 IN PUNICODE_STRING ObjectName,
1320 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1321 IN PSID PrincipalSelfSid,
1322 IN ACCESS_MASK DesiredAccess,
1323 IN AUDIT_EVENT_TYPE AuditType,
1324 IN ULONG Flags,
1325 IN POBJECT_TYPE_LIST ObjectTypeList,
1326 IN ULONG ObjectTypeLength,
1327 IN PGENERIC_MAPPING GenericMapping,
1328 IN BOOLEAN ObjectCreation,
1329 OUT PACCESS_MASK GrantedAccess,
1330 OUT PNTSTATUS AccessStatus,
1331 OUT PBOOLEAN GenerateOnClose)
1332 {
1333 UNIMPLEMENTED;
1334 return STATUS_NOT_IMPLEMENTED;
1335 }
1336
1337 NTSTATUS
1338 NTAPI
1339 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName,
1340 IN HANDLE HandleId,
1341 IN HANDLE ClientToken,
1342 IN PUNICODE_STRING ObjectTypeName,
1343 IN PUNICODE_STRING ObjectName,
1344 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1345 IN PSID PrincipalSelfSid,
1346 IN ACCESS_MASK DesiredAccess,
1347 IN AUDIT_EVENT_TYPE AuditType,
1348 IN ULONG Flags,
1349 IN POBJECT_TYPE_LIST ObjectTypeList,
1350 IN ULONG ObjectTypeLength,
1351 IN PGENERIC_MAPPING GenericMapping,
1352 IN BOOLEAN ObjectCreation,
1353 OUT PACCESS_MASK GrantedAccess,
1354 OUT PNTSTATUS AccessStatus,
1355 OUT PBOOLEAN GenerateOnClose)
1356 {
1357 UNIMPLEMENTED;
1358 return STATUS_NOT_IMPLEMENTED;
1359 }
1360
1361 VOID STDCALL
1362 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
1363 OUT PACCESS_MASK DesiredAccess)
1364 {
1365 if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
1366 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
1367 {
1368 *DesiredAccess |= READ_CONTROL;
1369 }
1370 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1371 {
1372 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
1373 }
1374 }
1375
1376 VOID STDCALL
1377 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
1378 OUT PACCESS_MASK DesiredAccess)
1379 {
1380 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
1381 {
1382 *DesiredAccess |= WRITE_OWNER;
1383 }
1384 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1385 {
1386 *DesiredAccess |= WRITE_DAC;
1387 }
1388 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1389 {
1390 *DesiredAccess |= ACCESS_SYSTEM_SECURITY;
1391 }
1392 }
1393
1394 /* EOF */