ReactOS  0.4.15-dev-4853-g3a72a52
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 1157 of file accesschk.c.

1166 {
1167  PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL;
1172  ULONG CapturedPrivilegeSetLength, RequiredPrivilegeSetLength;
1173  PTOKEN Token;
1174  NTSTATUS Status;
1175 
1176  PAGED_CODE();
1177 
1178  /* Check if this is kernel mode */
1179  if (PreviousMode == KernelMode)
1180  {
1181  /* Check if kernel wants everything */
1183  {
1184  /* Give it */
1187  }
1188  else
1189  {
1190  /* Just give the desired access */
1192  }
1193 
1194  /* Success */
1196  return STATUS_SUCCESS;
1197  }
1198 
1199  /* Protect probe in SEH */
1200  _SEH2_TRY
1201  {
1202  /* Probe all pointers */
1203  ProbeForRead(GenericMapping, sizeof(GENERIC_MAPPING), sizeof(ULONG));
1204  ProbeForRead(PrivilegeSetLength, sizeof(ULONG), sizeof(ULONG));
1205  ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG));
1206  ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG));
1207  ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG));
1208 
1209  /* Capture the privilege set length and the mapping */
1210  CapturedPrivilegeSetLength = *PrivilegeSetLength;
1211  }
1213  {
1214  /* Return the exception code */
1216  }
1217  _SEH2_END;
1218 
1219  /* Check for unmapped access rights */
1222 
1223  /* Reference the token */
1225  TOKEN_QUERY,
1227  PreviousMode,
1228  (PVOID*)&Token,
1229  NULL);
1230  if (!NT_SUCCESS(Status))
1231  {
1232  DPRINT("Failed to reference token (Status %lx)\n", Status);
1233  return Status;
1234  }
1235 
1236  /* Check token type */
1237  if (Token->TokenType != TokenImpersonation)
1238  {
1239  DPRINT("No impersonation token\n");
1242  }
1243 
1244  /* Check the impersonation level */
1245  if (Token->ImpersonationLevel < SecurityIdentification)
1246  {
1247  DPRINT("Impersonation level < SecurityIdentification\n");
1250  }
1251 
1252  /* Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access */
1255  NULL,
1256  Token,
1257  &Privileges,
1258  PreviousMode);
1259  if (!NT_SUCCESS(Status))
1260  {
1261  DPRINT("SePrivilegePolicyCheck failed (Status 0x%08lx)\n", Status);
1263  *AccessStatus = Status;
1264  *GrantedAccess = 0;
1265  return STATUS_SUCCESS;
1266  }
1267 
1268  /* Check the size of the privilege set and return the privileges */
1269  if (Privileges != NULL)
1270  {
1271  DPRINT("Privileges != NULL\n");
1272 
1273  /* Calculate the required privilege set buffer size */
1274  RequiredPrivilegeSetLength = SepGetPrivilegeSetLength(Privileges);
1275 
1276  /* Fail if the privilege set buffer is too small */
1277  if (CapturedPrivilegeSetLength < RequiredPrivilegeSetLength)
1278  {
1281  *PrivilegeSetLength = RequiredPrivilegeSetLength;
1282  return STATUS_BUFFER_TOO_SMALL;
1283  }
1284 
1285  /* Copy the privilege set to the caller */
1286  RtlCopyMemory(PrivilegeSet,
1287  Privileges,
1288  RequiredPrivilegeSetLength);
1289 
1290  /* Free the local privilege set */
1292  }
1293  else
1294  {
1295  DPRINT("Privileges == NULL\n");
1296 
1297  /* Fail if the privilege set buffer is too small */
1298  if (CapturedPrivilegeSetLength < sizeof(PRIVILEGE_SET))
1299  {
1301  *PrivilegeSetLength = sizeof(PRIVILEGE_SET);
1302  return STATUS_BUFFER_TOO_SMALL;
1303  }
1304 
1305  /* Initialize the privilege set */
1306  PrivilegeSet->PrivilegeCount = 0;
1307  PrivilegeSet->Control = 0;
1308  }
1309 
1310  /* Capture the security descriptor */
1312  PreviousMode,
1313  PagedPool,
1314  FALSE,
1315  &CapturedSecurityDescriptor);
1316  if (!NT_SUCCESS(Status))
1317  {
1318  DPRINT("Failed to capture the Security Descriptor\n");
1320  return Status;
1321  }
1322 
1323  /* Check the captured security descriptor */
1324  if (CapturedSecurityDescriptor == NULL)
1325  {
1326  DPRINT("Security Descriptor is NULL\n");
1329  }
1330 
1331  /* Check security descriptor for valid owner and group */
1332  if (SepGetSDOwner(CapturedSecurityDescriptor) == NULL ||
1333  SepGetSDGroup(CapturedSecurityDescriptor) == NULL)
1334  {
1335  DPRINT("Security Descriptor does not have a valid group or owner\n");
1336  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1337  PreviousMode,
1338  FALSE);
1341  }
1342 
1343  /* Set up the subject context, and lock it */
1345 
1346  /* Lock the token */
1348 
1349  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
1351  {
1352  if (SepTokenIsOwner(Token, CapturedSecurityDescriptor, FALSE))
1353  {
1356  else
1358 
1360  }
1361  }
1362 
1363  if (DesiredAccess == 0)
1364  {
1367  }
1368  else
1369  {
1370  /* Now perform the access check */
1371  SepAccessCheck(CapturedSecurityDescriptor,
1372  Token,
1374  NULL,
1375  DesiredAccess,
1376  NULL,
1377  0,
1380  PreviousMode,
1381  FALSE,
1382  NULL,
1383  GrantedAccess,
1384  AccessStatus);
1385  }
1386 
1387  /* Release subject context and unlock the token */
1390 
1391  /* Release the captured security descriptor */
1392  SeReleaseSecurityDescriptor(CapturedSecurityDescriptor,
1393  PreviousMode,
1394  FALSE);
1395 
1396  /* Dereference the token */
1398 
1399  /* Check succeeded */
1400  return STATUS_SUCCESS;
1401 }
#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:843
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:3063
BOOLEAN NTAPI SepAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_opt_ PACCESS_TOKEN ClientAccessToken, _In_ PACCESS_TOKEN PrimaryAccessToken, _In_opt_ PSID PrincipalSelfSid, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ ACCESS_MASK PreviouslyGrantedAccess, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN UseResultList, _Out_opt_ PPRIVILEGE_SET *Privileges, _Out_ PACCESS_MASK GrantedAccessList, _Out_ PNTSTATUS AccessStatusList)
Private function that determines whether security access rights can be given to the calling thread in...
Definition: accesschk.c:465
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
_SEH2_TRY
Definition: create.c:4226
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:816
NTSTATUS NTAPI SeCaptureSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Captures a security descriptor.
Definition: sd.c:386
#define ObDereferenceObject
Definition: obfuncs.h:203
#define 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
_SEH2_END
Definition: create.c:4400
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:789
#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 1447 of file accesschk.c.

