ReactOS  0.4.15-dev-5608-gafb953a
accesschk.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for accesschk.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PACCESS_CHECK_RIGHTS SepInitAccessCheckRights (VOID)
 Allocates memory for the internal access check rights data structure and initializes it for use for the kernel. The purpose of this piece of data is to track down the remaining, granted and denied access rights whilst we are doing an access check procedure. More...
 
VOID SepFreeAccessCheckRights (_In_ PACCESS_CHECK_RIGHTS AccessRights)
 Frees an allocated access check rights from memory space after access check procedures have finished. More...
 
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 access right masks of each entry with the purpose to judge whether the calling thread can be warranted access check to a certain object or not. More...
 
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 order to access an object depending on the security descriptor and other security context entities, such as an owner. This function is the heart and brain of the whole access check algorithm in the kernel. More...
 
static PSID SepGetSDOwner (_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
 Retrieves the main user from a security descriptor. More...
 
static PSID SepGetSDGroup (_In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
 Retrieves the group from a security descriptor. More...
 
static ULONG SepGetPrivilegeSetLength (_In_ PPRIVILEGE_SET PrivilegeSet)
 Retrieves the length size of a set list of privileges structure. More...
 
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 descriptor and other security context entities, such as an owner. More...
 
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 descriptor. Unlike the regular access check procedure in the NT kernel, the fast traverse check is a faster way to quickly check if access can be made into an object. More...
 
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 descriptor and a valid handle to an access token. More...
 
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 such access through type. More...
 
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 such access through type list. More...
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file accesschk.c.

Function Documentation

◆ NtAccessCheck()

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 descriptor and a valid handle to an access token.

Parameters
[in]SecurityDescriptorSecurity descriptor of the object that is being accessed.
[in]TokenHandleA handle to a token.
[in]DesiredAccessThe access right bitmask where the calling thread wants to acquire.
[in]GenericMappingThe generic mapping of access rights of an object type.
[out]PrivilegeSetThe returned set of privileges.
[in,out]PrivilegeSetLengthThe total length size of a set of privileges.
[out]GrantedAccessA list of granted access rights.
[out]AccessStatusThe returned status code specifying why access cannot be made onto an object (if said access is denied in the first place).
Returns
Returns STATUS_SUCCESS if access check has been done without problems and that the object can be accessed. STATUS_GENERIC_NOT_MAPPED is returned if no generic access right is mapped. STATUS_NO_IMPERSONATION_TOKEN is returned if the token from the handle is not an impersonation token. STATUS_BAD_IMPERSONATION_LEVEL is returned if the token cannot be impersonated because the current security impersonation level doesn't permit so. STATUS_INVALID_SECURITY_DESCR is returned if the security descriptor given to the call is not a valid one. STATUS_BUFFER_TOO_SMALL is returned if the buffer to the captured privileges has a length that is less than the required size of the set of privileges. A failure NTSTATUS code is returned otherwise.

Definition at line 1164 of file accesschk.c.

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 }
_SEH2_TRY
Definition: create.c:4226
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
_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
static ULONG SepGetPrivilegeSetLength(_In_ PPRIVILEGE_SET PrivilegeSet)
Retrieves the length size of a set list of privileges structure.
Definition: accesschk.c:850
struct _PRIVILEGE_SET PRIVILEGE_SET
_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
_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
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
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
_SEH2_END
Definition: create.c:4400
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
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
#define FALSE
Definition: types.h:117
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STATUS_GENERIC_NOT_MAPPED
Definition: ntstatus.h:466
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
#define STATUS_NO_IMPERSONATION_TOKEN
Definition: ntstatus.h:328
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
PACCESS_TOKEN PrimaryToken
Definition: setypes.h:220
#define TOKEN_QUERY
Definition: setypes.h:924
#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 WRITE_DAC
Definition: nt_native.h:59
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define READ_CONTROL
Definition: nt_native.h:58
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
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
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
#define NULL
Definition: types.h:112
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
#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
#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 _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#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
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGED_CODE()
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13

Referenced by AccessCheck(), and CheckTokenMembership().

◆ NtAccessCheckByType()

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 such access through type.

Parameters
[in]SecurityDescriptorA security descriptor with information data for auditing.
[in]PrincipalSelfSidA principal self user SID.
[in]ClientTokenA client access token.
[in]DesiredAccessThe desired access masks rights requested by the caller.
[in]ObjectTypeListA list of object types.
[in]ObjectTypeLengthThe length size of the list.
[in]GenericMappingThe generic mapping list of access masks rights.
[in]PrivilegeSetAn array set of privileges.
[in,out]PrivilegeSetLengthThe length size of the array set of privileges.
[out]GrantedAccessThe returned granted access rights.
[out]AccessStatusThe returned NTSTATUS code indicating the final results of auditing.
Returns
To be added...

Definition at line 1454 of file accesschk.c.

1466 {
1467  UNIMPLEMENTED;
1468  return STATUS_NOT_IMPLEMENTED;
1469 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

◆ NtAccessCheckByTypeResultList()

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 such access through type list.

Parameters
[in]SecurityDescriptorA security descriptor with information data for auditing.
[in]PrincipalSelfSidA principal self user SID.
[in]ClientTokenA client access token.
[in]DesiredAccessThe desired access masks rights requested by the caller.
[in]ObjectTypeListA list of object types.
[in]ObjectTypeLengthThe length size of the list.
[in]GenericMappingThe generic mapping list of access masks rights.
[in]PrivilegeSetAn array set of privileges.
[in,out]PrivilegeSetLengthThe length size of the array set of privileges.
[out]GrantedAccessThe returned granted access rights.
[out]AccessStatusThe returned NTSTATUS code indicating the final results of auditing.
Returns
To be added...

Definition at line 1516 of file accesschk.c.

1528 {
1529  UNIMPLEMENTED;
1530  return STATUS_NOT_IMPLEMENTED;
1531 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

◆ SeAccessCheck()

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 descriptor and other security context entities, such as an owner.

Parameters
[in]SecurityDescriptorSecurity descriptor of the object that is being accessed.
[in]SubjectSecurityContextThe captured subject security context.
[in]SubjectContextLockedIf set to TRUE, the caller acknowledges that the subject context has already been locked by the caller himself. If set to FALSE, the function locks the subject context.
[in]DesiredAccessAccess right bitmask that the calling thread wants to acquire.
[in]PreviouslyGrantedAccessThe access rights previously acquired in the past.
[out]PrivilegesThe returned set of privileges.
[in]GenericMappingThe generic mapping of access rights of an object type.
[in]AccessModeThe processor request level mode.
[out]GrantedAccessA list of granted access rights.
[out]AccessStatusThe returned status code specifying why access cannot be made onto an object (if said access is denied in the first place).
Returns
Returns TRUE if access onto the specific object is allowed, FALSE otherwise.

Definition at line 910 of file accesschk.c.

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 }
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
_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
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
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
#define FALSE
Definition: types.h:117
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
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
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN SubjectContextLocked
Definition: sefuncs.h:13
PACCESS_TOKEN PrimaryToken
Definition: setypes.h:220
#define WRITE_DAC
Definition: nt_native.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define READ_CONTROL
Definition: nt_native.h:58
int ret
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
#define NULL
Definition: types.h:112
#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
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK PreviouslyGrantedAccess
Definition: sefuncs.h:13
#define STATUS_SUCCESS
Definition: shellext.h:65
ACCESS_MASK GenericAll
Definition: nt_native.h:568
_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
PACCESS_TOKEN ClientToken
Definition: setypes.h:218
#define PAGED_CODE()
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13

Referenced by create_stream(), FatExplicitDeviceAccessGranted(), file_create(), IopParseDevice(), NpCreateClientEnd(), NpCreateExistingNamedPipe(), ObCheckCreateObjectAccess(), ObCheckObjectAccess(), ObpCheckObjectReference(), ObpCheckTraverseAccess(), open_file2(), PspCreateProcess(), PspCreateThread(), PspSetPrimaryToken(), set_link_information(), set_rename_information(), START_TEST(), and UDFCheckAccessRights().

◆ SeFastTraverseCheck()

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 descriptor. Unlike the regular access check procedure in the NT kernel, the fast traverse check is a faster way to quickly check if access can be made into an object.

Parameters
[in]SecurityDescriptorSecurity descriptor of the object that is being accessed.
[in]AccessStateAn access state to determine if the access token in the current security context of the object is an restricted token.
[in]DesiredAccessThe access right bitmask where the calling thread wants to acquire.
[in]AccessModeProcess level request mode.
Returns
Returns TRUE if access onto the specific object is allowed, FALSE otherwise.

Definition at line 1054 of file accesschk.c.

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 }
struct _KNOWN_ACE * PKNOWN_ACE
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
Definition: se.h:14
#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
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
Definition: card.h:12
#define ASSERT(a)
Definition: mode.c:44
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
PSID SeWorldSid
Definition: sid.c:25
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:119
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1179
#define PAGED_CODE()

Referenced by IopParseDevice(), and ObpCheckTraverseAccess().

◆ SepAccessCheck()

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 order to access an object depending on the security descriptor and other security context entities, such as an owner. This function is the heart and brain of the whole access check algorithm in the kernel.

Parameters
[in]ClientAccessTokenA pointer to a client (thread) access token that requests access rights of an object or subset of multiple objects.
[in]PrimaryAccessTokenA pointer to a primary access token that describes the primary security context of the main calling process.
[in]PrincipalSelfSidA pointer to a security identifier that represents a security principal, that is, a user object associated with its security descriptor.
[in]DesiredAccessThe access rights desired by the calling thread to acquire in order to access an object.
[in]ObjectTypeListAn array list of object types to be checked against for access. The function will act accordingly in this case by checking each sub-object of an object of primary level and such. If this parameter is NULL, the function will perform a normal access check against the target object itself.
[in]ObjectTypeListLengthThe length of a object type list. Such length represents the number of elements in this list.
[in]PreviouslyGrantedAccessThe access rights previously acquired in the past. If this parameter is 0, it is deemed that the calling thread hasn't acquired any rights. Access checks are more tighten in this case.
[in]GenericMappingA pointer to a generic mapping of access rights of the target object.
[in]AccessModeThe processor request level mode.
[in]UseResultListIf set to TRUE, the function will return a list of granted access rights of each sub-object as well as status code for each. If this parameter is set to FALSE, then the function will just return only the granted access rights and status code for single object that's been target for access checks.
[out]PrivilegesA pointer to a definite set of privileges that have been audited whilst doing access check procedures. Such set of privileges are optionally returned to the caller. This can be set to NULL if the caller doesn't want to obtain a set of privileges.
[out]GrantedAccessListA list of granted access rights returned to the caller. This list can comprehend multiple elements which represent the sub-objects that have been checked or a single element which is the target object itself.
[out]AccessStatusListA list of access status codes returned to the caller. This list can comprehend multiple elements which represent the sub-objects that have been checked or a single element which is the target object itself.
Returns
Returns TRUE if access onto the specific object is allowed, FALSE otherwise.

Definition at line 465 of file accesschk.c.

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 }
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
VOID SepDumpSdDebugInfo(_In_opt_ PISECURITY_DESCRIPTOR SecurityDescriptor)
Dumps debug information of a security descriptor to the debugger.
Definition: debug.c:215
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#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
LONG NTSTATUS
Definition: precomp.h:26
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
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
#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
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
ACCESS_MASK RemainingAccessRights
Definition: se.h:43
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
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
ACCESS_MASK GrantedAccessRights
Definition: se.h:44
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
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 NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
VOID SepDumpAccessRightsStats(_In_opt_ PACCESS_CHECK_RIGHTS AccessRights)
Dumps security access rights to the debugger.
Definition: debug.c:315
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK PreviouslyGrantedAccess
Definition: sefuncs.h:13
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
ACCESS_MASK GenericAll
Definition: nt_native.h:568
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
#define PAGED_CODE()

