ReactOS  0.4.15-dev-5496-g599ba9c
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  ULONG ResultListLength;
483  ULONG ResultListIndex;
484  PACL Dacl;
485  BOOLEAN Present;
486  BOOLEAN Defaulted;
489  PACCESS_CHECK_RIGHTS AccessCheckRights = NULL;
490 
491  PAGED_CODE();
492 
493  /* A security descriptor must be expected for access checks */
495 
496  /* Check for no access desired */
497  if (!DesiredAccess)
498  {
499  /* Check if we had no previous access */
501  {
502  /* Then there's nothing to give */
503  DPRINT1("SepAccessCheck(): The caller has no previously granted access gained!\n");
505  goto ReturnCommonStatus;
506  }
507 
508  /* Return the previous access only */
510  *Privileges = NULL;
511  goto ReturnCommonStatus;
512  }
513 
514  /* Map given accesses */
518 
519  /* Initialize remaining access rights */
520  RemainingAccess = DesiredAccess;
521 
522  /*
523  * Obtain the token provided by the caller. Client (or also
524  * called impersonation or thread) token takes precedence over
525  * the primary token which is the token associated with the security
526  * context of the main calling process. This is because it is the
527  * client itself that requests access of an object or subset of
528  * multiple objects. Otherwise obtain the security context of the
529  * main process (the actual primary token).
530  */
531  Token = ClientAccessToken ? ClientAccessToken : PrimaryAccessToken;
532 
533  /*
534  * We should at least expect a primary token
535  * to be present if client token is not
536  * available.
537  */
538  ASSERT(Token);
539 
540  /*
541  * Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access.
542  * Write down a set of privileges that have been checked
543  * if the caller wants it.
544  */
545  Status = SePrivilegePolicyCheck(&RemainingAccess,
547  NULL,
548  Token,
549  Privileges,
550  AccessMode);
551  if (!NT_SUCCESS(Status))
552  {
553  goto ReturnCommonStatus;
554  }
555 
556  /* Succeed if there are no more rights to grant */
557  if (RemainingAccess == 0)
558  {
560  goto ReturnCommonStatus;
561  }
562 
563  /* Get the DACL */
565  &Present,
566  &Dacl,
567  &Defaulted);
568  if (!NT_SUCCESS(Status))
569  {
570  goto ReturnCommonStatus;
571  }
572 
573  /* Grant desired access if the object is unprotected */
574  if (Present == FALSE || Dacl == NULL)
575  {
576  PreviouslyGrantedAccess |= RemainingAccess;
577  if (RemainingAccess & MAXIMUM_ALLOWED)
578  {
581  }
582 
584  goto ReturnCommonStatus;
585  }
586 
587  /* Deny access if the DACL is empty */
588  if (Dacl->AceCount == 0)
589  {
590  if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0)
591  {
593  }
594  else
595  {
596  DPRINT1("SepAccessCheck(): The DACL has no ACEs and the caller has no previously granted access!\n");
599  }
600  goto ReturnCommonStatus;
601  }
602 
603  /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
605  {
606  /* Perform access checks against ACEs from this DACL */
607  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
608  Dacl,
609  Token,
610  PrimaryAccessToken,
611  FALSE,
612  FALSE,
613  PrincipalSelfSid,
615  ObjectTypeList,
616  ObjectTypeListLength,
617  0);
618 
619  /*
620  * Getting the access check rights is very
621  * important as we have to do access checks
622  * depending on the kind of rights we get.
623  * Fail prematurely if we can't...
624  */
625  if (!AccessCheckRights)
626  {
627  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
630  goto ReturnCommonStatus;
631  }
632 
633  /*
634  * Perform further access checks if this token
635  * has restricted SIDs.
636  */
638  {
639  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
640  Dacl,
641  Token,
642  PrimaryAccessToken,
643  TRUE,
644  TRUE,
645  PrincipalSelfSid,
647  ObjectTypeList,
648  ObjectTypeListLength,
649  0);
650  }
651 
652  /* Fail if some rights have not been granted */
653  RemainingAccess &= ~(MAXIMUM_ALLOWED | AccessCheckRights->GrantedAccessRights);
654  if (RemainingAccess != 0)
655  {
656  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", RemainingAccess, DesiredAccess);
659  goto ReturnCommonStatus;
660  }
661 
662  /* Set granted access right and access status */
663  PreviouslyGrantedAccess |= AccessCheckRights->GrantedAccessRights;
664  if (PreviouslyGrantedAccess != 0)
665  {
667  }
668  else
669  {
670  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
672  }
673 
674  /* We have successfully granted all the rights */
675  goto ReturnCommonStatus;
676  }
677 
678  /* Grant rights according to the DACL */
679  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
680  Dacl,
681  Token,
682  PrimaryAccessToken,
683  FALSE,
684  FALSE,
685  PrincipalSelfSid,
687  ObjectTypeList,
688  ObjectTypeListLength,
689  RemainingAccess);
690 
691  /*
692  * Getting the access check rights is very
693  * important as we have to do access checks
694  * depending on the kind of rights we get.
695  * Fail prematurely if we can't...
696  */
697  if (!AccessCheckRights)
698  {
699  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
702  goto ReturnCommonStatus;
703  }
704 
705  /* Fail if some rights have not been granted */
706  if (AccessCheckRights->RemainingAccessRights != 0)
707  {
708  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
711  goto ReturnCommonStatus;
712  }
713 
714  /*
715  * Perform further access checks if this token
716  * has restricted SIDs.
717  */
719  {
720  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
721  Dacl,
722  Token,
723  PrimaryAccessToken,
724  TRUE,
725  TRUE,
726  PrincipalSelfSid,
728  ObjectTypeList,
729  ObjectTypeListLength,
730  RemainingAccess);
731 
732  /* Fail if some rights have not been granted */
733  if (AccessCheckRights->RemainingAccessRights != 0)
734  {
735  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
738  goto ReturnCommonStatus;
739  }
740  }
741 
742  /* Set granted access rights */
744 
745  /* Fail if no rights have been granted */
746  if (PreviouslyGrantedAccess == 0)
747  {
748  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
750  goto ReturnCommonStatus;
751  }
752 
753  /*
754  * If we're here then we granted all the desired
755  * access rights the caller wanted.
756  */
758 
759 ReturnCommonStatus:
760  ResultListLength = UseResultList ? ObjectTypeListLength : 1;
761  for (ResultListIndex = 0; ResultListIndex < ResultListLength; ResultListIndex++)
762  {
763  GrantedAccessList[ResultListIndex] = PreviouslyGrantedAccess;
764  AccessStatusList[ResultListIndex] = Status;
765  }
766 
767 #if DBG
768  /* Dump security debug info on access denied case */
770  {
773  SepDumpAccessRightsStats(AccessCheckRights);
774  }
775 #endif
776 
777  /* Free the allocated access check rights */
778  SepFreeAccessCheckRights(AccessCheckRights);
779  AccessCheckRights = NULL;
780 
781  return NT_SUCCESS(Status);
782 }
783 
795 static PSID
797  _In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
798 {
799  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
800  PSID Owner;
801 
802  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
803  Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
805  else
807 
808  return Owner;
809 }
810 
822 static PSID
824  _In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
825 {
826  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
827  PSID Group;
828 
829  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
830  Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
832  else
833  Group = (PSID)SecurityDescriptor->Group;
834 
835  return Group;
836 }
837 
848 static
849 ULONG
851  _In_ PPRIVILEGE_SET PrivilegeSet)
852 {
853  if (PrivilegeSet == NULL)
854  return 0;
855 
856  if (PrivilegeSet->PrivilegeCount == 0)
857  return (ULONG)(sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES));
858 
859  return (ULONG)(sizeof(PRIVILEGE_SET) +
860  (PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES));
861 }
862 
863 /* PUBLIC FUNCTIONS ***********************************************************/
864 
908 BOOLEAN
909 NTAPI
921 {
922  BOOLEAN ret;
923 
924  PAGED_CODE();
925 
926  /* Check if this is kernel mode */
927  if (AccessMode == KernelMode)
928  {
929  /* Check if kernel wants everything */
931  {
932  /* Give it */
936  }
937  else
938  {
939  /* Give the desired and previous access */
941  }
942 
943  /* Success */
945  return TRUE;
946  }
947 
948  /* Check if we didn't get an SD */
949  if (!SecurityDescriptor)
950  {
951  /* Automatic failure */
953  return FALSE;
954  }
955 
956  /* Check for invalid impersonation */
959  {
961  return FALSE;
962  }
963 
964  /* Acquire the lock if needed */
967 
968  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
970  {
973 
976  FALSE))
977  {
980  else
982 
984  }
985  }
986 
987  if (DesiredAccess == 0)
988  {
990  if (PreviouslyGrantedAccess == 0)
991  {
992  DPRINT1("Request for zero access to an object. Denying.\n");
994  ret = FALSE;
995  }
996  else
997  {
999  ret = TRUE;
1000  }
1001  }
1002  else
1003  {
1004  /* Call the internal function */
1008  NULL,
1009  DesiredAccess,
1010  NULL,
1011  0,
1014  AccessMode,
1015  FALSE,
1016  Privileges,
1017  GrantedAccess,
1018  AccessStatus);
1019  }
1020 
1021  /* Release the lock if needed */
1022  if (!SubjectContextLocked)
1024 
1025  return ret;
1026 }
1027 
1052 BOOLEAN
1053 NTAPI
1059 {
1060  PACL Dacl;
1061  ULONG AceIndex;
1062  PKNOWN_ACE Ace;
1063 
1064  PAGED_CODE();
1065 
1067 
1068  if (SecurityDescriptor == NULL)
1069  return FALSE;
1070 
1071  /* Get DACL */
1073  /* If no DACL, grant access */
1074  if (Dacl == NULL)
1075  return TRUE;
1076 
1077  /* No ACE -> Deny */
1078  if (!Dacl->AceCount)
1079  return FALSE;
1080 
1081  /* Can't perform the check on restricted token */
1082  if (AccessState->Flags & TOKEN_IS_RESTRICTED)
1083  return FALSE;
1084 
1085  /* Browse the ACEs */
1086  for (AceIndex = 0, Ace = (PKNOWN_ACE)((ULONG_PTR)Dacl + sizeof(ACL));
1087  AceIndex < Dacl->AceCount;
1088  AceIndex++, Ace = (PKNOWN_ACE)((ULONG_PTR)Ace + Ace->Header.AceSize))
1089  {
1090  if (Ace->Header.AceFlags & INHERIT_ONLY_ACE)
1091  continue;
1092 
1093  /* If access-allowed ACE */
1094  if (Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
1095  {
1096  /* Check if all accesses are granted */
1097  if (!(Ace->Mask & DesiredAccess))
1098  continue;
1099 
1100  /* Check SID and grant access if matching */
1101  if (RtlEqualSid(SeWorldSid, &(Ace->SidStart)))
1102  return TRUE;
1103  }
1104  /* If access-denied ACE */
1105  else if (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE)
1106  {
1107  /* Here, only check if it denies any access wanted and deny if so */
1108  if (Ace->Mask & DesiredAccess)
1109  return FALSE;
1110  }
1111  }
1112 
1113  /* Faulty, deny */
1114  return FALSE;
1115 }
1116 
1117 /* SYSTEM CALLS ***************************************************************/
1118 
1162 NTSTATUS
1163 NTAPI
1169  _Out_opt_ PPRIVILEGE_SET PrivilegeSet,
1170  _Inout_ PULONG PrivilegeSetLength,
1173 {
1174  PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL;
1179  ULONG CapturedPrivilegeSetLength, RequiredPrivilegeSetLength;
1180  PTOKEN Token;
1181  NTSTATUS Status;
1182 
1183  PAGED_CODE();
1184 
1185  /* Check if this is kernel mode */
1186  if (PreviousMode == KernelMode)
1187  {
1188  /* Check if kernel wants everything */
1190  {
1191  /* Give it */
1194  }
1195  else
1196  {
1197  /* Just give the desired access */
1199  }
1200 
1201  /* Success */
1203  return STATUS_SUCCESS;
1204  }
1205 
1206  /* Protect probe in SEH */
1207  _SEH2_TRY
1208  {
1209  /* Probe all pointers */
1210  ProbeForRead(GenericMapping, sizeof(GENERIC_MAPPING), sizeof(ULONG));
1211  ProbeForRead(PrivilegeSetLength, sizeof(ULONG), sizeof(ULONG));
1212  ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG));
1213  ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
1214  ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
1215 
1216  /* Capture the privilege set length and the mapping */
1217  CapturedPrivilegeSetLength = *PrivilegeSetLength;
1218  }
1220  {
1221  /* Return the exception code */
1223  }
1224  _SEH2_END;
1225 
1226  /* Check for unmapped access rights */
1229 
1230  /* Reference the token */
1232  TOKEN_QUERY,
1234  PreviousMode,
1235  (PVOID*)&Token,
1236  NULL);
1237  if (!NT_SUCCESS(Status))
1238  {
1239  DPRINT("Failed to reference token (Status %lx)\n", Status);
1240  return Status;
1241  }
1242 
1243  /* Check token type */
1244  if (Token->TokenType != TokenImpersonation)
1245  {
1246  DPRINT("No impersonation token\n");
1249  }
1250 
1251  /* Check the impersonation level */
1252  if (Token->ImpersonationLevel < SecurityIdentification)
1253  {
1254  DPRINT("Impersonation level < SecurityIdentification\n");
1257  }
1258 
1259  /* Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access */
1262  NULL,
1263  Token,
1264  &Privileges,
1265  PreviousMode);
1266  if (!NT_SUCCESS(Status))
1267  {
1268  DPRINT("SePrivilegePolicyCheck failed (Status 0x%08lx)\n", Status);
1270  *AccessStatus = Status;
1271  *GrantedAccess = 0;
1272  return STATUS_SUCCESS;
1273  }
1274 
1275  /* Check the size of the privilege set and return the privileges */
1276  if (Privileges != NULL)
1277  {
1278  DPRINT("Privileges != NULL\n");
1279 
1280  /* Calculate the required privilege set buffer size */
1281  RequiredPrivilegeSetLength = SepGetPrivilegeSetLength(Privileges);
1282 
1283  /* Fail if the privilege set buffer is too small */
1284  if (CapturedPrivilegeSetLength < RequiredPrivilegeSetLength)
1285  {
1288  *PrivilegeSetLength = RequiredPrivilegeSetLength;
1289  return STATUS_BUFFER_TOO_SMALL;
1290  }
1291 
1292  /* Copy the privilege set to the caller */
1293  RtlCopyMemory(PrivilegeSet,
1294  Privileges,
1295  RequiredPrivilegeSetLength);
1296 
1297  /* Free the local privilege set */
1299  }
1300  else
1301  {
1302  DPRINT("Privileges == NULL\n");
1303 
1304  /* Fail if the privilege set buffer is too small */
1305  if (CapturedPrivilegeSetLength < sizeof(PRIVILEGE_SET))
1306  {
1308  *PrivilegeSetLength = sizeof(PRIVILEGE_SET);
1309  return STATUS_BUFFER_TOO_SMALL;
1310  }
1311 
1312  /* Initialize the privilege set */
1313  PrivilegeSet->PrivilegeCount = 0;
1314  PrivilegeSet->Control = 0;
1315  }
1316 
1317  /* Capture the security descriptor */
1319  PreviousMode,
1320  PagedPool,
1321  FALSE,
1322  &CapturedSecurityDescriptor);
1323  if (!NT_SUCCESS(Status))
1324  {
1325  DPRINT("Failed to capture the Security Descriptor\n");
1327  return Status;
1328  }
1329 
1330  /* Check the captured security descriptor */
1331  if (CapturedSecurityDescriptor == NULL)
1332  {
1333  DPRINT("Security Descriptor is NULL\n");
1336  }
1337 
1338  /* Check security descriptor for valid owner and group */
1339  if (SepGetSDOwner(CapturedSecurityDescriptor) == NULL ||
1340  SepGetSDGroup(CapturedSecurityDescriptor) == NULL)
1341  {
1342  DPRINT("Security Descriptor does not have a valid group or owner\n");
1343  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1344  PreviousMode,
1345  FALSE);
1348  }
1349 
1350  /* Set up the subject context, and lock it */
1352 
1353  /* Lock the token */
1355 
1356  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
1358  {
1359  if (SepTokenIsOwner(Token, CapturedSecurityDescriptor, FALSE))
1360  {
1363  else
1365 
1367  }
1368  }
1369 
1370  if (DesiredAccess == 0)
1371  {
1374  }
1375  else
1376  {
1377  /* Now perform the access check */
1378  SepAccessCheck(CapturedSecurityDescriptor,
1379  Token,
1381  NULL,
1382  DesiredAccess,
1383  NULL,
1384  0,
1387  PreviousMode,
1388  FALSE,
1389  NULL,
1390  GrantedAccess,
1391  AccessStatus);
1392  }
1393 
1394  /* Release subject context and unlock the token */
1397 
1398  /* Release the captured security descriptor */
1399  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1400  PreviousMode,
1401  FALSE);
1402 
1403  /* Dereference the token */
1405 
1406  /* Check succeeded */
1407  return STATUS_SUCCESS;
1408 }
1409 
1452 NTSTATUS
1453 NTAPI
1456  _In_ PSID PrincipalSelfSid,
1457  _In_ HANDLE ClientToken,
1459  _In_ POBJECT_TYPE_LIST ObjectTypeList,
1460  _In_ ULONG ObjectTypeLength,
1462  _In_ PPRIVILEGE_SET PrivilegeSet,
1463  _Inout_ PULONG PrivilegeSetLength,
1466 {
1467  UNIMPLEMENTED;
1468  return STATUS_NOT_IMPLEMENTED;
1469 }
1470 
1514 NTSTATUS
1515 NTAPI
1518  _In_ PSID PrincipalSelfSid,
1519  _In_ HANDLE ClientToken,
1521  _In_ POBJECT_TYPE_LIST ObjectTypeList,
1522  _In_ ULONG ObjectTypeLength,
1524  _In_ PPRIVILEGE_SET PrivilegeSet,
1525  _Inout_ PULONG PrivilegeSetLength,
1528 {
1529  UNIMPLEMENTED;
1530  return STATUS_NOT_IMPLEMENTED;
1531 }
1532 
1533 /* EOF */
_SEH2_TRY
Definition: create.c:4226
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
VOID SepDumpSdDebugInfo(_In_opt_ PISECURITY_DESCRIPTOR SecurityDescriptor)
Dumps debug information of a security descriptor to the debugger.
Definition: debug.c:215
#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:850
#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:14
#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:1646
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:3062
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)
_SEH2_END
Definition: create.c:4400
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
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
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
#define FALSE
Definition: types.h:117
VOID SepDumpTokenDebugInfo(_In_opt_ PTOKEN Token)
Dumps debug information of an access token to the debugger.
Definition: debug.c:274
#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
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
unsigned char BOOLEAN
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
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:1454
#define _In_
Definition: ms_sal.h:308
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
#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:43
_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:1164
#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
static PSID SepGetSDGroup(_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
Retrieves the group from a security descriptor.
Definition: accesschk.c:823
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:1593
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:286
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:44
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:579
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: sid.c:443
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:910
VOID NTAPI SeFreePrivileges(_In_ PPRIVILEGE_SET Privileges)
Frees a set of privileges.
Definition: priv.c:669
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
static PSID SepGetSDOwner(_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
Retrieves the main user from a security descriptor.
Definition: accesschk.c:796
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:1913
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:1597
#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:1516
#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: token.c:511
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:219
VOID SepDumpAccessRightsStats(_In_opt_ PACCESS_CHECK_RIGHTS AccessRights)
Dumps security access rights to the debugger.
Definition: debug.c:315
#define SepAcquireTokenLockShared(Token)
Definition: se.h:280
_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:119
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
#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:45
#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:1054
#define TAG_ACCESS_CHECK_RIGHT
Definition: tag.h:167
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