1459 {
1460  UNIMPLEMENTED;
1461  return STATUS_NOT_IMPLEMENTED;
1462 }
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 1509 of file accesschk.c.

1521 {
1522  UNIMPLEMENTED;
1523  return STATUS_NOT_IMPLEMENTED;
1524 }
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 903 of file accesschk.c.

914 {
915  BOOLEAN ret;
916 
917  PAGED_CODE();
918 
919  /* Check if this is kernel mode */
920  if (AccessMode == KernelMode)
921  {
922  /* Check if kernel wants everything */
924  {
925  /* Give it */
929  }
930  else
931  {
932  /* Give the desired and previous access */
934  }
935 
936  /* Success */
938  return TRUE;
939  }
940 
941  /* Check if we didn't get an SD */
942  if (!SecurityDescriptor)
943  {
944  /* Automatic failure */
946  return FALSE;
947  }
948 
949  /* Check for invalid impersonation */
952  {
954  return FALSE;
955  }
956 
957  /* Acquire the lock if needed */
960 
961  /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */
963  {
966 
969  FALSE))
970  {
973  else
975 
977  }
978  }
979 
980  if (DesiredAccess == 0)
981  {
983  if (PreviouslyGrantedAccess == 0)
984  {
985  DPRINT1("Request for zero access to an object. Denying.\n");
987  ret = FALSE;
988  }
989  else
990  {
992  ret = TRUE;
993  }
994  }
995  else
996  {
997  /* Call the internal function */
1001  NULL,
1002  DesiredAccess,
1003  NULL,
1004  0,
1007  AccessMode,
1008  FALSE,
1009  Privileges,
1010  GrantedAccess,
1011  AccessStatus);
1012  }
1013 
1014  /* Release the lock if needed */
1015  if (!SubjectContextLocked)
1017 
1018  return ret;
1019 }
#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
_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
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 1047 of file accesschk.c.