Referenced by NtAccessCheck(), and SeAccessCheck().

◆ SepAnalyzeAcesFromDacl()

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 access right masks of each entry with the purpose to judge whether the calling thread can be warranted access check to a certain object or not.

Parameters
[in]ActionTypeThe type of analysis to be done against an access entry. This type influences how access rights are gathered. This can either be AccessCheckMaximum which means the algorithm will perform analysis against ACEs on behalf of the requestor that gave us the acknowledgement that he desires MAXIMUM_ALLOWED access right or AccessCheckRegular if the requestor wants a subset of access rights.
[in]DaclThe discretionary access control list to be given to this function. This DACL must have at least one ACE currently present in the list.
[in]AccessTokenA pointer to an access token, where an equality comparison check is performed if the security identifier (SID) from a ACE of a certain object is present in this token. This token represents the effective (calling thread) token of the caller.
[in]PrimaryAccessTokenA pointer to an access token, represented as an access token associated with the primary calling process. This token describes the primary security context of the main process.
[in]IsTokenRestrictedIf this parameter is set to TRUE, the function considers the token pointed by AccessToken parameter argument as restricted. That is, the token has restricted SIDs therefore the function will act accordingly against that token by checking for restricted SIDs only when doing an equaility comparison check between the two identifiers.
[in]AccessRightsAllocatedIf this parameter is set to TRUE, the function will not allocate the access check rights again. This is typical when we have to do additional analysis of ACEs because a token has restricted SIDs (see IsTokenRestricted parameter) of which we already initialized the access check rights pointer before.
[in]PrincipalSelfSidA pointer to a security identifier that represents a principal. A principal identifies a user object which is associated with its own security descriptor.
[in]GenericMappingA pointer to a generic mapping that is associated with the object in question being checked for access. If certain set of desired access rights have a generic access right, this parameter is needed to map generic rights.
[in]ObjectTypeListA pointer to a list array of object types. If such array is provided to the function, the algorithm will perform a different approach by doing analysis against ACEs each sub-object of an object of primary level (level 0) or sub-objects of a sub-object of an object. If this parameter is NULL, the function will normally analyze the ACEs of a DACL of the target object itself.
[in]ObjectTypeListLengthThe length of the object type list array, pointed by ObjectTypeList. This length in question represents the number of elements in such array. This parameter must be 0 if no array list is provided.
[in]RemainingAccessThe remaining access rights that have yet to be granted to the calling thread whomst requests access to a certain object. This parameter mustn't be 0 as the remaining rights are left to be addressed. This is the case if we have to address the remaining rights on a regular subset basis (the requestor didn't ask for MAXIMUM_ALLOWED). Otherwise this parameter can be 0.
Returns
Returns a pointer to initialized access check rights after ACE analysis has finished. This pointer contains the rights that have been acquired in order to determine if access can be granted to the calling thread. Typically this pointer contains the remaining, denied and granted rights.

