ReactOS  0.4.15-dev-4603-gb922b6d
accesschk.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Security access check control implementation
5  * COPYRIGHT: Copyright 2014 Timo Kreuzer <timo.kreuzer@reactos.org>
6  * Copyright 2014 Eric Kohl
7  * Copyright 2022 George BiČ™oc <george.bisoc@reactos.org>
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PRIVATE FUNCTIONS **********************************************************/
17 
32 {
33  PACCESS_CHECK_RIGHTS AccessRights;
34 
35  PAGED_CODE();
36 
37  /* Allocate some pool for access check rights */
38  AccessRights = ExAllocatePoolWithTag(PagedPool,
39  sizeof(ACCESS_CHECK_RIGHTS),
41 
42  /* Bail out if we failed */
43  if (!AccessRights)
44  {
45  return NULL;
46  }
47 
48  /* Initialize the structure */
49  AccessRights->RemainingAccessRights = 0;
50  AccessRights->GrantedAccessRights = 0;
51  AccessRights->DeniedAccessRights = 0;
52 
53  return AccessRights;
54 }
55 
69 VOID
71  _In_ PACCESS_CHECK_RIGHTS AccessRights)
72 {
73  PAGED_CODE();
74 
75  if (AccessRights)
76  {
78  }
79 }
80 
162  _In_ ACCESS_CHECK_RIGHT_TYPE ActionType,
163  _In_ PACL Dacl,
164  _In_ PACCESS_TOKEN AccessToken,
165  _In_ PACCESS_TOKEN PrimaryAccessToken,
167  _In_ BOOLEAN AccessRightsAllocated,
168  _In_opt_ PSID PrincipalSelfSid,
170  _In_opt_ POBJECT_TYPE_LIST ObjectTypeList,
171  _In_ ULONG ObjectTypeListLength,
172  _In_ ACCESS_MASK RemainingAccess)
173 {
175  PACE CurrentAce;
176  ULONG AceIndex;
177  PSID Sid;
178  ACCESS_MASK Access;
179  PACCESS_CHECK_RIGHTS AccessRights;
180 
181  PAGED_CODE();
182 
183  /* These parameters are really needed */
184  ASSERT(Dacl);
185  ASSERT(AccessToken);
186 
187  /* TODO: To be removed once we support object type handling in Se */
188  DBG_UNREFERENCED_PARAMETER(ObjectTypeList);
189  DBG_UNREFERENCED_PARAMETER(ObjectTypeListLength);
190 
191  /* TODO: To be removed once we support compound ACEs handling in Se */
192  DBG_UNREFERENCED_PARAMETER(PrimaryAccessToken);
193 
194  /*
195  * Allocate memory for access check rights if
196  * we have not done it so. Otherwise just use
197  * the already allocated pointer. This is
198  * typically when we have to do additional
199  * ACEs analysis because the token has
200  * restricted SIDs so we have allocated this
201  * pointer before.
202  */
203  if (!AccessRightsAllocated)
204  {
205  AccessRights = SepInitAccessCheckRights();
206  if (!AccessRights)
207  {
208  DPRINT1("SepAnalyzeAcesFromDacl(): Failed to initialize the access check rights!\n");
209  return NULL;
210  }
211  }
212 
213  /* Determine how we should analyze the ACEs */
214  switch (ActionType)
215  {
216  /*
217  * We got the acknowledgement the calling thread desires
218  * maximum rights (as according to MAXIMUM_ALLOWED access
219  * mask). Analyze the ACE of the given DACL.
220  */
221  case AccessCheckMaximum:
222  {
223  /* Loop over the DACL to retrieve ACEs */
224  for (AceIndex = 0; AceIndex < Dacl->AceCount; AceIndex++)
225  {
226  /* Obtain a ACE now */
227  Status = RtlGetAce(Dacl, AceIndex, (PVOID*)&CurrentAce);
228 
229  /* Getting this ACE is important, otherwise something is seriously wrong */
231 
232  /*
233  * Now it's time to analyze it based upon the
234  * type of this ACE we're being given.
235  */
236  if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE))
237  {
238  if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
239  {
240  /* Get the SID from this ACE */
242 
243  if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, TRUE, IsTokenRestricted))
244  {
245  /* Get this access right from the ACE */
246  Access = CurrentAce->AccessMask;
247 
248  /* Map this access right if it has a generic mask right */
249  if ((Access & GENERIC_ACCESS) && GenericMapping)
250  {
252  }
253 
254  /* Deny access rights that have not been granted yet */
255  AccessRights->DeniedAccessRights |= (Access & ~AccessRights->GrantedAccessRights);
256  DPRINT("SepAnalyzeAcesFromDacl(): DeniedAccessRights 0x%08lx\n", AccessRights->DeniedAccessRights);
257  }
258  }
259  else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
260  {
261  /* Get the SID from this ACE */
263 
264  if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, FALSE, IsTokenRestricted))
265  {
266  /* Get this access right from the ACE */
267  Access = CurrentAce->AccessMask;
268 
269  /* Map this access right if it has a generic mask right */
270  if ((Access & GENERIC_ACCESS) && GenericMapping)
271  {
273  }
274 
275  /* Grant access rights that have not been denied yet */
276  AccessRights->GrantedAccessRights |= (Access & ~AccessRights->DeniedAccessRights);
277  DPRINT("SepAnalyzeAcesFromDacl(): GrantedAccessRights 0x%08lx\n", AccessRights->GrantedAccessRights);
278  }
279  }
280  else
281  {
282  DPRINT1("SepAnalyzeAcesFromDacl(): Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType);
283  }
284  }
285  }
286 
287  /* We're done here */
288  break;
289  }
290 
291  /*
292  * We got the acknowledgement the calling thread desires
293  * only a subset of rights therefore we have to act a little
294  * different here.
295  */
296  case AccessCheckRegular:
297  {
298  /* Cache the remaining access rights to be addressed */
299  AccessRights->RemainingAccessRights = RemainingAccess;
300 
301  /* Loop over the DACL to retrieve ACEs */
302  for (AceIndex = 0; AceIndex < Dacl->AceCount; AceIndex++)
303  {
304  /* Obtain a ACE now */
305  Status = RtlGetAce(Dacl, AceIndex, (PVOID*)&CurrentAce);
306 
307  /* Getting this ACE is important, otherwise something is seriously wrong */
309 
310  /*
311  * Now it's time to analyze it based upon the
312  * type of this ACE we're being given.
313  */
314  if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE))
315  {
316  if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
317  {
318  /* Get the SID from this ACE */
320 
321  if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, TRUE, IsTokenRestricted))
322  {
323  /* Get this access right from the ACE */
324  Access = CurrentAce->AccessMask;
325 
326  /* Map this access right if it has a generic mask right */
327  if ((Access & GENERIC_ACCESS) && GenericMapping)
328  {
330  }
331 
332  /*
333  * The caller requests a right that cannot be
334  * granted. Access is implicitly denied for
335  * the calling thread. Track this access right.
336  */
337  if (AccessRights->RemainingAccessRights & Access)
338  {
339  DPRINT("SepAnalyzeAcesFromDacl(): Refuted access 0x%08lx\n", Access);
340  AccessRights->DeniedAccessRights |= Access;
341  break;
342  }
343  }
344  }
345  else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
346  {
347  /* Get the SID from this ACE */
349 
350  if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, FALSE, IsTokenRestricted))
351  {
352  /* Get this access right from the ACE */
353  Access = CurrentAce->AccessMask;
354 
355  /* Map this access right if it has a generic mask right */
356  if ((Access & GENERIC_ACCESS) && GenericMapping)
357  {
359  }
360 
361  /* Remove granted rights */
362  DPRINT("SepAnalyzeAcesFromDacl(): RemainingAccessRights 0x%08lx Access 0x%08lx\n", AccessRights->RemainingAccessRights, Access);
363  AccessRights->RemainingAccessRights &= ~Access;
364  DPRINT("SepAnalyzeAcesFromDacl(): RemainingAccessRights 0x%08lx\n", AccessRights->RemainingAccessRights);
365 
366  /* Track the granted access right */
367  AccessRights->GrantedAccessRights |= Access;
368  }
369  }
370  else
371  {
372  DPRINT1("SepAnalyzeAcesFromDacl(): Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType);
373  }
374  }
375  }
376 
377  /* We're done here */
378  break;
379  }
380 
381  /* We shouldn't reach here */
383  }
384 
385  /* Return the access rights that we've got */
386  return AccessRights;
387 }
388 
463 BOOLEAN
464 NTAPI
467  _In_opt_ PACCESS_TOKEN ClientAccessToken,
468  _In_ PACCESS_TOKEN PrimaryAccessToken,
469  _In_opt_ PSID PrincipalSelfSid,
471  _In_opt_ POBJECT_TYPE_LIST ObjectTypeList,
472  _In_ ULONG ObjectTypeListLength,
476  _In_ BOOLEAN UseResultList,
478  _Out_ PACCESS_MASK GrantedAccessList,
479  _Out_ PNTSTATUS AccessStatusList)
480 {
481  ACCESS_MASK RemainingAccess;
482  PACCESS_CHECK_RIGHTS AccessCheckRights;
484  ULONG ResultListLength;
485  ULONG ResultListIndex;
486  PACL Dacl;
487  BOOLEAN Present;
488  BOOLEAN Defaulted;
490 
491  PAGED_CODE();
492 
493  /* A security descriptor must be expected for access checks */
495 
496  /* Assume no access check rights first */
497  AccessCheckRights = NULL;
498 
499  /* Check for no access desired */
500  if (!DesiredAccess)
501  {
502  /* Check if we had no previous access */
504  {
505  /* Then there's nothing to give */
506  DPRINT1("SepAccessCheck(): The caller has no previously granted access gained!\n");
508  goto ReturnCommonStatus;
509  }
510 
511  /* Return the previous access only */
513  *Privileges = NULL;
514  goto ReturnCommonStatus;
515  }
516 
517  /* Map given accesses */
521 
522  /* Initialize remaining access rights */
523  RemainingAccess = DesiredAccess;
524 
525  /*
526  * Obtain the token provided by the caller. Client (or also
527  * called impersonation or thread) token takes precedence over
528  * the primary token which is the token associated with the security
529  * context of the main calling process. This is because it is the
530  * client itself that requests access of an object or subset of
531  * multiple objects. Otherwise obtain the security context of the
532  * main process (the actual primary token).
533  */
534  Token = ClientAccessToken ? ClientAccessToken : PrimaryAccessToken;
535 
536  /*
537  * We should at least expect a primary token
538  * to be present if client token is not
539  * available.
540  */
541  ASSERT(Token);
542 
543  /*
544  * Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access.
545  * Write down a set of privileges that have been checked
546  * if the caller wants it.
547  */
548  Status = SePrivilegePolicyCheck(&RemainingAccess,
550  NULL,
551  Token,
552  Privileges,
553  AccessMode);
554  if (!NT_SUCCESS(Status))
555  {
556  goto ReturnCommonStatus;
557  }
558 
559  /* Succeed if there are no more rights to grant */
560  if (RemainingAccess == 0)
561  {
563  goto ReturnCommonStatus;
564  }
565 
566  /* Get the DACL */
568  &Present,
569  &Dacl,
570  &Defaulted);
571  if (!NT_SUCCESS(Status))
572  {
573  goto ReturnCommonStatus;
574  }
575 
576  /* Grant desired access if the object is unprotected */
577  if (Present == FALSE || Dacl == NULL)
578  {
579  PreviouslyGrantedAccess |= RemainingAccess;
580  if (RemainingAccess & MAXIMUM_ALLOWED)
581  {
584  }
585 
587  goto ReturnCommonStatus;
588  }
589 
590  /* Deny access if the DACL is empty */
591  if (Dacl->AceCount == 0)
592  {
593  if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0)
594  {
596  }
597  else
598  {
599  DPRINT1("SepAccessCheck(): The DACL has no ACEs and the caller has no previously granted access!\n");
602  }
603  goto ReturnCommonStatus;
604  }
605 
606  /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
608  {
609  /* Perform access checks against ACEs from this DACL */
610  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
611  Dacl,
612  Token,
613  PrimaryAccessToken,
614  FALSE,
615  FALSE,
616  PrincipalSelfSid,
618  ObjectTypeList,
619  ObjectTypeListLength,
620  0);
621 
622  /*
623  * Getting the access check rights is very
624  * important as we have to do access checks
625  * depending on the kind of rights we get.
626  * Fail prematurely if we can't...
627  */
628  if (!AccessCheckRights)
629  {
630  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
633  goto ReturnCommonStatus;
634  }
635 
636  /*
637  * Perform further access checks if this token
638  * has restricted SIDs.
639  */
641  {
642  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
643  Dacl,
644  Token,
645  PrimaryAccessToken,
646  TRUE,
647  TRUE,
648  PrincipalSelfSid,
650  ObjectTypeList,
651  ObjectTypeListLength,
652  0);
653  }
654 
655  /* Fail if some rights have not been granted */
656  RemainingAccess &= ~(MAXIMUM_ALLOWED | AccessCheckRights->GrantedAccessRights);
657  if (RemainingAccess != 0)
658  {
659  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", RemainingAccess, DesiredAccess);
662  goto ReturnCommonStatus;
663  }
664 
665  /* Set granted access right and access status */
666  PreviouslyGrantedAccess |= AccessCheckRights->GrantedAccessRights;
667  if (PreviouslyGrantedAccess != 0)
668  {
670  }
671  else
672  {
673  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
675  }
676 
677  /* We have successfully granted all the rights */
678  goto ReturnCommonStatus;
679  }
680 
681  /* Grant rights according to the DACL */
682  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
683  Dacl,
684  Token,
685  PrimaryAccessToken,
686  FALSE,
687  FALSE,
688  PrincipalSelfSid,
690  ObjectTypeList,
691  ObjectTypeListLength,
692  RemainingAccess);
693 
694  /*
695  * Getting the access check rights is very
696  * important as we have to do access checks
697  * depending on the kind of rights we get.
698  * Fail prematurely if we can't...
699  */
700  if (!AccessCheckRights)
701  {
702  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
705  goto ReturnCommonStatus;
706  }
707 
708  /* Fail if some rights have not been granted */
709  if (AccessCheckRights->RemainingAccessRights != 0)
710  {
711  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
714  goto ReturnCommonStatus;
715  }
716 
717  /*
718  * Perform further access checks if this token
719  * has restricted SIDs.
720  */
722  {
723  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
724  Dacl,
725  Token,
726  PrimaryAccessToken,
727  TRUE,
728  TRUE,
729  PrincipalSelfSid,
731  ObjectTypeList,
732  ObjectTypeListLength,
733  RemainingAccess);
734 
735  /* Fail if some rights have not been granted */
736  if (AccessCheckRights->RemainingAccessRights != 0)
737  {
738  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
741  goto ReturnCommonStatus;
742  }
743  }
744 
745  /* Set granted access rights */
747 
748  /* Fail if no rights have been granted */
749  if (PreviouslyGrantedAccess == 0)
750  {
751  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
753  goto ReturnCommonStatus;
754  }
755 
756  /*
757  * If we're here then we granted all the desired
758  * access rights the caller wanted.
759  */
761 
762 ReturnCommonStatus:
763  ResultListLength = UseResultList ? ObjectTypeListLength : 1;
764  for (ResultListIndex = 0; ResultListIndex < ResultListLength; ResultListIndex++)
765  {
766  GrantedAccessList[ResultListIndex] = PreviouslyGrantedAccess;
767  AccessStatusList[ResultListIndex] = Status;
768  }
769 
770  /* Free the allocated access check rights */
771  SepFreeAccessCheckRights(AccessCheckRights);
772  AccessCheckRights = NULL;
773 
774  return NT_SUCCESS(Status);
775 }
776 
788 static PSID
790  _In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
791 {
792  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
793  PSID Owner;
794 
795  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
796  Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
798  else
800 
801  return Owner;
802 }
803 
815 static PSID
817  _In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
818 {
819  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
820  PSID Group;
821 
822  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
823  Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
825  else
826  Group = (PSID)SecurityDescriptor->Group;
827 
828  return Group;
829 }
830 
841 static
842 ULONG
844  _In_ PPRIVILEGE_SET PrivilegeSet)
845 {
846  if (PrivilegeSet == NULL)
847  return 0;
848 
849  if (PrivilegeSet->PrivilegeCount == 0)
850  return (ULONG)(sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES));
851 
852  return (ULONG)(sizeof(PRIVILEGE_SET) +
853  (PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES));
854 }
855 
856 /* PUBLIC FUNCTIONS ***********************************************************/
857 
901 BOOLEAN
902 NTAPI
914 {
915  BOOLEAN ret;
916 
917  PAGED_CODE();
918 
919  /* Check if this is kernel mode */
920  if (AccessMode == KernelMode)
921  {
922  /* Check if kernel wants everything */
924  {
925  /* Give it */
929  }
930  else
931  {
932  /* Give the desired and previous access */
934  }
935 
936  /* Success */
938  return TRUE;
939  }
940 
941  /* Check if we didn't get an SD */
942  if (!SecurityDescriptor)
943  {
944  /* Automatic failure */
946  return FALSE;
947  }
948 
949  /* Check for invalid impersonation */
952  {
954  return FALSE;
955  }
956 
957  /* Acquire the lock if needed */
960 
961  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
963  {
966 
969  FALSE))
970  {
973  else
975 
977  }
978  }
979 
980  if (DesiredAccess == 0)
981  {
983  if (PreviouslyGrantedAccess == 0)
984  {
985  DPRINT1("Request for zero access to an object. Denying.\n");
987  ret = FALSE;
988  }
989  else
990  {
992  ret = TRUE;
993  }
994  }
995  else
996  {
997  /* Call the internal function */
1001  NULL,
1002  DesiredAccess,
1003  NULL,
1004  0,
1007  AccessMode,
1008  FALSE,
1009  Privileges,
1010  GrantedAccess,
1011  AccessStatus);
1012  }
1013 
1014  /* Release the lock if needed */
1015  if (!SubjectContextLocked)
1017 
1018  return ret;
1019 }
1020 
1045 BOOLEAN
1046 NTAPI
1052 {
1053  PACL Dacl;
1054  ULONG AceIndex;
1055  PKNOWN_ACE Ace;
1056 
1057  PAGED_CODE();
1058 
1060 
1061  if (SecurityDescriptor == NULL)
1062  return FALSE;
1063 
1064  /* Get DACL */
1066  /* If no DACL, grant access */
1067  if (Dacl == NULL)
1068  return TRUE;
1069 
1070  /* No ACE -> Deny */
1071  if (!Dacl->AceCount)
1072  return FALSE;
1073 
1074  /* Can't perform the check on restricted token */
1075  if (AccessState->Flags & TOKEN_IS_RESTRICTED)
1076  return FALSE;
1077 
1078  /* Browse the ACEs */
1079  for (AceIndex = 0, Ace = (PKNOWN_ACE)((ULONG_PTR)Dacl + sizeof(ACL));
1080  AceIndex < Dacl->AceCount;
1081  AceIndex++, Ace = (PKNOWN_ACE)((ULONG_PTR)Ace + Ace->Header.AceSize))
1082  {
1083  if (Ace->Header.AceFlags & INHERIT_ONLY_ACE)
1084  continue;
1085 
1086  /* If access-allowed ACE */
1087  if (Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
1088  {
1089  /* Check if all accesses are granted */
1090  if (!(Ace->Mask & DesiredAccess))
1091  continue;
1092 
1093  /* Check SID and grant access if matching */
1094  if (RtlEqualSid(SeWorldSid, &(Ace->SidStart)))
1095  return TRUE;
1096  }
1097  /* If access-denied ACE */
1098  else if (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE)
1099  {
1100  /* Here, only check if it denies any access wanted and deny if so */
1101  if (Ace->Mask & DesiredAccess)
1102  return FALSE;
1103  }
1104  }
1105 
1106  /* Faulty, deny */
1107  return FALSE;
1108 }
1109 
1110 /* SYSTEM CALLS ***************************************************************/
1111 
1155 NTSTATUS
1156 NTAPI
1162  _Out_opt_ PPRIVILEGE_SET PrivilegeSet,
1163  _Inout_ PULONG PrivilegeSetLength,
1166 {
1167  PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL;
1172  ULONG CapturedPrivilegeSetLength, RequiredPrivilegeSetLength;
1173  PTOKEN Token;
1174  NTSTATUS Status;
1175 
1176  PAGED_CODE();
1177 
1178  /* Check if this is kernel mode */
1179  if (PreviousMode == KernelMode)
1180  {
1181  /* Check if kernel wants everything */
1183  {
1184  /* Give it */
1187  }
1188  else
1189  {
1190  /* Just give the desired access */
1192  }
1193 
1194  /* Success */
1196  return STATUS_SUCCESS;
1197  }
1198 
1199  /* Protect probe in SEH */
1200  _SEH2_TRY
1201  {
1202  /* Probe all pointers */
1203  ProbeForRead(GenericMapping, sizeof(GENERIC_MAPPING), sizeof(ULONG));
1204  ProbeForRead(PrivilegeSetLength, sizeof(ULONG), sizeof(ULONG));
1205  ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG));
1206  ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
1207  ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
1208 
1209  /* Capture the privilege set length and the mapping */
1210  CapturedPrivilegeSetLength = *PrivilegeSetLength;
1211  }
1213  {
1214  /* Return the exception code */
1216  }
1217  _SEH2_END;
1218 
1219  /* Check for unmapped access rights */
1222 
1223  /* Reference the token */
1225  TOKEN_QUERY,
1227  PreviousMode,
1228  (PVOID*)&Token,
1229  NULL);
1230  if (!NT_SUCCESS(Status))
1231  {
1232  DPRINT("Failed to reference token (Status %lx)\n", Status);
1233  return Status;
1234  }
1235 
1236  /* Check token type */
1237  if (Token->TokenType != TokenImpersonation)
1238  {
1239  DPRINT("No impersonation token\n");
1242  }
1243 
1244  /* Check the impersonation level */
1245  if (Token->ImpersonationLevel < SecurityIdentification)
1246  {
1247  DPRINT("Impersonation level < SecurityIdentification\n");
1250  }
1251 
1252  /* Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access */
1255  NULL,
1256  Token,
1257  &Privileges,
1258  PreviousMode);
1259  if (!NT_SUCCESS(Status))
1260  {
1261  DPRINT("SePrivilegePolicyCheck failed (Status 0x%08lx)\n", Status);
1263  *AccessStatus = Status;
1264  *GrantedAccess = 0;
1265  return STATUS_SUCCESS;
1266  }
1267 
1268  /* Check the size of the privilege set and return the privileges */
1269  if (Privileges != NULL)
1270  {
1271  DPRINT("Privileges != NULL\n");
1272 
1273  /* Calculate the required privilege set buffer size */
1274  RequiredPrivilegeSetLength = SepGetPrivilegeSetLength(Privileges);
1275 
1276  /* Fail if the privilege set buffer is too small */
1277  if (CapturedPrivilegeSetLength < RequiredPrivilegeSetLength)
1278  {
1281  *PrivilegeSetLength = RequiredPrivilegeSetLength;
1282  return STATUS_BUFFER_TOO_SMALL;
1283  }
1284 
1285  /* Copy the privilege set to the caller */
1286  RtlCopyMemory(PrivilegeSet,
1287  Privileges,
1288  RequiredPrivilegeSetLength);
1289 
1290  /* Free the local privilege set */
1292  }
1293  else
1294  {
1295  DPRINT("Privileges == NULL\n");
1296 
1297  /* Fail if the privilege set buffer is too small */
1298  if (CapturedPrivilegeSetLength < sizeof(PRIVILEGE_SET))
1299  {
1301  *PrivilegeSetLength = sizeof(PRIVILEGE_SET);
1302  return STATUS_BUFFER_TOO_SMALL;
1303  }
1304 
1305  /* Initialize the privilege set */
1306  PrivilegeSet->PrivilegeCount = 0;
1307  PrivilegeSet->Control = 0;
1308  }
1309 
1310  /* Capture the security descriptor */
1312  PreviousMode,
1313  PagedPool,
1314  FALSE,
1315  &CapturedSecurityDescriptor);
1316  if (!NT_SUCCESS(Status))
1317  {
1318  DPRINT("Failed to capture the Security Descriptor\n");
1320  return Status;
1321  }
1322 
1323  /* Check the captured security descriptor */
1324  if (CapturedSecurityDescriptor == NULL)
1325  {
1326  DPRINT("Security Descriptor is NULL\n");
1329  }
1330 
1331  /* Check security descriptor for valid owner and group */
1332  if (SepGetSDOwner(CapturedSecurityDescriptor) == NULL ||
1333  SepGetSDGroup(CapturedSecurityDescriptor) == NULL)
1334  {
1335  DPRINT("Security Descriptor does not have a valid group or owner\n");
1336  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1337  PreviousMode,
1338  FALSE);
1341  }
1342 
1343  /* Set up the subject context, and lock it */
1345 
1346  /* Lock the token */
1348 
1349  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
1351  {
1352  if (SepTokenIsOwner(Token, CapturedSecurityDescriptor, FALSE))
1353  {
1356  else
1358 
1360  }
1361  }
1362 
1363  if (DesiredAccess == 0)
1364  {
1367  }
1368  else
1369  {
1370  /* Now perform the access check */
1371  SepAccessCheck(CapturedSecurityDescriptor,
1372  Token,
1374  NULL,
1375  DesiredAccess,
1376  NULL,
1377  0,
1380  PreviousMode,
1381  FALSE,
1382  NULL,
1383  GrantedAccess,
1384  AccessStatus);
1385  }
1386 
1387  /* Release subject context and unlock the token */
1390 
1391  /* Release the captured security descriptor */
1392  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1393  PreviousMode,
1394  FALSE);
1395 
1396  /* Dereference the token */
1398 
1399  /* Check succeeded */
1400  return STATUS_SUCCESS;
1401 }
1402 
1445 NTSTATUS
1446 NTAPI
1449  _In_ PSID PrincipalSelfSid,
1450  _In_ HANDLE ClientToken,
1452  _In_ POBJECT_TYPE_LIST ObjectTypeList,
1453  _In_ ULONG ObjectTypeLength,
1455  _In_ PPRIVILEGE_SET PrivilegeSet,
1456  _Inout_ PULONG PrivilegeSetLength,
1459 {
1460  UNIMPLEMENTED;
1461  return STATUS_NOT_IMPLEMENTED;
1462 }
1463 
1507 NTSTATUS
1508 NTAPI
1511  _In_ PSID PrincipalSelfSid,
1512  _In_ HANDLE ClientToken,
1514  _In_ POBJECT_TYPE_LIST ObjectTypeList,
1515  _In_ ULONG ObjectTypeLength,
1517  _In_ PPRIVILEGE_SET PrivilegeSet,
1518  _Inout_ PULONG PrivilegeSetLength,
1521 {
1522  UNIMPLEMENTED;
1523  return STATUS_NOT_IMPLEMENTED;
1524 }
1525 
1526 /* EOF */
struct _KNOWN_ACE * PKNOWN_ACE
* PNTSTATUS
Definition: strlen.c:14
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define DEFAULT_UNREACHABLE
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define GENERIC_ALL
Definition: nt_native.h:92
#define STATUS_INVALID_SECURITY_DESCR
Definition: ntstatus.h:357
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static ULONG SepGetPrivilegeSetLength(_In_ PPRIVILEGE_SET PrivilegeSet)
Retrieves the length size of a set list of privileges structure.
Definition: accesschk.c:843
#define SE_SELF_RELATIVE
Definition: setypes.h:830
#define _In_opt_
Definition: ms_sal.h:309
struct _PRIVILEGE_SET PRIVILEGE_SET
#define _Inout_
Definition: ms_sal.h:378
Definition: se.h:3
#define _Out_
Definition: ms_sal.h:345
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK _Out_ PNTSTATUS AccessStatus
Definition: sefuncs.h:13
#define TRUE
Definition: types.h:120
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:318
_In_opt_ PSID Group
Definition: rtlfuncs.h:1605
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
BOOLEAN NTAPI SepAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_opt_ PACCESS_TOKEN ClientAccessToken, _In_ PACCESS_TOKEN PrimaryAccessToken, _In_opt_ PSID PrincipalSelfSid, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ ACCESS_MASK PreviouslyGrantedAccess, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN UseResultList, _Out_opt_ PPRIVILEGE_SET *Privileges, _Out_ PACCESS_MASK GrantedAccessList, _Out_ PNTSTATUS AccessStatusList)
Private function that determines whether security access rights can be given to the calling thread in...
Definition: accesschk.c:465
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
PACCESS_CHECK_RIGHTS SepAnalyzeAcesFromDacl(_In_ ACCESS_CHECK_RIGHT_TYPE ActionType, _In_ PACL Dacl, _In_ PACCESS_TOKEN AccessToken, _In_ PACCESS_TOKEN PrimaryAccessToken, _In_ BOOLEAN IsTokenRestricted, _In_ BOOLEAN AccessRightsAllocated, _In_opt_ PSID PrincipalSelfSid, _In_ PGENERIC_MAPPING GenericMapping, _In_opt_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ ACCESS_MASK RemainingAccess)
Analyzes an access control entry that is present in a discretionary access control list (DACL) for ac...
Definition: accesschk.c:161
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
return STATUS_NOT_IMPLEMENTED
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: access.c:459
#define FALSE
Definition: types.h:117
#define GENERIC_WRITE
Definition: nt_native.h:90
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define STATUS_GENERIC_NOT_MAPPED
Definition: ntstatus.h:466
Definition: card.h:12
unsigned char BOOLEAN
POBJECT_TYPE SeTokenObjectType
Definition: token.c:19
NTSTATUS NTAPI NtAccessCheckByType(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSID PrincipalSelfSid, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeLength, _In_ PGENERIC_MAPPING GenericMapping, _In_ PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access could be granted or not on an object by the requestor who wants su...
Definition: accesschk.c:1447
#define _In_
Definition: ms_sal.h:308
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1103
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: access.c:490
#define STATUS_NO_IMPERSONATION_TOKEN
Definition: ntstatus.h:328
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN SubjectContextLocked
Definition: sefuncs.h:13
PACCESS_CHECK_RIGHTS SepInitAccessCheckRights(VOID)
Allocates memory for the internal access check rights data structure and initializes it for use for t...
Definition: accesschk.c:31
Status
Definition: gdiplustypes.h:24
ACCESS_MASK RemainingAccessRights
Definition: se.h:29
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
PACCESS_TOKEN PrimaryToken
Definition: setypes.h:220
NTSTATUS NTAPI NtAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ HANDLE TokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_ PGENERIC_MAPPING GenericMapping, _Out_opt_ PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1157
#define TOKEN_QUERY
Definition: setypes.h:924
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: access.c:437
static PSID SepGetSDGroup(_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
Retrieves the group from a security descriptor.
Definition: accesschk.c:816
NTSTATUS NTAPI SeCaptureSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Captures a security descriptor.
Definition: sd.c:386
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define WRITE_DAC
Definition: nt_native.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
struct _SID * PSID
Definition: eventlog.c:35
#define READ_CONTROL
Definition: nt_native.h:58
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1552
int ret
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define SepReleaseTokenLock(Token)
Definition: se.h:248
NTSTATUS NTAPI SePrivilegePolicyCheck(_Inout_ PACCESS_MASK DesiredAccess, _Inout_ PACCESS_MASK GrantedAccess, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PTOKEN Token, _Out_opt_ PPRIVILEGE_SET *OutPrivilegeSet, _In_ KPROCESSOR_MODE PreviousMode)
Checks the security policy and returns a set of privileges based upon the said security policy contex...
Definition: priv.c:244
#define GENERIC_READ
Definition: compat.h:135
enum _ACCESS_CHECK_RIGHT_TYPE ACCESS_CHECK_RIGHT_TYPE
ACCESS_MASK GrantedAccessRights
Definition: se.h:30
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
PSID SeWorldSid
Definition: sid.c:25
PSID NTAPI SepGetSidFromAce(_In_ UCHAR AceType, _In_ PACE Ace)
Captures a security identifier from a given access control entry. This identifier is valid for the wh...
Definition: sid.c:439
BOOLEAN NTAPI SepSidInTokenEx(_In_ PACCESS_TOKEN _Token, _In_ PSID PrincipalSelfSid, _In_ PSID _Sid, _In_ BOOLEAN Deny, _In_ BOOLEAN Restricted)
Checks if a SID is present in a token.
Definition: access.c:48
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:903
VOID NTAPI SeFreePrivileges(_In_ PPRIVILEGE_SET Privileges)
Frees a set of privileges.
Definition: priv.c:669
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
_SEH2_END
Definition: create.c:4400
static PSID SepGetSDOwner(_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
Retrieves the main user from a security descriptor.
Definition: accesschk.c:789
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:3479
VOID SepFreeAccessCheckRights(_In_ PACCESS_CHECK_RIGHTS AccessRights)
Frees an allocated access check rights from memory space after access check procedures have finished.
Definition: accesschk.c:70
#define _Out_opt_
Definition: ms_sal.h:346
unsigned int * PULONG
Definition: retypes.h:1
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1556
#define NULL
Definition: types.h:112
NTSTATUS NTAPI NtAccessCheckByTypeResultList(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSID PrincipalSelfSid, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeLength, _In_ PGENERIC_MAPPING GenericMapping, _In_ PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access could be granted or not on an object by the requestor who wants su...
Definition: accesschk.c:1509
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: access.c:523
#define GENERIC_ACCESS
Definition: security.c:35
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI SepTokenIsOwner(_In_ PACCESS_TOKEN _Token, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ BOOLEAN TokenLocked)
Checks if a token belongs to the main user, being the owner.
Definition: access.c:180
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:219
#define SepAcquireTokenLockShared(Token)
Definition: se.h:242
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK PreviouslyGrantedAccess
Definition: sefuncs.h:13
unsigned int ULONG
Definition: retypes.h:1
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
#define UNIMPLEMENTED
Definition: debug.h:115
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:96
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
ACCESS_MASK DeniedAccessRights
Definition: se.h:31
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
ACCESS_MASK GenericAll
Definition: nt_native.h:568
#define DPRINT
Definition: sndvol32.h:71
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:13
#define GENERIC_EXECUTE
Definition: nt_native.h:91
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PACCESS_TOKEN ClientToken
Definition: setypes.h:218
BOOLEAN NTAPI SeFastTraverseCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PACCESS_STATE AccessState, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE AccessMode)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1047
#define TAG_ACCESS_CHECK_RIGHT
Definition: tag.h:164
BOOL WINAPI IsTokenRestricted(HANDLE TokenHandle)
Definition: token.c:207
Definition: rtltypes.h:992
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1179
#define PAGED_CODE()
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13