1052 {
1053  PACL Dacl;
1054  ULONG AceIndex;
1055  PKNOWN_ACE Ace;
1056 
1057  PAGED_CODE();
1058 
1060 
1061  if (SecurityDescriptor == NULL)
1062  return FALSE;
1063 
1064  /* Get DACL */
1066  /* If no DACL, grant access */
1067  if (Dacl == NULL)
1068  return TRUE;
1069 
1070  /* No ACE -> Deny */
1071  if (!Dacl->AceCount)
1072  return FALSE;
1073 
1074  /* Can't perform the check on restricted token */
1075  if (AccessState->Flags & TOKEN_IS_RESTRICTED)
1076  return FALSE;
1077 
1078  /* Browse the ACEs */
1079  for (AceIndex = 0, Ace = (PKNOWN_ACE)((ULONG_PTR)Dacl + sizeof(ACL));
1080  AceIndex < Dacl->AceCount;
1081  AceIndex++, Ace = (PKNOWN_ACE)((ULONG_PTR)Ace + Ace->Header.AceSize))
1082  {
1083  if (Ace->Header.AceFlags & INHERIT_ONLY_ACE)
1084  continue;
1085 
1086  /* If access-allowed ACE */
1087  if (Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
1088  {
1089  /* Check if all accesses are granted */
1090  if (!(Ace->Mask & DesiredAccess))
1091  continue;
1092 
1093  /* Check SID and grant access if matching */
1094  if (RtlEqualSid(SeWorldSid, &(Ace->SidStart)))
1095  return TRUE;
1096  }
1097  /* If access-denied ACE */
1098  else if (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE)
1099  {
1100  /* Here, only check if it denies any access wanted and deny if so */
1101  if (Ace->Mask & DesiredAccess)
1102  return FALSE;
1103  }
1104  }
1105 
1106  /* Faulty, deny */
1107  return FALSE;
1108 }
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:1552
_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  PACCESS_CHECK_RIGHTS AccessCheckRights;
484  ULONG ResultListLength;
485  ULONG ResultListIndex;
486  PACL Dacl;
487  BOOLEAN Present;
488  BOOLEAN Defaulted;
490 
491  PAGED_CODE();
492 
493  /* A security descriptor must be expected for access checks */
495 
496  /* Assume no access check rights first */
497  AccessCheckRights = NULL;
498 
499  /* Check for no access desired */
500  if (!DesiredAccess)
501  {
502  /* Check if we had no previous access */
504  {
505  /* Then there's nothing to give */
506  DPRINT1("SepAccessCheck(): The caller has no previously granted access gained!\n");
508  goto ReturnCommonStatus;
509  }
510 
511  /* Return the previous access only */
513  *Privileges = NULL;
514  goto ReturnCommonStatus;
515  }
516 
517  /* Map given accesses */
521 
522  /* Initialize remaining access rights */
523  RemainingAccess = DesiredAccess;
524 
525  /*
526  * Obtain the token provided by the caller. Client (or also
527  * called impersonation or thread) token takes precedence over
528  * the primary token which is the token associated with the security
529  * context of the main calling process. This is because it is the
530  * client itself that requests access of an object or subset of
531  * multiple objects. Otherwise obtain the security context of the
532  * main process (the actual primary token).
533  */
534  Token = ClientAccessToken ? ClientAccessToken : PrimaryAccessToken;
535 
536  /*
537  * We should at least expect a primary token
538  * to be present if client token is not
539  * available.
540  */
541  ASSERT(Token);
542 
543  /*
544  * Check for ACCESS_SYSTEM_SECURITY and WRITE_OWNER access.
545  * Write down a set of privileges that have been checked
546  * if the caller wants it.
547  */
548  Status = SePrivilegePolicyCheck(&RemainingAccess,
550  NULL,
551  Token,
552  Privileges,
553  AccessMode);
554  if (!NT_SUCCESS(Status))
555  {
556  goto ReturnCommonStatus;
557  }
558 
559  /* Succeed if there are no more rights to grant */
560  if (RemainingAccess == 0)
561  {
563  goto ReturnCommonStatus;
564  }
565 
566  /* Get the DACL */
568  &Present,
569  &Dacl,
570  &Defaulted);
571  if (!NT_SUCCESS(Status))
572  {
573  goto ReturnCommonStatus;
574  }
575 
576  /* Grant desired access if the object is unprotected */
577  if (Present == FALSE || Dacl == NULL)
578  {
579  PreviouslyGrantedAccess |= RemainingAccess;
580  if (RemainingAccess & MAXIMUM_ALLOWED)
581  {
584  }
585 
587  goto ReturnCommonStatus;
588  }
589 
590  /* Deny access if the DACL is empty */
591  if (Dacl->AceCount == 0)
592  {
593  if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0)
594  {
596  }
597  else
598  {
599  DPRINT1("SepAccessCheck(): The DACL has no ACEs and the caller has no previously granted access!\n");
602  }
603  goto ReturnCommonStatus;
604  }
605 
606  /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */
608  {
609  /* Perform access checks against ACEs from this DACL */
610  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
611  Dacl,
612  Token,
613  PrimaryAccessToken,
614  FALSE,
615  FALSE,
616  PrincipalSelfSid,
618  ObjectTypeList,
619  ObjectTypeListLength,
620  0);
621 
622  /*
623  * Getting the access check rights is very
624  * important as we have to do access checks
625  * depending on the kind of rights we get.
626  * Fail prematurely if we can't...
627  */
628  if (!AccessCheckRights)
629  {
630  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
633  goto ReturnCommonStatus;
634  }
635 
636  /*
637  * Perform further access checks if this token
638  * has restricted SIDs.
639  */
641  {
642  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckMaximum,
643  Dacl,
644  Token,
645  PrimaryAccessToken,
646  TRUE,
647  TRUE,
648  PrincipalSelfSid,
650  ObjectTypeList,
651  ObjectTypeListLength,
652  0);
653  }
654 
655  /* Fail if some rights have not been granted */
656  RemainingAccess &= ~(MAXIMUM_ALLOWED | AccessCheckRights->GrantedAccessRights);
657  if (RemainingAccess != 0)
658  {
659  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", RemainingAccess, DesiredAccess);
662  goto ReturnCommonStatus;
663  }
664 
665  /* Set granted access right and access status */
666  PreviouslyGrantedAccess |= AccessCheckRights->GrantedAccessRights;
667  if (PreviouslyGrantedAccess != 0)
668  {
670  }
671  else
672  {
673  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
675  }
676 
677  /* We have successfully granted all the rights */
678  goto ReturnCommonStatus;
679  }
680 
681  /* Grant rights according to the DACL */
682  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
683  Dacl,
684  Token,
685  PrimaryAccessToken,
686  FALSE,
687  FALSE,
688  PrincipalSelfSid,
690  ObjectTypeList,
691  ObjectTypeListLength,
692  RemainingAccess);
693 
694  /*
695  * Getting the access check rights is very
696  * important as we have to do access checks
697  * depending on the kind of rights we get.
698  * Fail prematurely if we can't...
699  */
700  if (!AccessCheckRights)
701  {
702  DPRINT1("SepAccessCheck(): Failed to obtain access check rights!\n");
705  goto ReturnCommonStatus;
706  }
707 
708  /* Fail if some rights have not been granted */
709  if (AccessCheckRights->RemainingAccessRights != 0)
710  {
711  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
714  goto ReturnCommonStatus;
715  }
716 
717  /*
718  * Perform further access checks if this token
719  * has restricted SIDs.
720  */
722  {
723  AccessCheckRights = SepAnalyzeAcesFromDacl(AccessCheckRegular,
724  Dacl,
725  Token,
726  PrimaryAccessToken,
727  TRUE,
728  TRUE,
729  PrincipalSelfSid,
731  ObjectTypeList,
732  ObjectTypeListLength,
733  RemainingAccess);
734 
735  /* Fail if some rights have not been granted */
736  if (AccessCheckRights->RemainingAccessRights != 0)
737  {
738  DPRINT1("SepAccessCheck(): Failed to grant access rights. RemainingAccess = 0x%08lx DesiredAccess = 0x%08lx\n", AccessCheckRights->RemainingAccessRights, DesiredAccess);
741  goto ReturnCommonStatus;
742  }
743  }
744 
745  /* Set granted access rights */
747 
748  /* Fail if no rights have been granted */
749  if (PreviouslyGrantedAccess == 0)
750  {
751  DPRINT1("SepAccessCheck(): Failed to grant access rights. PreviouslyGrantedAccess == 0 DesiredAccess = %08lx\n", DesiredAccess);
753  goto ReturnCommonStatus;
754  }
755 
756  /*
757  * If we're here then we granted all the desired
758  * access rights the caller wanted.
759  */
761 
762 ReturnCommonStatus:
763  ResultListLength = UseResultList ? ObjectTypeListLength : 1;
764  for (ResultListIndex = 0; ResultListIndex < ResultListLength; ResultListIndex++)
765  {
766  GrantedAccessList[ResultListIndex] = PreviouslyGrantedAccess;
767  AccessStatusList[ResultListIndex] = Status;
768  }
769 
770  /* Free the allocated access check rights */
771  SepFreeAccessCheckRights(AccessCheckRights);
772  AccessCheckRights = NULL;
773 
774  return NT_SUCCESS(Status);
775 }
#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_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
_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
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
_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:1552
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:1772
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
_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:1103
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:1552
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:164
#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 843 of file accesschk.c.

845 {
846  if (PrivilegeSet == NULL)
847  return 0;
848 
849  if (PrivilegeSet->PrivilegeCount == 0)
850  return (ULONG)(sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES));
851 
852  return (ULONG)(sizeof(PRIVILEGE_SET) +
853  (PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES));
854 }
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 816 of file accesschk.c.

818 {
819  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
820  PSID Group;
821 
822  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
823  Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
825  else
826  Group = (PSID)SecurityDescriptor->Group;
827 
828  return Group;
829 }
#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:1605
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 789 of file accesschk.c.

791 {
792  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
793  PSID Owner;
794 
795  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
796  Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
798  else
800 
801  return Owner;
802 }
#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:1556
#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:164
#define PAGED_CODE()

Referenced by SepAnalyzeAcesFromDacl().