Otherwise NULL is returned and thus access check procedure can't any longer continue further. We have prematurely failed this access check operation at this point.

Definition at line 161 of file accesschk.c.

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 }
#define DEFAULT_UNREACHABLE
UCHAR AceFlags
Definition: ms-dtyp.idl:211
#define TRUE
Definition: types.h:120
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:318
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
ACCESS_MASK AccessMask
Definition: rtltypes.h:995
#define FALSE
Definition: types.h:117
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
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
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
UCHAR AceType
Definition: ms-dtyp.idl:210
ACCESS_MASK GrantedAccessRights
Definition: se.h:44
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
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
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
#define NULL
Definition: types.h:112
#define GENERIC_ACCESS
Definition: security.c:35
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
ACCESS_MASK DeniedAccessRights
Definition: se.h:45
#define DPRINT
Definition: sndvol32.h:71
BOOL WINAPI IsTokenRestricted(HANDLE TokenHandle)
Definition: token.c:207
Definition: rtltypes.h:992
ACE_HEADER Header
Definition: rtltypes.h:994
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
#define PAGED_CODE()

Referenced by SepAccessCheck().

◆ SepFreeAccessCheckRights()

VOID SepFreeAccessCheckRights ( _In_ PACCESS_CHECK_RIGHTS  AccessRights)

