ReactOS  0.4.15-dev-3316-g067ca88
priv.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for priv.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define SE_MAXIMUM_PRIVILEGE_LIMIT   0x3C
 
#define CONST_LUID(x1, x2)   {x1, x2}
 

Functions

VOID NTAPI SepInitPrivileges (VOID)
 Initializes the privileges during the startup phase of the security manager module. This function serves as a placeholder as it currently does nothing. More...
 
BOOLEAN NTAPI SepPrivilegeCheck (_In_ PTOKEN Token, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_ ULONG PrivilegeCount, _In_ ULONG PrivilegeControl, _In_ KPROCESSOR_MODE PreviousMode)
 Checks the privileges pointed by Privileges array argument if they exist and match with the privileges from an access token. More...
 
BOOLEAN NTAPI SepSinglePrivilegeCheck (_In_ LUID PrivilegeValue, _In_ PTOKEN Token, _In_ KPROCESSOR_MODE PreviousMode)
 Checks only single privilege based upon the privilege pointed by a LUID and if it matches with the one from an access token. More...
 
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 context. More...
 
BOOLEAN NTAPI SeCheckAuditPrivilege (_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
 Checks a single privilege and performs an audit against a privileged service based on a security subject context. More...
 
NTSTATUS NTAPI SeCaptureLuidAndAttributesArray (_In_ PLUID_AND_ATTRIBUTES Src, _In_ ULONG PrivilegeCount, _In_ KPROCESSOR_MODE PreviousMode, _In_opt_ PLUID_AND_ATTRIBUTES AllocatedMem, _In_opt_ ULONG AllocatedLength, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PLUID_AND_ATTRIBUTES *Dest, _Inout_ PULONG Length)
 Captures a LUID with attributes structure. This function is mainly tied in the context of privileges. More...
 
VOID NTAPI SeReleaseLuidAndAttributesArray (_In_ PLUID_AND_ATTRIBUTES Privilege, _In_ KPROCESSOR_MODE PreviousMode, _In_ BOOLEAN CaptureIfKernel)
 Releases a LUID with attributes structure. More...
 
NTSTATUS NTAPI SeAppendPrivileges (_Inout_ PACCESS_STATE AccessState, _In_ PPRIVILEGE_SET Privileges)
 Appends additional privileges. More...
 
VOID NTAPI SeFreePrivileges (_In_ PPRIVILEGE_SET Privileges)
 Frees a set of privileges. More...
 
BOOLEAN NTAPI SePrivilegeCheck (_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
 Checks if a set of privileges exist and match within a security subject context. More...
 
BOOLEAN NTAPI SeSinglePrivilegeCheck (_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
 Checks if a single privilege is present in the context of the calling thread. More...
 
BOOLEAN NTAPI SeCheckPrivilegedObject (_In_ LUID PrivilegeValue, _In_ HANDLE ObjectHandle, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE PreviousMode)
 Checks a privileged object if such object has the specific privilege submitted by the caller. More...
 
NTSTATUS NTAPI NtPrivilegeCheck (_In_ HANDLE ClientToken, _In_ PPRIVILEGE_SET RequiredPrivileges, _Out_ PBOOLEAN Result)
 Checks a client access token if it has the required set of privileges. More...
 

Variables

const LUID SeCreateTokenPrivilege = CONST_LUID(SE_CREATE_TOKEN_PRIVILEGE, 0)
 
const LUID SeAssignPrimaryTokenPrivilege = CONST_LUID(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 0)
 
const LUID SeLockMemoryPrivilege = CONST_LUID(SE_LOCK_MEMORY_PRIVILEGE, 0)
 
const LUID SeIncreaseQuotaPrivilege = CONST_LUID(SE_INCREASE_QUOTA_PRIVILEGE, 0)
 
const LUID SeUnsolicitedInputPrivilege = CONST_LUID(6, 0)
 
const LUID SeTcbPrivilege = CONST_LUID(SE_TCB_PRIVILEGE, 0)
 
const LUID SeSecurityPrivilege = CONST_LUID(SE_SECURITY_PRIVILEGE, 0)
 
const LUID SeTakeOwnershipPrivilege = CONST_LUID(SE_TAKE_OWNERSHIP_PRIVILEGE, 0)
 
const LUID SeLoadDriverPrivilege = CONST_LUID(SE_LOAD_DRIVER_PRIVILEGE, 0)
 
const LUID SeSystemProfilePrivilege = CONST_LUID(SE_SYSTEM_PROFILE_PRIVILEGE, 0)
 
const LUID SeSystemtimePrivilege = CONST_LUID(SE_SYSTEMTIME_PRIVILEGE, 0)
 
const LUID SeProfileSingleProcessPrivilege = CONST_LUID(SE_PROF_SINGLE_PROCESS_PRIVILEGE, 0)
 
const LUID SeIncreaseBasePriorityPrivilege = CONST_LUID(SE_INC_BASE_PRIORITY_PRIVILEGE, 0)
 
const LUID SeCreatePagefilePrivilege = CONST_LUID(SE_CREATE_PAGEFILE_PRIVILEGE, 0)
 
const LUID SeCreatePermanentPrivilege = CONST_LUID(SE_CREATE_PERMANENT_PRIVILEGE, 0)
 
const LUID SeBackupPrivilege = CONST_LUID(SE_BACKUP_PRIVILEGE, 0)
 
const LUID SeRestorePrivilege = CONST_LUID(SE_RESTORE_PRIVILEGE, 0)
 
const LUID SeShutdownPrivilege = CONST_LUID(SE_SHUTDOWN_PRIVILEGE, 0)
 
const LUID SeDebugPrivilege = CONST_LUID(SE_DEBUG_PRIVILEGE, 0)
 
const LUID SeAuditPrivilege = CONST_LUID(SE_AUDIT_PRIVILEGE, 0)
 
const LUID SeSystemEnvironmentPrivilege = CONST_LUID(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, 0)
 
const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0)
 
const LUID SeRemoteShutdownPrivilege = CONST_LUID(SE_REMOTE_SHUTDOWN_PRIVILEGE, 0)
 
const LUID SeUndockPrivilege = CONST_LUID(SE_UNDOCK_PRIVILEGE, 0)
 
const LUID SeSyncAgentPrivilege = CONST_LUID(SE_SYNC_AGENT_PRIVILEGE, 0)
 
const LUID SeEnableDelegationPrivilege = CONST_LUID(SE_ENABLE_DELEGATION_PRIVILEGE, 0)
 
const LUID SeManageVolumePrivilege = CONST_LUID(SE_MANAGE_VOLUME_PRIVILEGE, 0)
 
const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0)
 
const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0)
 