Frees an allocated access check rights from memory space after access check procedures have finished.

Parameters
[in]AccessRightsA pointer to access check rights of which is to be freed from memory.
Returns
Nothing.

Definition at line 70 of file accesschk.c.

72 {
73  PAGED_CODE();
74 
75  if (AccessRights)
76  {
78  }
79 }
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define TAG_ACCESS_CHECK_RIGHT
Definition: tag.h:167
#define PAGED_CODE()

Referenced by SepAccessCheck().

◆ SepGetPrivilegeSetLength()

static ULONG SepGetPrivilegeSetLength ( _In_ PPRIVILEGE_SET  PrivilegeSet)
static

Retrieves the length size of a set list of privileges structure.

Parameters
[in]PrivilegeSetA valid set of privileges.
Returns
Returns the total length of a set of privileges.

Definition at line 850 of file accesschk.c.

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 }
struct _PRIVILEGE_SET PRIVILEGE_SET
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by NtAccessCheck().

◆ SepGetSDGroup()

static PSID SepGetSDGroup ( _In_ PSECURITY_DESCRIPTOR  _SecurityDescriptor)
static

Retrieves the group from a security descriptor.

Parameters
[in]SecurityDescriptorA valid allocated security descriptor structure where the group is to be retrieved.
Returns
Returns a SID that represents a group.

Definition at line 823 of file accesschk.c.

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 }
#define SE_SELF_RELATIVE
Definition: setypes.h:830
_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
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _SID * PSID
Definition: eventlog.c:35
#define ULONG_PTR
Definition: config.h:101

Referenced by NtAccessCheck().

◆ SepGetSDOwner()

static PSID SepGetSDOwner ( _In_ PSECURITY_DESCRIPTOR  _SecurityDescriptor)
static

Retrieves the main user from a security descriptor.

Parameters
[in]SecurityDescriptorA valid allocated security descriptor structure where the owner is to be retrieved.
Returns
Returns a SID that represents the main user (owner).

Definition at line 796 of file accesschk.c.

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 }
#define SE_SELF_RELATIVE
Definition: setypes.h:830
_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
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _SID * PSID
Definition: eventlog.c:35
_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 ULONG_PTR
Definition: config.h:101

Referenced by NtAccessCheck().

◆ SepInitAccessCheckRights()

PACCESS_CHECK_RIGHTS SepInitAccessCheckRights ( VOID  )

Allocates memory for the internal access check rights data structure and initializes it for use for the kernel. The purpose of this piece of data is to track down the remaining, granted and denied access rights whilst we are doing an access check procedure.

Returns
Returns a pointer to allocated and initialized access check rights, otherwise NULL is returned.

Definition at line 31 of file accesschk.c.

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 }
ACCESS_MASK RemainingAccessRights
Definition: se.h:43
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ACCESS_MASK GrantedAccessRights
Definition: se.h:44
#define NULL
Definition: types.h:112
ACCESS_MASK DeniedAccessRights
Definition: se.h:45
#define TAG_ACCESS_CHECK_RIGHT
Definition: tag.h:167
#define PAGED_CODE()

Referenced by SepAnalyzeAcesFromDacl().