const LUID SeTrustedCredmanPrivilege = CONST_LUID(SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE, 0)
 
const LUID SeRelabelPrivilege = CONST_LUID(SE_RELABEL_PRIVILEGE, 0)
 
const LUID SeIncreaseWorkingSetPrivilege = CONST_LUID(SE_INC_WORKING_SET_PRIVILEGE, 0)
 
const LUID SeTimeZonePrivilege = CONST_LUID(SE_TIME_ZONE_PRIVILEGE, 0)
 
const LUID SeCreateSymbolicLinkPrivilege = CONST_LUID(SE_CREATE_SYMBOLIC_LINK_PRIVILEGE, 0)
 

Macro Definition Documentation

◆ CONST_LUID

#define CONST_LUID (   x1,
  x2 
)    {x1, x2}

Definition at line 20 of file priv.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file priv.c.

◆ SE_MAXIMUM_PRIVILEGE_LIMIT

#define SE_MAXIMUM_PRIVILEGE_LIMIT   0x3C

Definition at line 18 of file priv.c.

Function Documentation

◆ NtPrivilegeCheck()

NTSTATUS NTAPI NtPrivilegeCheck ( _In_ HANDLE  ClientToken,
_In_ PPRIVILEGE_SET  RequiredPrivileges,
_Out_ PBOOLEAN  Result 
)

Checks a client access token if it has the required set of privileges.

Parameters
[in]ClientTokenA handle to an access client token.
[in]RequiredPrivilegesA set of required privileges to be checked against the privileges of the access token.
[out]ResultThe result, as a boolean value. If TRUE, the token has all the required privileges, FALSE otherwise.
Returns
Returns STATUS_SUCCESS if the function has completed successfully. STATUS_INVALID_PARAMETER is returned if the set array of required privileges has a bogus number of privileges, that is, the array has a count of privileges that exceeds the maximum threshold (or in other words, an integer overflow). A failure NTSTATUS code is returned otherwise.

Definition at line 868 of file priv.c.

872 {
874  PTOKEN Token;
875  ULONG PrivilegeCount = 0;
876  ULONG PrivilegeControl = 0;
877  ULONG Length;
878  BOOLEAN CheckResult;
881 
882  PAGED_CODE();
883 
885 
886  /* probe the buffers */
887  if (PreviousMode != KernelMode)
888  {
889  _SEH2_TRY
890  {
891  ProbeForWrite(RequiredPrivileges,
893  Privilege),
894  sizeof(ULONG));
895 
896  PrivilegeCount = RequiredPrivileges->PrivilegeCount;
897  PrivilegeControl = RequiredPrivileges->Control;
898 
899  /* Check PrivilegeCount to avoid an integer overflow! */
901  Privilege[PrivilegeCount]) /
902  sizeof(RequiredPrivileges->Privilege[0]) != PrivilegeCount)
903  {
905  }
906 
907  /* probe all of the array */
908  ProbeForWrite(RequiredPrivileges,
910  Privilege[PrivilegeCount]),
911  sizeof(ULONG));
912 
914  }
916  {
917  /* Return the exception code */
919  }
920  _SEH2_END;
921  }
922  else
923  {
924  PrivilegeCount = RequiredPrivileges->PrivilegeCount;
925  PrivilegeControl = RequiredPrivileges->Control;
926  }
927 
928  /* reference the token and make sure we're
929  not doing an anonymous impersonation */
930  Status = ObReferenceObjectByHandle(ClientToken,
931  TOKEN_QUERY,
933  PreviousMode,
934  (PVOID*)&Token,
935  NULL);
936  if (!NT_SUCCESS(Status))
937  {
938  return Status;
939  }
940 
941  if (Token->TokenType == TokenImpersonation &&
942  Token->ImpersonationLevel < SecurityIdentification)
943  {
946  }
947 
948  /* capture the privileges */
949  Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege,
950  PrivilegeCount,
951  PreviousMode,
952  NULL,
953  0,
954  PagedPool,
955  TRUE,
956  &Privileges,
957  &Length);
958  if (!NT_SUCCESS(Status))
959  {
961  return Status;
962  }
963 
964  CheckResult = SepPrivilegeCheck(Token,
965  Privileges,
966  PrivilegeCount,
967  PrivilegeControl,
968  PreviousMode);
969 
971 
972  /* return the array */
973  _SEH2_TRY
974  {
975  RtlCopyMemory(RequiredPrivileges->Privilege,
976  Privileges,
977  PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
978  *Result = CheckResult;
980  }
982  {
984  }
985  _SEH2_END;
986 
988  PreviousMode,
989  TRUE);
990 
991  return Status;
992 }
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define KeGetPreviousMode()
Definition: ketypes.h:1107
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
NTSTATUS NTAPI SeCaptureLuidAndAttributesArray(_In_ PLUID_AND_ATTRIBUTES Src, _In_ ULONG PrivilegeCount, _In_ KPROCESSOR_MODE PreviousMode, _In_opt_ PLUID_AND_ATTRIBUTES AllocatedMem, _In_opt_ ULONG AllocatedLength, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PLUID_AND_ATTRIBUTES *Dest, _Inout_ PULONG Length)
Captures a LUID with attributes structure. This function is mainly tied in the context of privileges.
Definition: priv.c:438
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4226
VOID NTAPI SeReleaseLuidAndAttributesArray(_In_ PLUID_AND_ATTRIBUTES Privilege, _In_ KPROCESSOR_MODE PreviousMode, _In_ BOOLEAN CaptureIfKernel)
Releases a LUID with attributes structure.
Definition: priv.c:554
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
unsigned char BOOLEAN
BOOLEAN NTAPI SepPrivilegeCheck(_In_ PTOKEN Token, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_ ULONG PrivilegeCount, _In_ ULONG PrivilegeControl, _In_ KPROCESSOR_MODE PreviousMode)
Checks the privileges pointed by Privileges array argument if they exist and match with the privilege...
Definition: priv.c:104
POBJECT_TYPE SeTokenObjectType
Definition: token.c:19
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TOKEN_QUERY
Definition: setypes.h:893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ProbeForWriteBoolean(Ptr)
Definition: probe.h:31
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
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
_SEH2_END
Definition: create.c:4400
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
#define PAGED_CODE()

Referenced by PrivilegeCheck().

◆ SeAppendPrivileges()

NTSTATUS NTAPI SeAppendPrivileges ( _Inout_ PACCESS_STATE  AccessState,
_In_ PPRIVILEGE_SET  Privileges 
)

Appends additional privileges.

Parameters
[in]AccessStateAccess request to append.
[in]PrivilegesSet of new privileges to append.
Returns
Returns STATUS_SUCCESS if the privileges have been successfully appended. Otherwise STATUS_INSUFFICIENT_RESOURCES is returned, indicating that pool allocation has failed for the buffer to hold the new set of privileges.

Definition at line 588 of file priv.c.

591 {
592  PAUX_ACCESS_DATA AuxData;
593  ULONG OldPrivilegeSetSize;
594  ULONG NewPrivilegeSetSize;
595  PPRIVILEGE_SET PrivilegeSet;
596 
597  PAGED_CODE();
598 
599  /* Get the Auxiliary Data */
600  AuxData = AccessState->AuxData;
601 
602  /* Calculate the size of the old privilege set */
603  OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) +
604  (AuxData->PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
605 
606  if (AuxData->PrivilegeSet->PrivilegeCount +
607  Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT)
608  {
609  /* Calculate the size of the new privilege set */
610  NewPrivilegeSetSize = OldPrivilegeSetSize +
611  Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
612 
613  /* Allocate a new privilege set */
614  PrivilegeSet = ExAllocatePoolWithTag(PagedPool,
615  NewPrivilegeSetSize,
617  if (PrivilegeSet == NULL)
619 
620  /* Copy original privileges from the acess state */
621  RtlCopyMemory(PrivilegeSet,
622  AuxData->PrivilegeSet,
623  OldPrivilegeSetSize);
624 
625  /* Append privileges from the privilege set*/
626  RtlCopyMemory((PVOID)((ULONG_PTR)PrivilegeSet + OldPrivilegeSetSize),
628  Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
629 
630  /* Adjust the number of privileges in the new privilege set */
631  PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
632 
633  /* Free the old privilege set if it was allocated */
634  if (AccessState->PrivilegesAllocated != FALSE)
636 
637  /* Now we are using an allocated privilege set */
638  AccessState->PrivilegesAllocated = TRUE;
639 
640  /* Assign the new privileges to the access state */
641  AuxData->PrivilegeSet = PrivilegeSet;
642  }
643  else
644  {
645  /* Append privileges */
646  RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet + OldPrivilegeSetSize),
648  Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
649 
650  /* Adjust the number of privileges in the target privilege set */
651  AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
652  }
653 
654  return STATUS_SUCCESS;
655 }
PPRIVILEGE_SET PrivilegeSet
Definition: setypes.h:234
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _PRIVILEGE_SET PRIVILEGE_SET
#define TRUE
Definition: types.h:120
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NULL
Definition: types.h:112
#define INITIAL_PRIVILEGE_COUNT
Definition: setypes.h:159
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define TAG_PRIVILEGE_SET
Definition: tag.h:180
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by IopCheckBackupRestorePrivilege(), IopParseDevice(), NpCreateClientEnd(), NpCreateExistingNamedPipe(), ObCheckCreateObjectAccess(), ObCheckObjectAccess(), ObpCheckTraverseAccess(), and START_TEST().

◆ SeCaptureLuidAndAttributesArray()

NTSTATUS NTAPI SeCaptureLuidAndAttributesArray ( _In_ PLUID_AND_ATTRIBUTES  Src,
_In_ ULONG  PrivilegeCount,
_In_ KPROCESSOR_MODE  PreviousMode,
_In_opt_ PLUID_AND_ATTRIBUTES  AllocatedMem,
_In_opt_ ULONG  AllocatedLength,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PLUID_AND_ATTRIBUTES Dest,
_Inout_ PULONG  Length 
)

Captures a LUID with attributes structure. This function is mainly tied in the context of privileges.

Parameters
[in]SrcSource of a valid LUID with attributes structure.
[in]PrivilegeCountCount number of privileges to be captured.
[in]PreviousModeProcessor level access mode.
[in]AllocatedMemIf specified, the function will use this allocated block memory buffer for the captured LUID and attributes structure. Otherwise the function will automatically allocate some buffer for it.
[in]AllocatedLengthThe length of the buffer, pointed by AllocatedMem.
[in]PoolTypePool type of the memory allocation.
[in]CaptureIfKernelIf set to TRUE, the capturing is done in the kernel itself. FALSE if the capturing is done in a kernel mode driver instead.
[out]DestThe captured LUID with attributes buffer.
[in,out]LengthThe length of the captured privileges count.
Returns
Returns STATUS_SUCCESS if the LUID and attributes array has been captured successfully. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the captured buffer has failed. STATUS_BUFFER_TOO_SMALL is returned if the buffer size is less than the required size. STATUS_INVALID_PARAMETER is returned if the caller has submitted a privilege count that exceeds that maximum threshold the kernel can permit, for the purpose to avoid an integer overflow.

Definition at line 438 of file priv.c.

448 {
451 
452  PAGED_CODE();
453 
454  if (PrivilegeCount == 0)
455  {
456  *Dest = 0;
457  *Length = 0;
458  return STATUS_SUCCESS;
459  }
460 
461  if (PrivilegeCount > SE_MAXIMUM_PRIVILEGE_LIMIT)
462  {
464  }
465 
466  if (PreviousMode == KernelMode && !CaptureIfKernel)
467  {
468  *Dest = Src;
469  return STATUS_SUCCESS;
470  }
471 
472  BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
473  *Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */
474 
475  /* probe the buffer */
476  if (PreviousMode != KernelMode)
477  {
478  _SEH2_TRY
479  {
480  ProbeForRead(Src,
481  BufferSize,
482  sizeof(ULONG));
483  }
485  {
486  /* Return the exception code */
488  }
489  _SEH2_END;
490  }
491 
492  /* allocate enough memory or check if the provided buffer is
493  large enough to hold the array */
494  if (AllocatedMem != NULL)
495  {
496  if (AllocatedLength < BufferSize)
497  {
499  }
500 
501  *Dest = AllocatedMem;
502  }
503  else
504  {
506  BufferSize,
507  TAG_LUID);
508  if (*Dest == NULL)
509  {
511  }
512  }
513 
514  /* copy the array to the buffer */
515  _SEH2_TRY
516  {
517  RtlCopyMemory(*Dest,
518  Src,
519  BufferSize);
520  }
522  {
524  }
525  _SEH2_END;
526 
527  if (!NT_SUCCESS(Status) && AllocatedMem == NULL)
528  {
529  ExFreePoolWithTag(*Dest, TAG_LUID);
530  }
531 
532  return Status;
533 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TAG_LUID
Definition: tag.h:178
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_SEH2_END
Definition: create.c:4400
#define SE_MAXIMUM_PRIVILEGE_LIMIT
Definition: priv.c:18
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
#define PAGED_CODE()

Referenced by NtPrivilegeCheck().

◆ SeCheckAuditPrivilege()

BOOLEAN NTAPI SeCheckAuditPrivilege ( _In_ PSECURITY_SUBJECT_CONTEXT  SubjectContext,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks a single privilege and performs an audit against a privileged service based on a security subject context.

Parameters
[in]DesiredAccessSecurity subject context used for privileged service auditing.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if service auditing and privilege checking tests have succeeded, FALSE otherwise.

Definition at line 360 of file priv.c.

363 {
364  PRIVILEGE_SET PrivilegeSet;
365  BOOLEAN Result;
366  PAGED_CODE();
367 
368  /* Initialize the privilege set with the single privilege */
369  PrivilegeSet.PrivilegeCount = 1;
370  PrivilegeSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
371  PrivilegeSet.Privilege[0].Luid = SeAuditPrivilege;
372  PrivilegeSet.Privilege[0].Attributes = 0;
373 
374  /* Check against the primary token! */
375  Result = SepPrivilegeCheck(SubjectContext->PrimaryToken,
376  &PrivilegeSet.Privilege[0],
377  1,
379  PreviousMode);
380 
381  if (PreviousMode != KernelMode)
382  {
385  &PrivilegeSet,
386  Result);
387  }
388 
389  return Result;
390 }
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
const LUID SeAuditPrivilege
Definition: priv.c:40
$ULONG Control
Definition: setypes.h:87
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
unsigned char BOOLEAN
BOOLEAN NTAPI SepPrivilegeCheck(_In_ PTOKEN Token, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_ ULONG PrivilegeCount, _In_ ULONG PrivilegeControl, _In_ KPROCESSOR_MODE PreviousMode)
Checks the privileges pointed by Privileges array argument if they exist and match with the privilege...
Definition: priv.c:104
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
VOID NTAPI SePrivilegedServiceAuditAlarm(_In_opt_ PUNICODE_STRING ServiceName, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PPRIVILEGE_SET PrivilegeSet, _In_ BOOLEAN AccessGranted)
Performs an audit alarm to a privileged service request.
Definition: audit.c:369
#define NULL
Definition: types.h:112
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
#define PAGED_CODE()

Referenced by NtCloseObjectAuditAlarm(), NtOpenObjectAuditAlarm(), NtPrivilegedServiceAuditAlarm(), and SepAccessCheckAndAuditAlarm().

◆ SeCheckPrivilegedObject()

BOOLEAN NTAPI SeCheckPrivilegedObject ( _In_ LUID  PrivilegeValue,
_In_ HANDLE  ObjectHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks a privileged object if such object has the specific privilege submitted by the caller.

Parameters
[in]PrivilegeValueA privilege to be checked against the one from the object.
[in]ObjectHandleA handle to any kind of object.
[in]DesiredAccessDesired access right mask requested by the caller.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if the privilege is present, FALSE otherwise.

Definition at line 803 of file priv.c.

808 {
810  PRIVILEGE_SET Priv;
811  BOOLEAN Result;
812 
813  PAGED_CODE();
814 
816 
817  Priv.PrivilegeCount = 1;
819  Priv.Privilege[0].Luid = PrivilegeValue;
821 
823  if (PreviousMode != KernelMode)
824  {
825 #if 0
826  SePrivilegeObjectAuditAlarm(ObjectHandle,
829  &PrivilegeValue,
830  Result,
831  PreviousMode);
832 #endif
833  }
834 
836 
837  return Result;
838 }
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
$ULONG Control
Definition: setypes.h:87
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: access.c:434
VOID NTAPI SePrivilegeObjectAuditAlarm(_In_ HANDLE Handle, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE CurrentMode)
Raises an audit with alarm notification message when an object tries to acquire this privilege.
Definition: audit.c:1422
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: access.c:520
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
#define PAGED_CODE()

Referenced by NtSetInformationProcess(), and NtSetInformationThread().

◆ SeFreePrivileges()

VOID NTAPI SeFreePrivileges ( _In_ PPRIVILEGE_SET  Privileges)

Frees a set of privileges.

Parameters
[in]PrivilegesSet of privileges array to be freed.
Returns
Nothing.

Definition at line 669 of file priv.c.

671 {
672  PAGED_CODE();
674 }
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define TAG_PRIVILEGE_SET
Definition: tag.h:180
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by IopParseDevice(), NpCreateClientEnd(), NpCreateExistingNamedPipe(), NtAccessCheck(), ObCheckCreateObjectAccess(), ObCheckObjectAccess(), ObpCheckTraverseAccess(), and START_TEST().

◆ SepInitPrivileges()

VOID NTAPI SepInitPrivileges ( VOID  )

Initializes the privileges during the startup phase of the security manager module. This function serves as a placeholder as it currently does nothing.

Returns
Nothing.

Definition at line 71 of file priv.c.

72 {
73 
74 }

Referenced by SepInitializationPhase0().

◆ SepPrivilegeCheck()

BOOLEAN NTAPI SepPrivilegeCheck ( _In_ PTOKEN  Token,
_In_ PLUID_AND_ATTRIBUTES  Privileges,
_In_ ULONG  PrivilegeCount,
_In_ ULONG  PrivilegeControl,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks the privileges pointed by Privileges array argument if they exist and match with the privileges from an access token.

Parameters
[in]TokenAn access token where privileges are to be checked.
[in]PrivilegesAn array of privileges with attributes used as checking indicator for the function.
[in]PrivilegeCountThe total number count of privileges in the array.
[in]PrivilegeControlPrivilege control bit mask to determine if we should check all the privileges based on the number count of privileges or not.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if the required privileges exist and that they do match. Otherwise the functions returns FALSE.

Definition at line 104 of file priv.c.

110 {
111  ULONG i;
112  ULONG j;
113  ULONG Required;
114 
115  DPRINT("SepPrivilegeCheck() called\n");
116 
117  PAGED_CODE();
118 
119  if (PreviousMode == KernelMode)
120  return TRUE;
121 
122  /* Get the number of privileges that are required to match */
123  Required = (PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) ? PrivilegeCount : 1;
124 
125  /* Acquire a shared token lock */
127 
128  /* Loop all requested privileges until we found the required ones */
129  for (i = 0; i < PrivilegeCount; i++)
130  {
131  /* Loop the privileges of the token */
132  for (j = 0; j < Token->PrivilegeCount; j++)
133  {
134  /* Check if the LUIDs match */
135  if (RtlEqualLuid(&Token->Privileges[j].Luid, &Privileges[i].Luid))
136  {
137  DPRINT("Found privilege. Attributes: %lx\n",
138  Token->Privileges[j].Attributes);
139 
140  /* Check if the privilege is enabled */
141  if (Token->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED)
142  {
144  Required--;
145 
146  /* Check if we have found all privileges */
147  if (Required == 0)
148  {
149  /* We're done! */
151  return TRUE;
152  }
153  }
154 
155  /* Leave the inner loop */
156  break;
157  }
158  }
159  }
160 
161  /* Release the token lock */
163 
164  /* When we reached this point, we did not find all privileges */
165  ASSERT(Required > 0);
166  return FALSE;
167 }
#define TRUE
Definition: types.h:120
_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
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define FALSE
Definition: types.h:117
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
#define SE_PRIVILEGE_USED_FOR_ACCESS
Definition: setypes.h:65
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define ASSERT(a)
Definition: mode.c:44
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define SepReleaseTokenLock(Token)
Definition: se.h:231
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SepAcquireTokenLockShared(Token)
Definition: se.h:225
unsigned int ULONG
Definition: retypes.h:1
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:38
#define DPRINT
Definition: sndvol32.h:71
#define PAGED_CODE()

Referenced by NtPrivilegeCheck(), SeCheckAuditPrivilege(), SePrivilegeCheck(), and SepSinglePrivilegeCheck().

◆ SePrivilegeCheck()

BOOLEAN NTAPI SePrivilegeCheck ( _In_ PPRIVILEGE_SET  Privileges,
_In_ PSECURITY_SUBJECT_CONTEXT  SubjectContext,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks if a set of privileges exist and match within a security subject context.

Parameters
[in]PrivilegesA set of privileges where the check must be performed against the subject context.
[in]SubjectContextA subject security context.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if all the privileges do exist and match with the ones specified by the caller and subject context, FALSE otherwise.

Definition at line 698 of file priv.c.

702 {
704 
705  PAGED_CODE();
706 
707  if (SubjectContext->ClientToken == NULL)
708  {
709  Token = SubjectContext->PrimaryToken;
710  }
711  else
712  {
713  Token = SubjectContext->ClientToken;
714  if (SubjectContext->ImpersonationLevel < 2)
715  {
716  return FALSE;
717  }
718  }
719 
720  return SepPrivilegeCheck(Token,
721  Privileges->Privilege,
722  Privileges->PrivilegeCount,
723  Privileges->Control,
724  PreviousMode);
725 }
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
_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
#define FALSE
Definition: types.h:117
BOOLEAN NTAPI SepPrivilegeCheck(_In_ PTOKEN Token, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_ ULONG PrivilegeCount, _In_ ULONG PrivilegeControl, _In_ KPROCESSOR_MODE PreviousMode)
Checks the privileges pointed by Privileges array argument if they exist and match with the privilege...
Definition: priv.c:104
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
#define NULL
Definition: types.h:112
#define PAGED_CODE()

Referenced by FatCheckManageVolumeAccess(), has_manage_volume_privilege(), HasPrivilege(), IopCheckBackupRestorePrivilege(), SeCheckPrivilegedObject(), SeSinglePrivilegeCheck(), and START_TEST().

◆ SePrivilegePolicyCheck()

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 context.

Parameters
[in,out]DesiredAccessThe desired access right mask.
[in,out]GrantedAccessThe granted access rights masks. The rights are granted depending on the desired access rights requested by the calling thread.
[in]SubjectContextSecurity subject context. If the caller supplies one, the access token supplied by the caller will be assigned to one of client or primary tokens of the subject context in question.
[in]TokenAn access token.
[out]OutPrivilegeSetAn array set of privileges to be reported to the caller, if the actual calling thread wants such set of privileges in the first place.
[in]PreviousModeProcessor level access mode.
Returns
Returns STATUS_PRIVILEGE_NOT_HELD if the respective operations have succeeded without problems. STATUS_PRIVILEGE_NOT_HELD is returned if the access token doesn't have SeSecurityPrivilege privilege to warrant ACCESS_SYSTEM_SECURITY access right. STATUS_INSUFFICIENT_RESOURCES is returned if we failed to allocate block of memory pool for the array set of privileges.

Definition at line 244 of file priv.c.

251 {
252  SIZE_T PrivilegeSize;
253  PPRIVILEGE_SET PrivilegeSet;
254  ULONG PrivilegeCount = 0, Index = 0;
256  PAGED_CODE();
257 
258  /* Check if we have a security subject context */
259  if (SubjectContext != NULL)
260  {
261  /* Check if there is a client impersonation token */
262  if (SubjectContext->ClientToken != NULL)
263  Token = SubjectContext->ClientToken;
264  else
265  Token = SubjectContext->PrimaryToken;
266  }
267 
268  /* Check if the caller wants ACCESS_SYSTEM_SECURITY access */
270  {
271  /* Do the privilege check */
273  {
274  /* Remember this access flag */
276  PrivilegeCount++;
277  }
278  else
279  {
281  }
282  }
283 
284  /* Check if the caller wants WRITE_OWNER access */
285  if (*DesiredAccess & WRITE_OWNER)
286  {
287  /* Do the privilege check */
289  {
290  /* Remember this access flag */
292  PrivilegeCount++;
293  }
294  }
295 
296  /* Update the access masks */
299 
300  /* Does the caller want a privilege set? */
301  if (OutPrivilegeSet != NULL)
302  {
303  /* Do we have any privileges to report? */
304  if (PrivilegeCount > 0)
305  {
306  /* Calculate size and allocate the structure */
307  PrivilegeSize = FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]);
308  PrivilegeSet = ExAllocatePoolWithTag(PagedPool, PrivilegeSize, TAG_PRIVILEGE_SET);
309  *OutPrivilegeSet = PrivilegeSet;
310  if (PrivilegeSet == NULL)
311  {
313  }
314 
315  PrivilegeSet->PrivilegeCount = PrivilegeCount;
316  PrivilegeSet->Control = 0;
317 
318  if (AccessMask & WRITE_OWNER)
319  {
320  PrivilegeSet->Privilege[Index].Luid = SeTakeOwnershipPrivilege;
322  Index++;
323  }
324 
326  {
327  PrivilegeSet->Privilege[Index].Luid = SeSecurityPrivilege;
329  }
330  }
331  else
332  {
333  /* No privileges, no structure */
334  *OutPrivilegeSet = NULL;
335  }
336  }
337 
338  return STATUS_SUCCESS;
339 }
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
_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 ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
_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
$ULONG Control
Definition: setypes.h:87
#define WRITE_OWNER
Definition: nt_native.h:60
#define SE_PRIVILEGE_USED_FOR_ACCESS
Definition: setypes.h:65
$ULONG PrivilegeCount
Definition: setypes.h:86
BOOLEAN NTAPI SepSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ PTOKEN Token, _In_ KPROCESSOR_MODE PreviousMode)
Checks only single privilege based upon the privilege pointed by a LUID and if it matches with the on...
Definition: priv.c:190
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
const LUID SeSecurityPrivilege
Definition: priv.c:27
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
unsigned int ULONG
Definition: retypes.h:1
#define TAG_PRIVILEGE_SET
Definition: tag.h:180
#define STATUS_SUCCESS
Definition: shellext.h:65
_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
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGED_CODE()

Referenced by NtAccessCheck(), and SepAccessCheck().

◆ SepSinglePrivilegeCheck()

BOOLEAN NTAPI SepSinglePrivilegeCheck ( _In_ LUID  PrivilegeValue,
_In_ PTOKEN  Token,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks only single privilege based upon the privilege pointed by a LUID and if it matches with the one from an access token.

Parameters
[in]PrivilegeValueThe privilege to be checked.
[in]TokenAn access token where its privilege is to be checked against the one provided by the caller.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if the required privilege exists and that it matches with the one from the access token, FALSE otherwise.

Definition at line 190 of file priv.c.

194 {
196  PAGED_CODE();
197  ASSERT(!RtlEqualLuid(&PrivilegeValue, &SeTcbPrivilege));
198 
199  Privilege.Luid = PrivilegeValue;
200  Privilege.Attributes = SE_PRIVILEGE_ENABLED;
201  return SepPrivilegeCheck(Token,
202  &Privilege,
203  1,
205  PreviousMode);
206 }
const LUID SeTcbPrivilege
Definition: priv.c: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
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
BOOLEAN NTAPI SepPrivilegeCheck(_In_ PTOKEN Token, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_ ULONG PrivilegeCount, _In_ ULONG PrivilegeControl, _In_ KPROCESSOR_MODE PreviousMode)
Checks the privileges pointed by Privileges array argument if they exist and match with the privilege...
Definition: priv.c:104
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define ASSERT(a)
Definition: mode.c:44
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
#define PAGED_CODE()

Referenced by SePrivilegePolicyCheck().

◆ SeReleaseLuidAndAttributesArray()

VOID NTAPI SeReleaseLuidAndAttributesArray ( _In_ PLUID_AND_ATTRIBUTES  Privilege,
_In_ KPROCESSOR_MODE  PreviousMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases a LUID with attributes structure.

Parameters
[in]PrivilegeArray of a LUID and attributes that represents a privilege.
[in]PreviousModeProcessor level access mode.
[in]CaptureIfKernelIf set to TRUE, the releasing is done in the kernel itself. FALSE if the releasing is done in a kernel mode driver instead.
Returns
Nothing.

Definition at line 554 of file priv.c.

558 {
559  PAGED_CODE();
560 
561  if (Privilege != NULL &&
562  (PreviousMode != KernelMode || CaptureIfKernel))
563  {
565  }
566 }
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TAG_LUID
Definition: tag.h:178
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
#define NULL
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by NtAdjustPrivilegesToken(), NtCreateToken(), and NtPrivilegeCheck().

◆ SeSinglePrivilegeCheck()

BOOLEAN NTAPI SeSinglePrivilegeCheck ( _In_ LUID  PrivilegeValue,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Checks if a single privilege is present in the context of the calling thread.

Parameters
[in]PrivilegeValueThe specific privilege to be checked.
[in]PreviousModeProcessor level access mode.
Returns
Returns TRUE if the privilege is present, FALSE otherwise.

Definition at line 744 of file priv.c.

747 {
749  PRIVILEGE_SET Priv;
750  BOOLEAN Result;
751 
752  PAGED_CODE();
753 
755 
756  Priv.PrivilegeCount = 1;
758  Priv.Privilege[0].Luid = PrivilegeValue;
760 
761  Result = SePrivilegeCheck(&Priv,
763  PreviousMode);
764 
765  if (PreviousMode != KernelMode)
766  {
769  &Priv,
770  Result);
771 
772  }
773 
775 
776  return Result;
777 }
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
$ULONG Control
Definition: setypes.h:87
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
$ULONG PrivilegeCount
Definition: setypes.h:86
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
VOID NTAPI SePrivilegedServiceAuditAlarm(_In_opt_ PUNICODE_STRING ServiceName, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PPRIVILEGE_SET PrivilegeSet, _In_ BOOLEAN AccessGranted)
Performs an audit alarm to a privileged service request.
Definition: audit.c:369
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: access.c:434
#define NULL
Definition: types.h:112
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: access.c:520
BOOLEAN NTAPI SePrivilegeCheck(_In_ PPRIVILEGE_SET Privileges, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a set of privileges exist and match within a security subject context.
Definition: priv.c:698
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
#define PAGED_CODE()

Referenced by add_device(), ApphelpCacheAccessCheck(), ExpRaiseHardError(), Ext2InvalidateVolumes(), FatCheckSystemSecurityAccess(), find_subvol(), fsctl_set_xattr(), invalidate_volumes(), ioctl_unload(), IopUnloadDriver(), KsInstallBusEnumInterface(), KsRemoveBusEnumInterface(), mknod(), NtAllocateVirtualMemory(), NtCreatePagingFile(), NtCreateProfile(), NtCreateToken(), NtDisplayString(), NtGetPlugPlayEvent(), NtLoadDriver(), NtLoadKeyEx(), NtLockVirtualMemory(), NtMakePermanentObject(), NtOpenProcess(), NtOpenThread(), NtPlugPlayControl(), NtQuerySystemEnvironmentValue(), NtSaveKeyEx(), NtSaveMergedKeys(), NtSetDebugFilterState(), NtSetDefaultHardErrorPort(), NtSetInformationObject(), NtSetInformationProcess(), NtSetInformationThread(), NtSetInformationToken(), NtSetSystemEnvironmentValue(), NtSetSystemPowerState(), NtSetSystemTime(), NtUnloadKey2(), NtUnlockVirtualMemory(), ObCreateObject(), ObpLookupObjectName(), pause_balance(), pause_scrub(), probe_volume(), PspSetPrimaryToken(), PspSetQuotaLimits(), query_scrub(), read_send_buffer(), recvd_subvol(), remove_device(), reserve_subvol(), reset_stats(), resize_device(), resume_balance(), resume_scrub(), send_subvol(), SSI_DEF(), start_balance(), start_scrub(), stop_balance(), stop_scrub(), UDFCheckAccessRights(), UDFCommonCreate(), and UDFInvalidateVolumes().

Variable Documentation

◆ SeAssignPrimaryTokenPrivilege

const LUID SeAssignPrimaryTokenPrivilege = CONST_LUID(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 0)

Definition at line 22 of file priv.c.

Referenced by PspSetPrimaryToken(), SepCreateSystemProcessToken(), and SepInitExports().

◆ SeAuditPrivilege

const LUID SeAuditPrivilege = CONST_LUID(SE_AUDIT_PRIVILEGE, 0)

Definition at line 40 of file priv.c.

Referenced by SeCheckAuditPrivilege(), SepCreateSystemProcessToken(), and SepInitExports().

◆ SeBackupPrivilege

◆ SeChangeNotifyPrivilege

const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0)

Definition at line 42 of file priv.c.

◆ SeCreateGlobalPrivilege

const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0)

Definition at line 49 of file priv.c.

◆ SeCreatePagefilePrivilege

const LUID SeCreatePagefilePrivilege = CONST_LUID(SE_CREATE_PAGEFILE_PRIVILEGE, 0)

Definition at line 34 of file priv.c.

Referenced by NtCreatePagingFile(), SepCreateSystemProcessToken(), and SepInitExports().

◆ SeCreatePermanentPrivilege

const LUID SeCreatePermanentPrivilege = CONST_LUID(SE_CREATE_PERMANENT_PRIVILEGE, 0)

◆ SeCreateSymbolicLinkPrivilege

const LUID SeCreateSymbolicLinkPrivilege = CONST_LUID(SE_CREATE_SYMBOLIC_LINK_PRIVILEGE, 0)

Definition at line 54 of file priv.c.

◆ SeCreateTokenPrivilege

const LUID SeCreateTokenPrivilege = CONST_LUID(SE_CREATE_TOKEN_PRIVILEGE, 0)

Definition at line 21 of file priv.c.

Referenced by NtCreateToken(), SepCreateSystemProcessToken(), and SepInitExports().

◆ SeDebugPrivilege

◆ SeEnableDelegationPrivilege

const LUID SeEnableDelegationPrivilege = CONST_LUID(SE_ENABLE_DELEGATION_PRIVILEGE, 0)

Definition at line 46 of file priv.c.

Referenced by SepInitExports().

◆ SeImpersonatePrivilege

const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0)

Definition at line 48 of file priv.c.

◆ SeIncreaseBasePriorityPrivilege

◆ SeIncreaseQuotaPrivilege

const LUID SeIncreaseQuotaPrivilege = CONST_LUID(SE_INCREASE_QUOTA_PRIVILEGE, 0)

Definition at line 24 of file priv.c.

Referenced by PspSetQuotaLimits(), SepCreateSystemProcessToken(), and SepInitExports().

◆ SeIncreaseWorkingSetPrivilege

const LUID SeIncreaseWorkingSetPrivilege = CONST_LUID(SE_INC_WORKING_SET_PRIVILEGE, 0)

Definition at line 52 of file priv.c.

◆ SeLoadDriverPrivilege

const LUID SeLoadDriverPrivilege = CONST_LUID(SE_LOAD_DRIVER_PRIVILEGE, 0)

◆ SeLockMemoryPrivilege

◆ SeManageVolumePrivilege

const LUID SeManageVolumePrivilege = CONST_LUID(SE_MANAGE_VOLUME_PRIVILEGE, 0)

Definition at line 47 of file priv.c.

Referenced by SepInitExports().

◆ SeProfileSingleProcessPrivilege

const LUID SeProfileSingleProcessPrivilege = CONST_LUID(SE_PROF_SINGLE_PROCESS_PRIVILEGE, 0)

Definition at line 32 of file priv.c.

Referenced by SepCreateSystemProcessToken(), and SepInitExports().

◆ SeRelabelPrivilege

const LUID SeRelabelPrivilege = CONST_LUID(SE_RELABEL_PRIVILEGE, 0)

Definition at line 51 of file priv.c.

◆ SeRemoteShutdownPrivilege

const LUID SeRemoteShutdownPrivilege = CONST_LUID(SE_REMOTE_SHUTDOWN_PRIVILEGE, 0)

Definition at line 43 of file priv.c.

Referenced by SepInitExports().

◆ SeRestorePrivilege

◆ SeSecurityPrivilege

const LUID SeSecurityPrivilege = CONST_LUID(SE_SECURITY_PRIVILEGE, 0)

Definition at line 27 of file priv.c.

Referenced by SepCreateSystemProcessToken(), SepInitExports(), and SePrivilegePolicyCheck().

◆ SeShutdownPrivilege

◆ SeSyncAgentPrivilege

const LUID SeSyncAgentPrivilege = CONST_LUID(SE_SYNC_AGENT_PRIVILEGE, 0)

Definition at line 45 of file priv.c.

Referenced by SepInitExports().

◆ SeSystemEnvironmentPrivilege

◆ SeSystemProfilePrivilege

const LUID SeSystemProfilePrivilege = CONST_LUID(SE_SYSTEM_PROFILE_PRIVILEGE, 0)

Definition at line 30 of file priv.c.

Referenced by NtCreateProfile(), and SepInitExports().

◆ SeSystemtimePrivilege

const LUID SeSystemtimePrivilege = CONST_LUID(SE_SYSTEMTIME_PRIVILEGE, 0)

Definition at line 31 of file priv.c.

Referenced by NtSetSystemTime(), SepCreateSystemProcessToken(), SepInitExports(), and SSI_DEF().

◆ SeTakeOwnershipPrivilege

const LUID SeTakeOwnershipPrivilege = CONST_LUID(SE_TAKE_OWNERSHIP_PRIVILEGE, 0)

Definition at line 28 of file priv.c.

Referenced by SepCreateSystemProcessToken(), SepInitExports(), and SePrivilegePolicyCheck().

◆ SeTcbPrivilege

◆ SeTimeZonePrivilege

const LUID SeTimeZonePrivilege = CONST_LUID(SE_TIME_ZONE_PRIVILEGE, 0)

Definition at line 53 of file priv.c.

◆ SeTrustedCredmanPrivilege

const LUID SeTrustedCredmanPrivilege = CONST_LUID(SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE, 0)

Definition at line 50 of file priv.c.

◆ SeUndockPrivilege

const LUID SeUndockPrivilege = CONST_LUID(SE_UNDOCK_PRIVILEGE, 0)

Definition at line 44 of file priv.c.

Referenced by SepInitExports().

◆ SeUnsolicitedInputPrivilege

const LUID SeUnsolicitedInputPrivilege = CONST_LUID(6, 0)

Definition at line 25 of file priv.c.

Referenced by SepInitExports().