ReactOS 0.4.15-dev-7788-g1ad9096
se.h File Reference

Go to the source code of this file.

Classes

struct  _KNOWN_ACE
 
struct  _KNOWN_OBJECT_ACE
 
struct  _KNOWN_COMPOUND_ACE
 
struct  _ACCESS_CHECK_RIGHTS
 
struct  _OBJECT_TYPE_LIST_INTERNAL
 
struct  _TOKEN_AUDIT_POLICY_INFORMATION
 

Macros

#define TOKEN_CREATE_METHOD   0xCUL
 
#define TOKEN_DUPLICATE_METHOD   0xDUL
 
#define TOKEN_FILTER_METHOD   0xFUL
 
#define SepAcquireTokenLockExclusive(Token)
 
#define SepAcquireTokenLockShared(Token)
 
#define SepReleaseTokenLock(Token)
 

Typedefs

typedef struct _KNOWN_ACE KNOWN_ACE
 
typedef struct _KNOWN_ACEPKNOWN_ACE
 
typedef struct _KNOWN_OBJECT_ACE KNOWN_OBJECT_ACE
 
typedef struct _KNOWN_OBJECT_ACEPKNOWN_OBJECT_ACE
 
typedef struct _KNOWN_COMPOUND_ACE KNOWN_COMPOUND_ACE
 
typedef struct _KNOWN_COMPOUND_ACEPKNOWN_COMPOUND_ACE
 
typedef struct _ACCESS_CHECK_RIGHTS ACCESS_CHECK_RIGHTS
 
typedef struct _ACCESS_CHECK_RIGHTSPACCESS_CHECK_RIGHTS
 
typedef struct _OBJECT_TYPE_LIST_INTERNAL OBJECT_TYPE_LIST_INTERNAL
 
typedef struct _OBJECT_TYPE_LIST_INTERNALPOBJECT_TYPE_LIST_INTERNAL
 
typedef enum _ACCESS_CHECK_RIGHT_TYPE ACCESS_CHECK_RIGHT_TYPE
 
typedef struct _TOKEN_AUDIT_POLICY_INFORMATION TOKEN_AUDIT_POLICY_INFORMATION
 
typedef struct _TOKEN_AUDIT_POLICY_INFORMATIONPTOKEN_AUDIT_POLICY_INFORMATION
 

Enumerations

enum  _ACCESS_CHECK_RIGHT_TYPE { AccessCheckMaximum , AccessCheckRegular }
 

Functions

FORCEINLINE PSID SepGetGroupFromDescriptor (_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
 
FORCEINLINE PSID SepGetOwnerFromDescriptor (_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
 
FORCEINLINE PACL SepGetDaclFromDescriptor (_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
 
FORCEINLINE PACL SepGetSaclFromDescriptor (_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
 
VOID NTAPI SepInitializeTokenImplementation (VOID)
 Internal function that initializes critical kernel data for access token implementation in SRM.
 
PTOKEN NTAPI SepCreateSystemProcessToken (VOID)
 Creates the system process token.
 
PTOKEN SepCreateSystemAnonymousLogonToken (VOID)
 Creates the anonymous logon token for the system. The difference between this token and the other one is the inclusion of everyone SID group (being SeWorldSid). The other token lacks such group.
 
PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone (VOID)
 Creates the anonymous logon token for the system. This kind of token doesn't include the everyone SID group (being SeWorldSid).
 
NTSTATUS NTAPI SepDuplicateToken (_In_ PTOKEN Token, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PTOKEN *NewAccessToken)
 Duplicates an access token, from an existing valid token.
 
NTSTATUS NTAPI SepCreateToken (_Out_ PHANDLE TokenHandle, _In_ KPROCESSOR_MODE PreviousMode, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PSID_AND_ATTRIBUTES User, _In_ ULONG GroupCount, _In_ PSID_AND_ATTRIBUTES Groups, _In_ ULONG GroupsLength, _In_ ULONG PrivilegeCount, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_opt_ PSID Owner, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl, _In_ PTOKEN_SOURCE TokenSource, _In_ BOOLEAN SystemToken)
 Internal function responsible for access token object creation in the kernel. A fully created token objected is inserted into the token handle, thus the handle becoming a valid handle to an access token object and ready for use.
 
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.
 
NTSTATUS SepCreateTokenLock (_Inout_ PTOKEN Token)
 Creates a lock for the token.
 
VOID SepDeleteTokenLock (_Inout_ PTOKEN Token)
 Deletes a lock of a token.
 
VOID SepUpdatePrivilegeFlagsToken (_Inout_ PTOKEN Token)
 Updates the token's flags based upon the privilege that the token has been granted. The function uses the private helper, SepUpdateSinglePrivilegeFlagToken, in order to update the flags of a token.
 
NTSTATUS SepFindPrimaryGroupAndDefaultOwner (_In_ PTOKEN Token, _In_ PSID PrimaryGroup, _In_opt_ PSID DefaultOwner, _Out_opt_ PULONG PrimaryGroupIndex, _Out_opt_ PULONG DefaultOwnerIndex)
 Finds the primary group and default owner entity based on the submitted primary group instance and an access token.
 
VOID SepUpdateSinglePrivilegeFlagToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Updates the token's flags based upon the privilege that the token has been granted. The flag can either be taken out or given to the token if the attributes of the specified privilege is enabled or not.
 
VOID SepRemovePrivilegeToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Removes a privilege from the token.
 
VOID SepRemoveUserGroupToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Removes a group from the token.
 
ULONG SepComputeAvailableDynamicSpace (_In_ ULONG DynamicCharged, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl)
 Computes the exact available dynamic area of an access token whilst querying token statistics.
 
NTSTATUS SepRebuildDynamicPartOfToken (_In_ PTOKEN Token, _In_ ULONG NewDynamicPartSize)
 
BOOLEAN NTAPI SeTokenCanImpersonate (_In_ PTOKEN ProcessToken, _In_ PTOKEN TokenToImpersonate, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 Determines whether the server is allowed to impersonate on behalf of a client or not. For further details, see Remarks.
 
VOID NTAPI SeGetTokenControlInformation (_In_ PACCESS_TOKEN _Token, _Out_ PTOKEN_CONTROL TokenControl)
 Retrieves token control information.
 
VOID NTAPI SeDeassignPrimaryToken (_Inout_ PEPROCESS Process)
 Removes the primary token of a process.
 
NTSTATUS NTAPI SeSubProcessToken (_In_ PTOKEN Parent, _Out_ PTOKEN *Token, _In_ BOOLEAN InUse, _In_ ULONG SessionId)
 Subtracts a token in exchange of duplicating a new one.
 
NTSTATUS NTAPI SeIsTokenChild (_In_ PTOKEN Token, _Out_ PBOOLEAN IsChild)
 Checks if the token is a child of the other token of the current process that the calling thread is invoking this function.
 
NTSTATUS NTAPI SeIsTokenSibling (_In_ PTOKEN Token, _Out_ PBOOLEAN IsSibling)
 Checks if the token is a sibling of the other token of the current process that the calling thread is invoking this function.
 
NTSTATUS NTAPI SeExchangePrimaryToken (_In_ PEPROCESS Process, _In_ PACCESS_TOKEN NewAccessToken, _Out_ PACCESS_TOKEN *OldAccessToken)
 Replaces the old access token of a process (pointed by the EPROCESS kernel structure) with a new access token. The new access token must be a primary token for use.
 
NTSTATUS NTAPI SeCopyClientToken (_In_ PACCESS_TOKEN Token, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PACCESS_TOKEN *NewToken)
 Copies an existing access token (technically duplicating a new one).
 
BOOLEAN NTAPI SeTokenIsInert (_In_ PTOKEN Token)
 Determines if a token is a sandbox inert token or not, based upon the token flags.
 
ULONG RtlLengthSidAndAttributes (_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
 Computes the length size of a SID.
 
BOOLEAN NTAPI SeInitSystem (VOID)
 Main security manager initialization function.
 
NTSTATUS NTAPI SeDefaultObjectMethod (_In_ PVOID Object, _In_ SECURITY_OPERATION_CODE OperationType, _In_ PSECURITY_INFORMATION SecurityInformation, _Inout_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_opt_ PULONG ReturnLength, _Inout_opt_ PSECURITY_DESCRIPTOR *OldSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping)
 
VOID NTAPI SeQuerySecurityAccessMask (_In_ SECURITY_INFORMATION SecurityInformation, _Out_ PACCESS_MASK DesiredAccess)
 Queries the access mask from a security information context.
 
VOID NTAPI SeSetSecurityAccessMask (_In_ SECURITY_INFORMATION SecurityInformation, _Out_ PACCESS_MASK DesiredAccess)
 Sets the access mask for a security information context.
 
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.
 
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.
 
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.
 
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.
 
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.
 
NTSTATUS NTAPI SeCaptureLuidAndAttributesArray (_In_ PLUID_AND_ATTRIBUTES Src, _In_ ULONG PrivilegeCount, _In_ KPROCESSOR_MODE PreviousMode, _In_ PLUID_AND_ATTRIBUTES AllocatedMem, _In_ ULONG AllocatedLength, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PLUID_AND_ATTRIBUTES *Dest, _Inout_ PULONG Length)
 
VOID NTAPI SeReleaseLuidAndAttributesArray (_In_ PLUID_AND_ATTRIBUTES Privilege, _In_ KPROCESSOR_MODE PreviousMode, _In_ BOOLEAN CaptureIfKernel)
 Releases a LUID with attributes structure.
 
BOOLEAN NTAPI SepInitSecurityIDs (VOID)
 Initializes all the SIDs known in the system.
 
NTSTATUS NTAPI SepCaptureSid (_In_ PSID InputSid, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSID *CapturedSid)
 Captures a SID.
 
VOID NTAPI SepReleaseSid (_In_ PSID CapturedSid, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
 Releases a captured SID.
 
BOOLEAN NTAPI SepSidInToken (_In_ PACCESS_TOKEN _Token, _In_ PSID Sid)
 Checks if a SID is present in a token.
 
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.
 
PSID NTAPI SepGetSidFromAce (_In_ PACE Ace)
 Captures a security identifier from a given access control entry. This identifier is valid for the whole of its lifetime.
 
NTSTATUS NTAPI SeCaptureSidAndAttributesArray (_In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes, _In_ ULONG AttributeCount, _In_ KPROCESSOR_MODE PreviousMode, _In_opt_ PVOID AllocatedMem, _In_ ULONG AllocatedLength, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSID_AND_ATTRIBUTES *CapturedSidAndAttributes, _Out_ PULONG ResultLength)
 Captures a SID with attributes.
 
VOID NTAPI SeReleaseSidAndAttributesArray (_In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
 Releases a captured SID with attributes.
 
BOOLEAN NTAPI SepInitDACLs (VOID)
 Initializes known discretionary access control lists in the system upon kernel and Executive initialization procedure.
 
NTSTATUS NTAPI SepCreateImpersonationTokenDacl (_In_ PTOKEN Token, _In_ PTOKEN PrimaryToken, _Out_ PACL *Dacl)
 Allocates a discretionary access control list based on certain properties of a regular and primary access tokens.
 
NTSTATUS NTAPI SepCaptureAcl (_In_ PACL InputAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PACL *CapturedAcl)
 Captures an access control list from an already valid input ACL.
 
VOID NTAPI SepReleaseAcl (_In_ PACL CapturedAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
 Releases (frees) a captured ACL from the memory pool.
 
NTSTATUS SepPropagateAcl (_Out_writes_bytes_opt_(DaclLength) PACL AclDest, _Inout_ PULONG AclLength, _In_reads_bytes_(AclSource->AclSize) PACL AclSource, _In_ PSID Owner, _In_ PSID Group, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
 
PACL SepSelectAcl (_In_opt_ PACL ExplicitAcl, _In_ BOOLEAN ExplicitPresent, _In_ BOOLEAN ExplicitDefaulted, _In_opt_ PACL ParentAcl, _In_opt_ PACL DefaultAcl, _Out_ PULONG AclLength, _In_ PSID Owner, _In_ PSID Group, _Out_ PBOOLEAN AclPresent, _Out_ PBOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
 Selects an ACL and returns it to the caller.
 
BOOLEAN NTAPI SepInitSDs (VOID)
 Initializes the known security descriptors in the system.
 
NTSTATUS NTAPI SeSetWorldSecurityDescriptor (_In_ SECURITY_INFORMATION SecurityInformation, _In_ PISECURITY_DESCRIPTOR SecurityDescriptor, _In_ PULONG BufferLength)
 Sets a "World" security descriptor.
 
NTSTATUS NTAPI SeComputeQuotaInformationSize (_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PULONG QuotaInfoSize)
 
BOOLEAN NTAPI SeRmInitPhase0 (VOID)
 Manages the phase 0 initialization of the security reference monitoring module of the kernel.
 
BOOLEAN NTAPI SeRmInitPhase1 (VOID)
 Manages the phase 1 initialization of the security reference monitoring module of the kernel.
 
NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken (_Inout_ PTOKEN Token)
 Inserts a logon session into an access token specified by the caller.
 
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken (_Inout_ PTOKEN Token)
 Removes a logon session from an access token.
 
NTSTATUS SepRmReferenceLogonSession (_Inout_ PLUID LogonLuid)
 
NTSTATUS SepRmDereferenceLogonSession (_Inout_ PLUID LogonLuid)
 
NTSTATUS NTAPI SepRegQueryHelper (_In_ PCWSTR KeyName, _In_ PCWSTR ValueName, _In_ ULONG ValueType, _In_ ULONG DataLength, _Out_ PVOID ValueData)
 A private registry helper that returns the desired value data based on the specifics requested by the caller.
 
NTSTATUS NTAPI SeGetLogonIdDeviceMap (_In_ PLUID LogonId, _Out_ PDEVICE_MAP *DeviceMap)
 Retrieves the DOS device map from a logon session.
 
NTSTATUS NTAPI SeInitializeProcessAuditName (_In_ PFILE_OBJECT FileObject, _In_ BOOLEAN DoAudit, _Out_ POBJECT_NAME_INFORMATION *AuditInfo)
 Initializes a process audit name and returns it to the caller.
 
BOOLEAN NTAPI SeDetailedAuditingWithToken (_In_ PTOKEN Token)
 Peforms a detailed security auditing with an access token.
 
VOID NTAPI SeAuditProcessExit (_In_ PEPROCESS Process)
 Peforms a security auditing against a process that is about to be terminated.
 
VOID NTAPI SeAuditProcessCreate (_In_ PEPROCESS Process)
 Peforms a security auditing against a process that is about to be created.
 
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.
 
VOID NTAPI SeCaptureSubjectContextEx (_In_ PETHREAD Thread, _In_ PEPROCESS Process, _Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
 An extended function that captures the security subject context based upon the specified thread and process.
 
NTSTATUS NTAPI SepCaptureSecurityQualityOfService (_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService, _Out_ PBOOLEAN Present)
 Captures the security quality of service data given the object attributes from an object.
 
VOID NTAPI SepReleaseSecurityQualityOfService (_In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
 Releases (frees) the captured SQOS data from an object in the memory pool.
 
PGUID SepGetObjectTypeGuidFromAce (_In_ PACE Ace, _In_ BOOLEAN IsAceDenied)
 Captures an object type GUID from an object access control entry (ACE).
 
BOOLEAN SepObjectTypeGuidInList (_In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST_INTERNAL ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ PGUID ObjectTypeGuid, _Out_ PULONG ObjectIndex)
 Searches for an object type GUID if it exists on an object type list.
 
NTSTATUS SeCaptureObjectTypeList (_In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ KPROCESSOR_MODE PreviousMode, _Out_ POBJECT_TYPE_LIST_INTERNAL *CapturedObjectTypeList)
 Captures a list of object types and converts it to an internal form for use by the kernel. The list is validated before its data is copied.
 
VOID SeReleaseObjectTypeList (_In_ _Post_invalid_ POBJECT_TYPE_LIST_INTERNAL CapturedObjectTypeList, _In_ KPROCESSOR_MODE PreviousMode)
 Releases a buffer list of object types.
 
NTSTATUS NTAPI SeCreateAccessStateEx (_In_ PETHREAD Thread, _In_ PEPROCESS Process, _In_ OUT PACCESS_STATE AccessState, _In_ PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
 
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.
 

Variables

SID_IDENTIFIER_AUTHORITY SeNullSidAuthority
 
SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority
 
SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority
 
SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority
 
SID_IDENTIFIER_AUTHORITY SeNtSidAuthority
 
PSID SeNullSid
 
PSID SeWorldSid
 
PSID SeLocalSid
 
PSID SeCreatorOwnerSid
 
PSID SeCreatorGroupSid
 
PSID SeCreatorOwnerServerSid
 
PSID SeCreatorGroupServerSid
 
PSID SeNtAuthoritySid
 
PSID SeDialupSid
 
PSID SeNetworkSid
 
PSID SeBatchSid
 
PSID SeInteractiveSid
 
PSID SeServiceSid
 
PSID SeAnonymousLogonSid
 
PSID SePrincipalSelfSid
 
PSID SeLocalSystemSid
 
PSID SeAuthenticatedUserSid
 
PSID SeRestrictedCodeSid
 
PSID SeAliasAdminsSid
 
PSID SeAliasUsersSid
 
PSID SeAliasGuestsSid
 
PSID SeAliasPowerUsersSid
 
PSID SeAliasAccountOpsSid
 
PSID SeAliasSystemOpsSid
 
PSID SeAliasPrintOpsSid
 
PSID SeAliasBackupOpsSid
 
PSID SeAuthenticatedUsersSid
 
PSID SeRestrictedSid
 
PSID SeLocalServiceSid
 
PSID SeNetworkServiceSid
 
const LUID SeCreateTokenPrivilege
 
const LUID SeAssignPrimaryTokenPrivilege
 
const LUID SeLockMemoryPrivilege
 
const LUID SeIncreaseQuotaPrivilege
 
const LUID SeUnsolicitedInputPrivilege
 
const LUID SeTcbPrivilege
 
const LUID SeSecurityPrivilege
 
const LUID SeTakeOwnershipPrivilege
 
const LUID SeLoadDriverPrivilege
 
const LUID SeSystemProfilePrivilege
 
const LUID SeSystemtimePrivilege
 
const LUID SeProfileSingleProcessPrivilege
 
const LUID SeIncreaseBasePriorityPrivilege
 
const LUID SeCreatePagefilePrivilege
 
const LUID SeCreatePermanentPrivilege
 
const LUID SeBackupPrivilege
 
const LUID SeRestorePrivilege
 
const LUID SeShutdownPrivilege
 
const LUID SeDebugPrivilege
 
const LUID SeAuditPrivilege
 
const LUID SeSystemEnvironmentPrivilege
 
const LUID SeChangeNotifyPrivilege
 
const LUID SeRemoteShutdownPrivilege
 
const LUID SeUndockPrivilege
 
const LUID SeSyncAgentPrivilege
 
const LUID SeEnableDelegationPrivilege
 
const LUID SeManageVolumePrivilege
 
const LUID SeImpersonatePrivilege
 
const LUID SeCreateGlobalPrivilege
 
const LUID SeTrustedCredmanPrivilege
 
const LUID SeRelabelPrivilege
 
const LUID SeIncreaseWorkingSetPrivilege
 
const LUID SeTimeZonePrivilege
 
const LUID SeCreateSymbolicLinkPrivilege
 
PACL SePublicDefaultUnrestrictedDacl
 
PACL SePublicOpenDacl
 
PACL SePublicOpenUnrestrictedDacl
 
PACL SeUnrestrictedDacl
 
PACL SeSystemAnonymousLogonDacl
 
PSECURITY_DESCRIPTOR SePublicDefaultSd
 
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
 
PSECURITY_DESCRIPTOR SePublicOpenSd
 
PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
 
PSECURITY_DESCRIPTOR SeSystemDefaultSd
 
PSECURITY_DESCRIPTOR SeUnrestrictedSd
 
PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd
 
PTOKEN SeAnonymousLogonToken
 
PTOKEN SeAnonymousLogonTokenNoEveryone
 

Macro Definition Documentation

◆ SepAcquireTokenLockExclusive

#define SepAcquireTokenLockExclusive (   Token)
Value:
{ \
KeEnterCriticalRegion(); \
ExAcquireResourceExclusiveLite(((PTOKEN)Token)->TokenLock, TRUE); \
}
#define TRUE
Definition: types.h:120

Definition at line 285 of file se.h.

◆ SepAcquireTokenLockShared

#define SepAcquireTokenLockShared (   Token)
Value:
{ \
KeEnterCriticalRegion(); \
ExAcquireResourceSharedLite(((PTOKEN)Token)->TokenLock, TRUE); \
}

Definition at line 290 of file se.h.

◆ SepReleaseTokenLock

#define SepReleaseTokenLock (   Token)
Value:
{ \
ExReleaseResourceLite(((PTOKEN)Token)->TokenLock); \
KeLeaveCriticalRegion(); \
}

Definition at line 296 of file se.h.

◆ TOKEN_CREATE_METHOD

#define TOKEN_CREATE_METHOD   0xCUL

Definition at line 80 of file se.h.

◆ TOKEN_DUPLICATE_METHOD

#define TOKEN_DUPLICATE_METHOD   0xDUL

Definition at line 81 of file se.h.

◆ TOKEN_FILTER_METHOD

#define TOKEN_FILTER_METHOD   0xFUL

Definition at line 82 of file se.h.

Typedef Documentation

◆ ACCESS_CHECK_RIGHT_TYPE

◆ ACCESS_CHECK_RIGHTS

◆ KNOWN_ACE

◆ KNOWN_COMPOUND_ACE

◆ KNOWN_OBJECT_ACE

◆ OBJECT_TYPE_LIST_INTERNAL

◆ PACCESS_CHECK_RIGHTS

◆ PKNOWN_ACE

◆ PKNOWN_COMPOUND_ACE

◆ PKNOWN_OBJECT_ACE

◆ POBJECT_TYPE_LIST_INTERNAL

◆ PTOKEN_AUDIT_POLICY_INFORMATION

◆ TOKEN_AUDIT_POLICY_INFORMATION

Enumeration Type Documentation

◆ _ACCESS_CHECK_RIGHT_TYPE

Enumerator
AccessCheckMaximum 
AccessCheckRegular 

Definition at line 58 of file se.h.

59{
@ AccessCheckMaximum
Definition: se.h:60
@ AccessCheckRegular
Definition: se.h:61
enum _ACCESS_CHECK_RIGHT_TYPE ACCESS_CHECK_RIGHT_TYPE

Function Documentation

◆ RtlLengthSidAndAttributes()

ULONG RtlLengthSidAndAttributes ( _In_ ULONG  Count,
_In_ PSID_AND_ATTRIBUTES  Src 
)

Computes the length size of a SID.

Parameters
[in]CountTotal count of entries that have SIDs in them (that being PSID_AND_ATTRIBUTES in this context).
[in]SrcSource that points to the attributes and SID entry structure.
Returns
Returns the total length of a SID size.

Definition at line 965 of file token.c.

968{
969 ULONG i;
970 ULONG uLength;
971
972 PAGED_CODE();
973
974 uLength = Count * sizeof(SID_AND_ATTRIBUTES);
975 for (i = 0; i < Count; i++)
976 uLength += RtlLengthSid(Src[i].Sid);
977
978 return uLength;
979}
#define PAGED_CODE()
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
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
int Count
Definition: noreturn.cpp:7
uint32_t ULONG
Definition: typedefs.h:59
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES

Referenced by NtQueryInformationToken(), SepPerformTokenFiltering(), and SeQueryInformationToken().

◆ SeAuditProcessCreate()

VOID NTAPI SeAuditProcessCreate ( _In_ PEPROCESS  Process)

Peforms a security auditing against a process that is about to be created.

@unimplemented

Parameters
[in]ProcessAn object that points to a process which is in process of creation.
Returns
Nothing.

Definition at line 56 of file audit.c.

58{
59 /* FIXME */
60}

Referenced by PspCreateProcess().

◆ SeAuditProcessExit()

VOID NTAPI SeAuditProcessExit ( _In_ PEPROCESS  Process)

Peforms a security auditing against a process that is about to be terminated.

@unimplemented

Parameters
[in]ProcessAn object that points to a process which is in process of termination.
Returns
Nothing.

Definition at line 77 of file audit.c.

79{
80 /* FIXME */
81}

Referenced by PspExitThread().

◆ SeCaptureLuidAndAttributesArray()

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

◆ SeCaptureObjectTypeList()

NTSTATUS SeCaptureObjectTypeList ( _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST  ObjectTypeList,
_In_ ULONG  ObjectTypeListLength,
_In_ KPROCESSOR_MODE  PreviousMode,
_Out_ POBJECT_TYPE_LIST_INTERNAL CapturedObjectTypeList 
)

Captures a list of object types and converts it to an internal form for use by the kernel. The list is validated before its data is copied.

Parameters
[in]ObjectTypeListA pointer to a list of object types passed from UM to be captured.
[in]ObjectTypeListLengthThe length size of the list. This length represents the number of object elements in that list.
[in]PreviousModeProcessor access level mode. This has to be set to UserMode as object type access check is not supported in the kernel.
[out]CapturedObjectTypeListA pointer to a returned captured list of object types.
Returns
Returns STATUS_SUCCESS if the list of object types has been captured successfully. STATUS_INVALID_PARAMETER is returned if the caller hasn't supplied a buffer list of object types or the list is invalid. STATUS_INSUFFICIENT_RESOURCES is returned if pool memory allocation for the captured list has failed.

Definition at line 282 of file objtype.c.

287{
289 ULONG ObjectTypeIndex;
290 SIZE_T Size;
291 PGUID ObjectTypeGuid;
292 POBJECT_TYPE_LIST_INTERNAL InternalTypeList;
293
294 PAGED_CODE();
295
296 /* We do not support that in the kernel */
298 {
300 }
301
302 /* No count elements of objects means no captured list for you */
303 if (ObjectTypeListLength == 0)
304 {
305 *CapturedObjectTypeList = NULL;
306 return STATUS_SUCCESS;
307 }
308
309 /* Check if the caller supplied a list since we have the count of elements */
310 if (ObjectTypeList == NULL)
311 {
312 DPRINT1("The caller did not provide a list of object types!\n");
314 }
315
316 /* Validate that list before we copy contents from it */
317 Status = SepValidateObjectTypeList(ObjectTypeList, ObjectTypeListLength);
318 if (!NT_SUCCESS(Status))
319 {
320 DPRINT1("SepValidateObjectTypeList failed (Status 0x%08lx)\n", Status);
321 return Status;
322 }
323
324 /* Allocate a new list */
325 Size = ObjectTypeListLength * sizeof(OBJECT_TYPE_LIST_INTERNAL);
326 InternalTypeList = ExAllocatePoolWithTag(PagedPool, Size, TAG_SEPA);
327 if (InternalTypeList == NULL)
328 {
329 DPRINT1("Failed to allocate pool memory for the object type list!\n");
331 }
332
334 {
335 /* Loop for every object element, data was already probed */
336 for (ObjectTypeIndex = 0;
337 ObjectTypeIndex < ObjectTypeListLength;
338 ObjectTypeIndex++)
339 {
340 /* Copy the object type GUID */
341 ObjectTypeGuid = ObjectTypeList[ObjectTypeIndex].ObjectType;
342 InternalTypeList[ObjectTypeIndex].ObjectTypeGuid = *ObjectTypeGuid;
343
344 /* Copy the object hierarchy level */
345 InternalTypeList[ObjectTypeIndex].Level = ObjectTypeList[ObjectTypeIndex].Level;
346
347 /* Initialize the access check rights */
348 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.RemainingAccessRights = 0;
349 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.GrantedAccessRights = 0;
350 InternalTypeList[ObjectTypeIndex].ObjectAccessRights.DeniedAccessRights = 0;
351 }
352
353 /* Give the captured list to caller */
354 *CapturedObjectTypeList = InternalTypeList;
355 }
357 {
358 ExFreePoolWithTag(InternalTypeList, TAG_SEPA);
359 InternalTypeList = NULL;
361 }
362 _SEH2_END;
363
364 return STATUS_SUCCESS;
365}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
struct _OBJECT_TYPE_LIST_INTERNAL OBJECT_TYPE_LIST_INTERNAL
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
static NTSTATUS SepValidateObjectTypeList(_In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength)
Validates a list of object types passed from user mode, ensuring the following conditions are met for...
Definition: objtype.c:46
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TAG_SEPA
Definition: tag.h:156
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SeCaptureSidAndAttributesArray()

NTSTATUS NTAPI SeCaptureSidAndAttributesArray ( _In_ PSID_AND_ATTRIBUTES  SrcSidAndAttributes,
_In_ ULONG  AttributeCount,
_In_ KPROCESSOR_MODE  PreviousMode,
_In_opt_ PVOID  AllocatedMem,
_In_ ULONG  AllocatedLength,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes,
_Out_ PULONG  ResultLength 
)

Captures a SID with attributes.

Parameters
[in]SrcSidAndAttributesSource of the SID with attributes to be captured.
[in]AttributeCountThe number count of attributes, in total.
[in]PreviousModeProcessor access level mode.
[in]AllocatedMemThe allocated memory buffer for the captured SID. If the caller supplies no allocated block of memory then the function will allocate some buffer block of memory for the captured SID automatically.
[in]AllocatedLengthThe length of the buffer that points to the allocated memory, in bytes.
[in]PoolTypeThe pool type for the captured SID and attributes to assign.
[in]CaptureIfKernelIf set to TRUE, the capturing is done within the kernel. Otherwise the capturing is done in a kernel mode driver.
[out]CapturedSidAndAttributesThe captured SID and attributes.
[out]ResultLengthThe length of the captured SID and attributes, in bytes.
Returns
Returns STATUS_SUCCESS if SID and attributes capturing has been completed successfully. STATUS_INVALID_PARAMETER is returned if the count of attributes exceeds the maximum threshold that the kernel can permit, with the purpose of avoiding integer overflows. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the captured SID has failed. STATUS_BUFFER_TOO_SMALL is returned if the length of the allocated buffer is less than the required size. STATUS_INVALID_SID is returned if a SID doesn't meet certain requirements to be considered a valid SID by the security manager. A failure NTSTATUS code is returned otherwise.
Remarks
A security identifier (SID) is a variable-length data structure that can change in size over time, depending on the factors that influence this effect in question. An attacker can take advantage of this fact and can potentially modify certain properties of a SID making it different in size than it was originally before. This is what we'd call, a TOCTOU vulnerability.

For this reason, the logic of copying the SIDs and their attributes into a new buffer goes like this: first, allocate a buffer array that just holds the lengths and subauthority count of each SID. Such information is copied in the first loop. Then in a second loop, iterate over the array with SID provided and copy them into the final array. The moment we're doing this, validate the lengths of each SID basing upon the captured lengths we've got before. In this way we ensure that the SIDs have remained intact. The validation checks are done in user mode as a general rule that we just cannot trust UM and whatever data is coming from it.

Definition at line 693 of file sid.c.

703{
704 ULONG ArraySize, RequiredLength, SidLength, i;
705 ULONG TempArrayValidate, TempLengthValidate;
706 PSID_AND_ATTRIBUTES SidAndAttributes;
707 _SEH2_VOLATILE PSID_VALIDATE ValidateArray;
708 PUCHAR CurrentDest;
709 PISID Sid;
711 PAGED_CODE();
712
713 ValidateArray = NULL;
714 SidAndAttributes = NULL;
715 *CapturedSidAndAttributes = NULL;
716 *ResultLength = 0;
717
718 if (AttributeCount == 0)
719 {
720 return STATUS_SUCCESS;
721 }
722
723 if (AttributeCount > SE_MAXIMUM_GROUP_LIMIT)
724 {
725 DPRINT1("SeCaptureSidAndAttributesArray(): Maximum group limit exceeded!\n");
727 }
728
729 if ((PreviousMode == KernelMode) && !CaptureIfKernel)
730 {
731 *CapturedSidAndAttributes = SrcSidAndAttributes;
732 return STATUS_SUCCESS;
733 }
734
735 ArraySize = AttributeCount * sizeof(SID_AND_ATTRIBUTES);
736 RequiredLength = ALIGN_UP_BY(ArraySize, sizeof(ULONG));
737
739 {
740 /* Check for user mode data */
742 {
743 /* First probe the whole array */
744 ProbeForRead(SrcSidAndAttributes, ArraySize, sizeof(ULONG));
745
746 /* We're in user mode, set up the size for the temporary array */
747 TempArrayValidate = AttributeCount * sizeof(SID_VALIDATE);
748 TempLengthValidate = ALIGN_UP_BY(TempArrayValidate, sizeof(ULONG));
749
750 /*
751 * Allocate a buffer for the array that we're going to
752 * temporarily hold the subauthority count and the SID
753 * elements. We'll be going to use this array to perform
754 * validation checks later.
755 */
757 TempLengthValidate,
759
760 /* Loop the array elements */
761 for (i = 0; i < AttributeCount; i++)
762 {
763 /* Get the SID and probe the minimal structure */
764 Sid = SrcSidAndAttributes[i].Sid;
765 ProbeForRead(Sid, sizeof(*Sid), sizeof(ULONG));
766
767 /*
768 * Capture the subauthority count and hold it
769 * into the temporary array for later validation.
770 * This way we ensure that the said count of each
771 * SID has remained the same.
772 */
773 ValidateArray[i].SubAuthorityCount = Sid->SubAuthorityCount;
774
775 /* Capture the SID */
776 ValidateArray[i].ProbeSid = Sid;
777
778 /* Calculate the SID length and probe the full SID */
779 SidLength = RtlLengthRequiredSid(ValidateArray[i].SubAuthorityCount);
780 ProbeForRead(ValidateArray[i].ProbeSid, SidLength, sizeof(ULONG));
781
782 /* Add the aligned length to the required length */
783 RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG));
784 }
785 }
787 {
789 _SEH2_YIELD(goto Cleanup);
790 }
791 _SEH2_END;
792 }
793 else
794 {
795 /* Loop the array elements */
796 for (i = 0; i < AttributeCount; i++)
797 {
798 /* Get the SID and it's length */
799 Sid = SrcSidAndAttributes[i].Sid;
801
802 /* Add the aligned length to the required length */
803 RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG));
804 }
805 }
806
807 /* Assume success */
810
811 /* Check if we have no buffer */
812 if (AllocatedMem == NULL)
813 {
814 /* Allocate a new buffer */
815 SidAndAttributes = ExAllocatePoolWithTag(PoolType,
818 if (SidAndAttributes == NULL)
819 {
820 DPRINT1("SeCaptureSidAndAttributesArray(): Failed to allocate memory for SID and attributes array (requested size -> %lu)!\n", RequiredLength);
822 goto Cleanup;
823 }
824 }
825 /* Otherwise check if the buffer is large enough */
826 else if (AllocatedLength >= RequiredLength)
827 {
828 /* Buffer is large enough, use it */
829 SidAndAttributes = AllocatedMem;
830 }
831 else
832 {
833 /* Buffer is too small, fail */
834 DPRINT1("SeCaptureSidAndAttributesArray(): The provided buffer is small (expected size -> %lu || current size -> %lu)!\n", RequiredLength, AllocatedLength);
836 goto Cleanup;
837 }
838
839 *CapturedSidAndAttributes = SidAndAttributes;
840
841 /* Check again for user mode */
843 {
845 {
846 /* The rest of the data starts after the array */
847 CurrentDest = (PUCHAR)SidAndAttributes;
848 CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG));
849
850 /* Loop the array elements */
851 for (i = 0; i < AttributeCount; i++)
852 {
853 /*
854 * Get the SID length from the subauthority
855 * count we've captured before.
856 */
857 SidLength = RtlLengthRequiredSid(ValidateArray[i].SubAuthorityCount);
858
859 /* Copy attributes */
860 SidAndAttributes[i].Attributes = SrcSidAndAttributes[i].Attributes;
861
862 /* Copy the SID to the current destination address */
863 SidAndAttributes[i].Sid = (PSID)CurrentDest;
864 RtlCopyMemory(CurrentDest, ValidateArray[i].ProbeSid, SidLength);
865
866 /* Obtain the SID we've captured before for validation */
867 Sid = SidAndAttributes[i].Sid;
868
869 /* Validate that the subauthority count hasn't changed */
870 if (ValidateArray[i].SubAuthorityCount !=
872 {
873 /* It's changed, bail out */
874 DPRINT1("SeCaptureSidAndAttributesArray(): The subauthority counts have changed (captured count -> %u || current count -> %u)\n",
875 ValidateArray[i].SubAuthorityCount, Sid->SubAuthorityCount);
877 goto Cleanup;
878 }
879
880 /* Validate that the SID length is the same */
881 if (SidLength != RtlLengthSid(Sid))
882 {
883 /* They're no longer the same, bail out */
884 DPRINT1("SeCaptureSidAndAttributesArray(): The SID lengths have changed (captured length -> %lu || current length -> %lu)\n",
885 SidLength, RtlLengthSid(Sid));
887 goto Cleanup;
888 }
889
890 /* Check that the SID is valid */
891 if (!RtlValidSid(Sid))
892 {
893 DPRINT1("SeCaptureSidAndAttributesArray(): The SID is not valid!\n");
895 goto Cleanup;
896 }
897
898 /* Update the current destination address */
899 CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG));
900 }
901 }
903 {
905 }
906 _SEH2_END;
907 }
908 else
909 {
910 /* The rest of the data starts after the array */
911 CurrentDest = (PUCHAR)SidAndAttributes;
912 CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG));
913
914 /* Loop the array elements */
915 for (i = 0; i < AttributeCount; i++)
916 {
917 /* Get the SID and it's length */
918 Sid = SrcSidAndAttributes[i].Sid;
920
921 /* Copy attributes */
922 SidAndAttributes[i].Attributes = SrcSidAndAttributes[i].Attributes;
923
924 /* Copy the SID to the current destination address */
925 SidAndAttributes[i].Sid = (PSID)CurrentDest;
926 RtlCopyMemory(CurrentDest, SrcSidAndAttributes[i].Sid, SidLength);
927
928 /* Update the current destination address */
929 CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG));
930 }
931 }
932
933Cleanup:
934 /* Check for failure */
935 if (!NT_SUCCESS(Status))
936 {
937 /* Check if we allocated a new array */
938 if ((SidAndAttributes != AllocatedMem) && (SidAndAttributes != NULL))
939 {
940 /* Free the array */
941 ExFreePoolWithTag(SidAndAttributes, TAG_SID_AND_ATTRIBUTES);
942 }
943
944 /* Set returned address to NULL */
945 *CapturedSidAndAttributes = NULL;
946 }
947
948 /* Free the temporary validation array */
949 if ((PreviousMode != KernelMode) && (ValidateArray != NULL))
950 {
951 ExFreePoolWithTag(ValidateArray, TAG_SID_VALIDATE);
952 }
953
954 return Status;
955}
#define ALIGN_UP_BY(size, align)
static const WCHAR Cleanup[]
Definition: register.c:80
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
struct _SID * PSID
Definition: eventlog.c:35
NTSYSAPI ULONG NTAPI RtlLengthRequiredSid(IN ULONG SubAuthorityCount)
Definition: sid.c:54
_In_ PSID_IDENTIFIER_AUTHORITY _In_ UCHAR SubAuthorityCount
Definition: rtlfuncs.h:1515
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
struct _SID_VALIDATE SID_VALIDATE
#define SE_MAXIMUM_GROUP_LIMIT
Definition: sid.c:16
#define STATUS_INVALID_SID
Definition: ntstatus.h:356
#define _SEH2_VOLATILE
Definition: pseh2_64.h:163
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200
#define TAG_SID_VALIDATE
Definition: tag.h:166
#define TAG_SID_AND_ATTRIBUTES
Definition: tag.h:165
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
#define POOL_RAISE_IF_ALLOCATION_FAILURE

Referenced by NtAdjustGroupsToken(), NtCreateToken(), and NtFilterToken().

◆ SeCaptureSubjectContextEx()

VOID NTAPI SeCaptureSubjectContextEx ( _In_ PETHREAD  Thread,
_In_ PEPROCESS  Process,
_Out_ PSECURITY_SUBJECT_CONTEXT  SubjectContext 
)

An extended function that captures the security subject context based upon the specified thread and process.

Parameters
[in]ThreadA thread where the calling thread's token is to be referenced for the security context.
[in]ProcessA process where the main process' token is to be referenced for the security context.
[out]SubjectContextThe returned security subject context.
Returns
Nothing.

Definition at line 41 of file subject.c.

45{
47
48 PAGED_CODE();
49
50 /* Save the unique ID */
51 SubjectContext->ProcessAuditId = Process->UniqueProcessId;
52
53 /* Check if we have a thread */
54 if (!Thread)
55 {
56 /* We don't, so no token */
57 SubjectContext->ClientToken = NULL;
58 }
59 else
60 {
61 /* Get the impersonation token */
65 &SubjectContext->ImpersonationLevel);
66 }
67
68 /* Get the primary token */
70}
unsigned char BOOLEAN
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_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:2246
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:410
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
PACCESS_TOKEN NTAPI PsReferenceImpersonationToken(IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:871
_Out_ PBOOLEAN CopyOnOpen
Definition: psfuncs.h:154

Referenced by SeCaptureSubjectContext(), and SeCreateAccessStateEx().

◆ 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;
366 PAGED_CODE();
367
368 /* Initialize the privilege set with the single privilege */
369 PrivilegeSet.PrivilegeCount = 1;
371 PrivilegeSet.Privilege[0].Luid = SeAuditPrivilege;
372 PrivilegeSet.Privilege[0].Attributes = 0;
373
374 /* Check against the primary token! */
376 &PrivilegeSet.Privilege[0],
377 1,
380
382 {
385 &PrivilegeSet,
386 Result);
387 }
388
389 return Result;
390}
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
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
const LUID SeAuditPrivilege
Definition: priv.c:40
LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]
Definition: setypes.h:88
$ULONG Control
Definition: setypes.h:87
$ULONG PrivilegeCount
Definition: setypes.h:86
_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:409
#define PRIVILEGE_SET_ALL_NECESSARY
Definition: setypes.h:83

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;
812
813 PAGED_CODE();
814
816
817 Priv.PrivilegeCount = 1;
819 Priv.Privilege[0].Luid = PrivilegeValue;
821
824 {
825#if 0
826 SePrivilegeObjectAuditAlarm(ObjectHandle,
829 &PrivilegeValue,
830 Result,
832#endif
833 }
834
836
837 return Result;
838}
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:1321
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
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63

Referenced by NtSetInformationProcess(), and NtSetInformationThread().

◆ SeComputeQuotaInformationSize()

NTSTATUS NTAPI SeComputeQuotaInformationSize ( _In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_Out_ PULONG  QuotaInfoSize 
)

◆ SeCopyClientToken()

NTSTATUS NTAPI SeCopyClientToken ( _In_ PACCESS_TOKEN  Token,
_In_ SECURITY_IMPERSONATION_LEVEL  Level,
_In_ KPROCESSOR_MODE  PreviousMode,
_Out_ PACCESS_TOKEN NewToken 
)

Copies an existing access token (technically duplicating a new one).

Parameters
[in]TokenToken to copy.
[in]LevelImpersonation security level to assign to the newly copied token.
[in]PreviousModeProcessor request level mode.
[out]NewTokenThe newly copied token.
Returns
Returns STATUS_SUCCESS when token copying has finished successfully. A failure NTSTATUS code is returned otherwise.

Definition at line 1542 of file token.c.

1547{
1550
1551 PAGED_CODE();
1552
1554 NULL,
1555 0,
1556 NULL,
1557 NULL);
1558
1561 FALSE,
1563 Level,
1565 (PTOKEN*)NewToken);
1566
1567 return Status;
1568}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FALSE
Definition: types.h:117
@ TokenImpersonation
Definition: imports.h:274
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS NTAPI SepDuplicateToken(_In_ PTOKEN Token, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PTOKEN *NewAccessToken)
Duplicates an access token, from an existing valid token.
Definition: tokenlif.c:471
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

Referenced by PsImpersonateClient(), and SepCreateClientSecurity().

◆ SeCreateAccessStateEx()

NTSTATUS NTAPI SeCreateAccessStateEx ( _In_ PETHREAD  Thread,
_In_ PEPROCESS  Process,
_In_ OUT PACCESS_STATE  AccessState,
_In_ PAUX_ACCESS_DATA  AuxData,
_In_ ACCESS_MASK  Access,
_In_ PGENERIC_MAPPING  GenericMapping 
)

◆ SeDeassignPrimaryToken()

VOID NTAPI SeDeassignPrimaryToken ( _Inout_ PEPROCESS  Process)

Removes the primary token of a process.

Parameters
[in,out]ProcessThe process instance with the access token to be removed.
Returns
Nothing.

Definition at line 936 of file token.c.

938{
939 PTOKEN OldToken;
940
941 /* Remove the Token */
942 OldToken = ObFastReplaceObject(&Process->Token, NULL);
943
944 /* Mark the Old Token as free */
945 OldToken->TokenInUse = FALSE;
946
947 /* Dereference the Token */
948 ObDereferenceObject(OldToken);
949}
PVOID FASTCALL ObFastReplaceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
BOOLEAN TokenInUse
Definition: setypes.h:242
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by PspDeleteProcessSecurity(), and SeAssignPrimaryToken().

◆ SeDefaultObjectMethod()

NTSTATUS NTAPI SeDefaultObjectMethod ( _In_ PVOID  Object,
_In_ SECURITY_OPERATION_CODE  OperationType,
_In_ PSECURITY_INFORMATION  SecurityInformation,
_Inout_opt_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_Inout_opt_ PULONG  ReturnLength,
_Inout_opt_ PSECURITY_DESCRIPTOR OldSecurityDescriptor,
_In_ POOL_TYPE  PoolType,
_In_ PGENERIC_MAPPING  GenericMapping 
)

◆ SeDetailedAuditingWithToken()

BOOLEAN NTAPI SeDetailedAuditingWithToken ( _In_ PTOKEN  Token)

Peforms a detailed security auditing with an access token.

@unimplemented

Parameters
[in]TokenA valid token object.
Returns
To be added...

Definition at line 34 of file audit.c.

36{
37 /* FIXME */
38 return FALSE;
39}

Referenced by ObInitProcess(), PspCreateProcess(), and PspExitThread().

◆ SeExchangePrimaryToken()

NTSTATUS NTAPI SeExchangePrimaryToken ( _In_ PEPROCESS  Process,
_In_ PACCESS_TOKEN  NewAccessToken,
_Out_ PACCESS_TOKEN OldAccessToken 
)

Replaces the old access token of a process (pointed by the EPROCESS kernel structure) with a new access token. The new access token must be a primary token for use.

Parameters
[in]ProcessThe process instance where its access token is about to be replaced.
[in]NewAccessTokenThe new token that it's going to replace the old one.
[out]OldAccessTokenThe returned old token that's been replaced, which the caller can do anything.
Returns
Returns STATUS_SUCCESS if the exchange operation between tokens has completed successfully. STATUS_BAD_TOKEN_TYPE is returned if the new token is not a primary one so that we cannot exchange it with the old one from the process. STATUS_TOKEN_ALREADY_IN_USE is returned if both tokens aren't equal which means one of them has different properties (groups, privileges, etc.) and as such one of them is currently in use. A failure NTSTATUS code is returned otherwise.

Definition at line 846 of file token.c.

850{
851 PTOKEN OldToken;
852 PTOKEN NewToken = (PTOKEN)NewAccessToken;
853
854 PAGED_CODE();
855
856 if (NewToken->TokenType != TokenPrimary)
858
859 if (NewToken->TokenInUse)
860 {
863
864 /* Maybe we're trying to set the same token */
866 if (OldToken == NewToken)
867 {
868 /* So it's a nop. */
869 *OldAccessToken = OldToken;
870 return STATUS_SUCCESS;
871 }
872
873 Status = SepCompareTokens(OldToken, NewToken, &IsEqual);
874 if (!NT_SUCCESS(Status))
875 {
877 *OldAccessToken = NULL;
878 return Status;
879 }
880
881 if (!IsEqual)
882 {
884 *OldAccessToken = NULL;
886 }
887 /* Silently return STATUS_SUCCESS but do not set the new token,
888 * as it's already in use elsewhere. */
889 *OldAccessToken = OldToken;
890 return STATUS_SUCCESS;
891 }
892
893 /* Lock the new token */
895
896 /* Mark new token in use */
897 NewToken->TokenInUse = TRUE;
898
899 /* Set the session ID for the new token */
900 NewToken->SessionId = MmGetSessionId(Process);
901
902 /* Unlock the new token */
903 SepReleaseTokenLock(NewToken);
904
905 /* Reference the new token */
906 ObReferenceObject(NewToken);
907
908 /* Replace the old with the new */
909 OldToken = ObFastReplaceObject(&Process->Token, NewToken);
910
911 /* Lock the old token */
913
914 /* Mark the old token as free */
915 OldToken->TokenInUse = FALSE;
916
917 /* Unlock the old token */
918 SepReleaseTokenLock(OldToken);
919
920 *OldAccessToken = (PACCESS_TOKEN)OldToken;
921 return STATUS_SUCCESS;
922}
@ IsEqual
Definition: fatprocs.h:1886
@ TokenPrimary
Definition: imports.h:273
#define PsDereferencePrimaryToken(T)
Definition: imports.h:301
struct _TOKEN * PTOKEN
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
#define SepAcquireTokenLockExclusive(Token)
Definition: se.h:285
#define SepReleaseTokenLock(Token)
Definition: se.h:296
static NTSTATUS SepCompareTokens(_In_ PTOKEN FirstToken, _In_ PTOKEN SecondToken, _Out_ PBOOLEAN Equal)
Compares tokens if they're equal based on all the following properties. If all of the said conditions...
Definition: token.c:243
#define STATUS_TOKEN_ALREADY_IN_USE
Definition: ntstatus.h:535
#define STATUS_BAD_TOKEN_TYPE
Definition: ntstatus.h:404
ULONG SessionId
Definition: setypes.h:225
TOKEN_TYPE TokenType
Definition: setypes.h:239
#define ObReferenceObject
Definition: obfuncs.h:204
PVOID PACCESS_TOKEN
Definition: setypes.h:11

Referenced by PspAssignPrimaryToken().

◆ 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 2138 of file accesschk.c.

2143{
2144 PACL Dacl;
2147
2148 PAGED_CODE();
2149
2151
2152 if (SecurityDescriptor == NULL)
2153 return FALSE;
2154
2155 /* Get DACL */
2157 /* If no DACL, grant access */
2158 if (Dacl == NULL)
2159 return TRUE;
2160
2161 /* No ACE -> Deny */
2162 if (!Dacl->AceCount)
2163 return FALSE;
2164
2165 /* Can't perform the check on restricted token */
2166 if (AccessState->Flags & TOKEN_IS_RESTRICTED)
2167 return FALSE;
2168
2169 /* Browse the ACEs */
2170 for (AceIndex = 0, Ace = (PKNOWN_ACE)((ULONG_PTR)Dacl + sizeof(ACL));
2171 AceIndex < Dacl->AceCount;
2172 AceIndex++, Ace = (PKNOWN_ACE)((ULONG_PTR)Ace + Ace->Header.AceSize))
2173 {
2174 if (Ace->Header.AceFlags & INHERIT_ONLY_ACE)
2175 continue;
2176
2177 /* If access-allowed ACE */
2178 if (Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
2179 {
2180 /* Check if all accesses are granted */
2181 if (!(Ace->Mask & DesiredAccess))
2182 continue;
2183
2184 /* Check SID and grant access if matching */
2185 if (RtlEqualSid(SeWorldSid, &(Ace->SidStart)))
2186 return TRUE;
2187 }
2188 /* If access-denied ACE */
2189 else if (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE)
2190 {
2191 /* Here, only check if it denies any access wanted and deny if so */
2192 if (Ace->Mask & DesiredAccess)
2193 return FALSE;
2194 }
2195 }
2196
2197 /* Faulty, deny */
2198 return FALSE;
2199}
@ Ace
Definition: card.h:12
#define ASSERT(a)
Definition: mode.c:44
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
PSID SeWorldSid
Definition: sid.c:25
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:129
struct _KNOWN_ACE * PKNOWN_ACE
Definition: se.h:15
uint32_t ULONG_PTR
Definition: typedefs.h:65
_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:191
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1183

Referenced by IopParseDevice(), and ObpCheckTraverseAccess().

◆ SeGetLogonIdDeviceMap()

NTSTATUS NTAPI SeGetLogonIdDeviceMap ( _In_ PLUID  LogonId,
_Out_ PDEVICE_MAP DeviceMap 
)

Retrieves the DOS device map from a logon session.

Parameters
[in]LogonIdA valid logon session ID.
[out]DeviceMapThe returned device map buffer from the logon session.
Returns
Returns STATUS_SUCCESS if the device map could be gathered from the logon session. STATUS_INVALID_PARAMETER is returned if one of the parameters aren't initialized (that is, the caller has submitted a NULL pointer variable). STATUS_NO_SUCH_LOGON_SESSION is returned if no such session could be found. A failure NTSTATUS code is returned otherwise.

Definition at line 1347 of file srm.c.

1350{
1352 WCHAR Buffer[63];
1353 PDEVICE_MAP LocalMap;
1354 HANDLE DirectoryHandle, LinkHandle;
1356 PSEP_LOGON_SESSION_REFERENCES CurrentSession;
1357 UNICODE_STRING DirectoryName, LinkName, TargetName;
1358
1359 PAGED_CODE();
1360
1361 if (LogonId == NULL ||
1362 DeviceMap == NULL)
1363 {
1365 }
1366
1367 /* Acquire the database lock */
1369
1370 /* Loop all existing sessions */
1371 for (CurrentSession = SepLogonSessions;
1372 CurrentSession != NULL;
1373 CurrentSession = CurrentSession->Next)
1374 {
1375 /* Check if the LUID matches the provided one */
1376 if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
1377 {
1378 break;
1379 }
1380 }
1381
1382 /* No session found, fail */
1383 if (CurrentSession == NULL)
1384 {
1385 /* Release the database lock */
1387
1389 }
1390
1391 /* The found session has a device map, return it! */
1392 if (CurrentSession->pDeviceMap != NULL)
1393 {
1394 *DeviceMap = CurrentSession->pDeviceMap;
1395
1396 /* Release the database lock */
1398
1399 return STATUS_SUCCESS;
1400 }
1401
1402 /* At that point, we'll setup a new device map for the session */
1403 LocalMap = NULL;
1404
1405 /* Reference the session so that it doesn't go away */
1406 CurrentSession->ReferenceCount += 1;
1407
1408 /* Release the database lock */
1410
1411 /* Create our object directory given the LUID */
1413 sizeof(Buffer) / sizeof(WCHAR),
1414 L"\\Sessions\\0\\DosDevices\\%08x-%08x",
1415 LogonId->HighPart,
1416 LogonId->LowPart);
1417 RtlInitUnicodeString(&DirectoryName, Buffer);
1418
1420 &DirectoryName,
1422 NULL,
1423 NULL);
1427 if (NT_SUCCESS(Status))
1428 {
1429 /* Create the associated device map */
1431 if (NT_SUCCESS(Status))
1432 {
1433 /* Make Global point to \Global?? in the directory */
1434 RtlInitUnicodeString(&LinkName, L"Global");
1435 RtlInitUnicodeString(&TargetName, L"\\Global??");
1436
1438 &LinkName,
1441 NULL);
1442 Status = ZwCreateSymbolicLinkObject(&LinkHandle,
1445 &TargetName);
1446 if (!NT_SUCCESS(Status))
1447 {
1448 ObfDereferenceDeviceMap(LocalMap);
1449 }
1450 else
1451 {
1452 ZwClose(LinkHandle);
1453 }
1454 }
1455
1457 }
1458
1459 /* Acquire the database lock */
1461
1462 /* If we succeed... */
1463 if (NT_SUCCESS(Status))
1464 {
1465 /* The session now has a device map? We raced with someone else */
1466 if (CurrentSession->pDeviceMap != NULL)
1467 {
1468 /* Give up on our new device map */
1469 ObfDereferenceDeviceMap(LocalMap);
1470 }
1471 /* Otherwise use our newly allocated device map */
1472 else
1473 {
1474 CurrentSession->pDeviceMap = LocalMap;
1475 }
1476
1477 /* Return the device map */
1478 *DeviceMap = CurrentSession->pDeviceMap;
1479 }
1480 /* Zero output */
1481 else
1482 {
1483 *DeviceMap = NULL;
1484 }
1485
1486 /* Release the database lock */
1488
1489 /* We're done with the session */
1490 SepRmDereferenceLogonSession(&CurrentSession->LogonId);
1491
1492 return Status;
1493}
static HANDLE DirectoryHandle
Definition: ObType.c:48
Definition: bufpool.h:45
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwCreateSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ PUNICODE_STRING Name)
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
_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 LogonId
NTSTATUS SepRmDereferenceLogonSession(_In_ PLUID LogonLuid)
De-references a logon session. If the session has a reference count of 0 by the time the function has...
Definition: srm.c:1008
KGUARDED_MUTEX SepRmDbLock
Definition: srm.c:61
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions
Definition: srm.c:62
#define STATUS_NO_SUCH_LOGON_SESSION
Definition: ntstatus.h:331
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObSetDirectoryDeviceMap(OUT PDEVICE_MAP *DeviceMap, IN HANDLE DirectoryHandle)
Definition: devicemap.c:149
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
static PCWSTR TargetName
Definition: ping.c:67
struct _SEP_LOGON_SESSION_REFERENCES * Next
Definition: setypes.h:169
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ObpReferenceDeviceMap(), and ObpSetCurrentProcessDeviceMap().

◆ SeGetTokenControlInformation()

VOID NTAPI SeGetTokenControlInformation ( _In_ PACCESS_TOKEN  _Token,
_Out_ PTOKEN_CONTROL  TokenControl 
)

Retrieves token control information.

Parameters
[in]_TokenA valid token object.
[out]SecurityDescriptorThe returned token control information.
Returns
Nothing.

Definition at line 1720 of file token.c.

1723{
1724 PTOKEN Token = _Token;
1725 PAGED_CODE();
1726
1727 /* Capture the main fields */
1728 TokenControl->AuthenticationId = Token->AuthenticationId;
1729 TokenControl->TokenId = Token->TokenId;
1730 TokenControl->TokenSource = Token->TokenSource;
1731
1732 /* Lock the token */
1734
1735 /* Capture the modified ID */
1736 TokenControl->ModifiedId = Token->ModifiedId;
1737
1738 /* Unlock it */
1740}
#define SepAcquireTokenLockShared(Token)
Definition: se.h:290

Referenced by SepCreateClientSecurity().

◆ SeInitializeProcessAuditName()

NTSTATUS NTAPI SeInitializeProcessAuditName ( _In_ PFILE_OBJECT  FileObject,
_In_ BOOLEAN  DoAudit,
_Out_ POBJECT_NAME_INFORMATION AuditInfo 
)

Initializes a process audit name and returns it to the caller.

Parameters
[in]FileObjectFile object that points to a name to be queried.
[in]DoAuditIf set to TRUE, the function will perform various security auditing onto the audit name.
[out]AuditInfoThe returned audit info data.
Returns
Returns STATUS_SUCCESS if process audit name initialization has completed successfully. STATUS_NO_MEMORY is returned if pool allocation for object name info has failed. A failure NTSTATUS code is returned otherwise.

Definition at line 105 of file audit.c.

109{
110 OBJECT_NAME_INFORMATION LocalNameInfo;
111 POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
114
115 PAGED_CODE();
116 ASSERT(AuditInfo);
117
118 /* Check if we should do auditing */
119 if (DoAudit)
120 {
121 /* FIXME: TODO */
122 }
123
124 /* Now query the name */
126 &LocalNameInfo,
127 sizeof(LocalNameInfo),
128 &ReturnLength);
129 if (((Status == STATUS_BUFFER_OVERFLOW) ||
132 (ReturnLength != sizeof(LocalNameInfo)))
133 {
134 /* Allocate required size */
135 ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool,
137 TAG_SEPA);
138 if (ObjectNameInfo)
139 {
140 /* Query the name again */
142 ObjectNameInfo,
144 &ReturnLength);
145 }
146 }
147
148 /* Check if we got here due to failure */
149 if ((ObjectNameInfo) &&
150 (!(NT_SUCCESS(Status)) || (ReturnLength == sizeof(LocalNameInfo))))
151 {
152 /* First, free any buffer we might've allocated */
153 ASSERT(FALSE);
154 if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
155
156 /* Now allocate a temporary one */
158 ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool,
160 TAG_SEPA);
161 if (ObjectNameInfo)
162 {
163 /* Clear it */
164 RtlZeroMemory(ObjectNameInfo, ReturnLength);
166 }
167 }
168
169 /* Check if memory allocation failed */
170 if (!ObjectNameInfo) Status = STATUS_NO_MEMORY;
171
172 /* Return the audit name */
173 *AuditInfo = ObjectNameInfo;
174
175 /* Return status */
176 return Status;
177}
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by MmInitializeProcessAddressSpace(), and SeLocateProcessImageName().

◆ SeInitSystem()

BOOLEAN NTAPI SeInitSystem ( VOID  )

Main security manager initialization function.

Returns
Returns a boolean value according to the phase initialization routine that handles it. If TRUE, the routine deems the initialization phase as complete, FALSE otherwise.

Definition at line 285 of file semgr.c.

286{
287 /* Check the initialization phase */
289 {
290 case 0:
291
292 /* Do Phase 0 */
294
295 case 1:
296
297 /* Do Phase 1 */
299
300 default:
301
302 /* Don't know any other phase! Bugcheck! */
303 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
304 0,
306 0,
307 0);
308 return FALSE;
309 }
310}
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
ULONG ExpInitializationPhase
Definition: init.c:68
BOOLEAN NTAPI SepInitializationPhase1(VOID)
Handles the phase 1 procedure of the SRM initialization.
Definition: semgr.c:168
BOOLEAN NTAPI SepInitializationPhase0(VOID)
Handles the phase 0 procedure of the SRM initialization.
Definition: semgr.c:115

Referenced by ExpInitializeExecutive(), and Phase1InitializationDiscard().

◆ SeIsTokenChild()

NTSTATUS NTAPI SeIsTokenChild ( _In_ PTOKEN  Token,
_Out_ PBOOLEAN  IsChild 
)

Checks if the token is a child of the other token of the current process that the calling thread is invoking this function.

Parameters
[in]TokenAn access token to determine if it's a child or not.
[out]IsChildThe returned boolean result.
Returns
Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL is returned if primary token of the current calling process couldn't be referenced otherwise.

Definition at line 1433 of file token.c.

1436{
1437 PTOKEN ProcessToken;
1438 LUID ProcessTokenId, CallerParentId;
1439
1440 /* Assume failure */
1441 *IsChild = FALSE;
1442
1443 /* Reference the process token */
1445 if (!ProcessToken)
1446 return STATUS_UNSUCCESSFUL;
1447
1448 /* Get its token ID */
1449 ProcessTokenId = ProcessToken->TokenId;
1450
1451 /* Dereference the token */
1453
1454 /* Get our parent token ID */
1455 CallerParentId = Token->ParentTokenId;
1456
1457 /* Compare the token IDs */
1458 if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1459 *IsChild = TRUE;
1460
1461 /* Return success */
1462 return STATUS_SUCCESS;
1463}
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
LUID TokenId
Definition: setypes.h:218
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by PspSetPrimaryToken().

◆ SeIsTokenSibling()

NTSTATUS NTAPI SeIsTokenSibling ( _In_ PTOKEN  Token,
_Out_ PBOOLEAN  IsSibling 
)

Checks if the token is a sibling of the other token of the current process that the calling thread is invoking this function.

Parameters
[in]TokenAn access token to determine if it's a sibling or not.
[out]IsSiblingThe returned boolean result.
Returns
Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL is returned if primary token of the current calling process couldn't be referenced otherwise.

Definition at line 1482 of file token.c.

1485{
1486 PTOKEN ProcessToken;
1487 LUID ProcessParentId, ProcessAuthId;
1488 LUID CallerParentId, CallerAuthId;
1489
1490 /* Assume failure */
1491 *IsSibling = FALSE;
1492
1493 /* Reference the process token */
1495 if (!ProcessToken)
1496 return STATUS_UNSUCCESSFUL;
1497
1498 /* Get its parent and authentication IDs */
1499 ProcessParentId = ProcessToken->ParentTokenId;
1500 ProcessAuthId = ProcessToken->AuthenticationId;
1501
1502 /* Dereference the token */
1504
1505 /* Get our parent and authentication IDs */
1506 CallerParentId = Token->ParentTokenId;
1507 CallerAuthId = Token->AuthenticationId;
1508
1509 /* Compare the token IDs */
1510 if (RtlEqualLuid(&CallerParentId, &ProcessParentId) &&
1511 RtlEqualLuid(&CallerAuthId, &ProcessAuthId))
1512 {
1513 *IsSibling = TRUE;
1514 }
1515
1516 /* Return success */
1517 return STATUS_SUCCESS;
1518}
LUID AuthenticationId
Definition: setypes.h:219
LUID ParentTokenId
Definition: setypes.h:220

Referenced by PspSetPrimaryToken().

◆ SepCaptureAcl()

NTSTATUS NTAPI SepCaptureAcl ( _In_ PACL  InputAcl,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PACL CapturedAcl 
)

Captures an access control list from an already valid input ACL.

Parameters
[in]InputAclA valid ACL.
[in]AccessModeProcessor level access mode. The processor mode determines how the input arguments are probed.
[in]PoolTypePool type for new captured ACL for creation. The pool type determines in which memory pool the ACL data should reside.
[in]CaptureIfKernelIf set to TRUE and the processor access mode being KernelMode, we are capturing an ACL directly in the kernel. Otherwise we are capturing within a kernel mode driver.
[out]CapturedAclThe returned and allocated captured ACL.
Returns
Returns STATUS_SUCCESS if the ACL has been successfully captured. STATUS_INSUFFICIENT_RESOURCES is returned otherwise.

Definition at line 352 of file acl.c.

358{
359 PACL NewAcl;
360 ULONG AclSize;
361
362 PAGED_CODE();
363
364 /* If in kernel mode and we do not capture, just
365 * return the given ACL and don't validate it. */
366 if ((AccessMode == KernelMode) && !CaptureIfKernel)
367 {
368 *CapturedAcl = InputAcl;
369 return STATUS_SUCCESS;
370 }
371
372 /* Otherwise, capture and validate the ACL, depending on the access mode */
373 if (AccessMode != KernelMode)
374 {
376 {
377 ProbeForRead(InputAcl,
378 sizeof(ACL),
379 sizeof(ULONG));
380 AclSize = InputAcl->AclSize;
381 ProbeForRead(InputAcl,
382 AclSize,
383 sizeof(ULONG));
384 }
386 {
387 /* Return the exception code */
389 }
390 _SEH2_END;
391
392 /* Validate the minimal size an ACL can have */
393 if (AclSize < sizeof(ACL))
394 return STATUS_INVALID_ACL;
395
397 AclSize,
398 TAG_ACL);
399 if (!NewAcl)
401
403 {
404 RtlCopyMemory(NewAcl, InputAcl, AclSize);
405 }
407 {
408 /* Free the ACL and return the exception code */
409 ExFreePoolWithTag(NewAcl, TAG_ACL);
411 }
412 _SEH2_END;
413 }
414 else
415 {
416 AclSize = InputAcl->AclSize;
417
418 /* Validate the minimal size an ACL can have */
419 if (AclSize < sizeof(ACL))
420 return STATUS_INVALID_ACL;
421
423 AclSize,
424 TAG_ACL);
425 if (!NewAcl)
427
428 RtlCopyMemory(NewAcl, InputAcl, AclSize);
429 }
430
431 /* Validate the captured ACL */
432 if (!RtlValidAcl(NewAcl))
433 {
434 /* Free the ACL and fail */
435 ExFreePoolWithTag(NewAcl, TAG_ACL);
436 return STATUS_INVALID_ACL;
437 }
438
439 /* It's valid, return it */
440 *CapturedAcl = NewAcl;
441 return STATUS_SUCCESS;
442}
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
#define TAG_ACL
Definition: tag.h:151

Referenced by NtCreateToken(), and NtSetInformationToken().

◆ SepCaptureSecurityQualityOfService()

NTSTATUS NTAPI SepCaptureSecurityQualityOfService ( _In_opt_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService,
_Out_ PBOOLEAN  Present 
)

Captures the security quality of service data given the object attributes from an object.

Parameters
[in]ObjectAttributesAttributes of an object where SQOS is to be retrieved. If the caller doesn't fill object attributes to the function, it automatically assumes SQOS is not present, or if, there's no SQOS present in the object attributes list of the object itself.
[in]AccessModeProcessor access mode.
[in]PoolTypeThe pool type for the captured SQOS to be used for allocation.
[in]CaptureIfKernelCapture access condition. To be set to TRUE if the capture is done within the kernel, FALSE if the capture is done in a kernel mode driver or user mode otherwise.
[out]CapturedSecurityQualityOfServiceThe captured SQOS data from the object.
[out]PresentReturns TRUE if SQOS is present in an object, FALSE otherwise. FALSE is also immediately returned if no object attributes is given to the call.
Returns
STATUS_SUCCESS if SQOS from the object has been fully and successfully captured. STATUS_INVALID_PARAMETER if the caller submits an invalid object attributes list. STATUS_INSUFFICIENT_RESOURCES if the function has failed to allocate some resources in the pool for the captured SQOS. A failure NTSTATUS code is returned otherwise.

Definition at line 52 of file sqos.c.

59{
62
63 PAGED_CODE();
64
65 ASSERT(CapturedSecurityQualityOfService);
66 ASSERT(Present);
67
69 {
71 {
73
75 {
77 sizeof(OBJECT_ATTRIBUTES),
78 sizeof(ULONG));
80 {
81 if (ObjectAttributes->SecurityQualityOfService != NULL)
82 {
83 ProbeForRead(ObjectAttributes->SecurityQualityOfService,
85 sizeof(ULONG));
86
87 if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
89 {
90 /*
91 * Don't allocate memory here because ExAllocate should bugcheck
92 * the system if it's buggy, SEH would catch that! So make a local
93 * copy of the qos structure.
94 */
95 RtlCopyMemory(&SafeQos,
96 ObjectAttributes->SecurityQualityOfService,
98 *Present = TRUE;
99 }
100 else
101 {
103 }
104 }
105 else
106 {
107 *CapturedSecurityQualityOfService = NULL;
108 *Present = FALSE;
109 }
110 }
111 else
112 {
114 }
115 }
117 {
119 }
120 _SEH2_END;
121
122 if (NT_SUCCESS(Status))
123 {
124 if (*Present)
125 {
126 CapturedQos = ExAllocatePoolWithTag(PoolType,
128 TAG_QOS);
129 if (CapturedQos != NULL)
130 {
131 RtlCopyMemory(CapturedQos,
132 &SafeQos,
134 *CapturedSecurityQualityOfService = CapturedQos;
135 }
136 else
137 {
139 }
140 }
141 else
142 {
143 *CapturedSecurityQualityOfService = NULL;
144 }
145 }
146 }
147 else
148 {
150 {
151 if (CaptureIfKernel)
152 {
153 if (ObjectAttributes->SecurityQualityOfService != NULL)
154 {
155 if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
157 {
158 CapturedQos = ExAllocatePoolWithTag(PoolType,
160 TAG_QOS);
161 if (CapturedQos != NULL)
162 {
163 RtlCopyMemory(CapturedQos,
164 ObjectAttributes->SecurityQualityOfService,
166 *CapturedSecurityQualityOfService = CapturedQos;
167 *Present = TRUE;
168 }
169 else
170 {
172 }
173 }
174 else
175 {
177 }
178 }
179 else
180 {
181 *CapturedSecurityQualityOfService = NULL;
182 *Present = FALSE;
183 }
184 }
185 else
186 {
187 *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
188 *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
189 }
190 }
191 else
192 {
194 }
195 }
196 }
197 else
198 {
199 *CapturedSecurityQualityOfService = NULL;
200 *Present = FALSE;
201 }
202
203 return Status;
204}
struct _SECURITY_QUALITY_OF_SERVICE * PSECURITY_QUALITY_OF_SERVICE
#define TAG_QOS
Definition: tag.h:154

Referenced by NtDuplicateToken().

◆ SepCaptureSid()

NTSTATUS NTAPI SepCaptureSid ( _In_ PSID  InputSid,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PSID CapturedSid 
)

Captures a SID.

Parameters
[in]InputSidA valid security identifier to be captured.
[in]AccessModeProcessor level access mode.
[in]PoolTypePool memory type for the captured SID to assign upon allocation.
[in]CaptureIfKernelIf set to TRUE, the capturing is done within the kernel. Otherwise the capturing is done in a kernel mode driver.
[out]CapturedSidThe captured security identifier, returned to the caller.
Returns
Returns STATUS_SUCCESS if the SID was captured. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the captured SID has failed.

Definition at line 314 of file sid.c.

320{
321 ULONG SidSize = 0;
322 PISID NewSid, Sid = (PISID)InputSid;
323
324 PAGED_CODE();
325
326 if (AccessMode != KernelMode)
327 {
329 {
330 ProbeForRead(Sid, FIELD_OFFSET(SID, SubAuthority), sizeof(UCHAR));
332 ProbeForRead(Sid, SidSize, sizeof(UCHAR));
333 }
335 {
336 /* Return the exception code */
338 }
339 _SEH2_END;
340
341 /* Allocate a SID and copy it */
343 if (!NewSid)
345
347 {
348 RtlCopyMemory(NewSid, Sid, SidSize);
349
350 *CapturedSid = NewSid;
351 }
353 {
354 /* Free the SID and return the exception code */
357 }
358 _SEH2_END;
359 }
360 else if (!CaptureIfKernel)
361 {
362 *CapturedSid = InputSid;
363 }
364 else
365 {
367
368 /* Allocate a SID and copy it */
370 if (NewSid == NULL)
372
373 RtlCopyMemory(NewSid, Sid, SidSize);
374
375 *CapturedSid = NewSid;
376 }
377
378 return STATUS_SUCCESS;
379}
#define TAG_SID
Definition: tag.h:152
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ PSID _In_ PSID NewSid
Definition: rtlfuncs.h:2814
struct _SID * PISID
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by NtCreateToken(), NtSecureConnectPort(), NtSetInformationToken(), SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SepComputeAvailableDynamicSpace()

ULONG SepComputeAvailableDynamicSpace ( _In_ ULONG  DynamicCharged,
_In_ PSID  PrimaryGroup,
_In_opt_ PACL  DefaultDacl 
)

Computes the exact available dynamic area of an access token whilst querying token statistics.

Parameters
[in]DynamicChargedThe current charged dynamic area of an access token. This must not be 0!
[in]PrimaryGroupA pointer to a primary group SID.
[in]DefaultDaclIf provided, this pointer points to a default DACL of an access token.
Returns
Returns the calculated available dynamic area.

Definition at line 659 of file token.c.

663{
664 ULONG DynamicAvailable;
665
666 PAGED_CODE();
667
668 /* A token's dynamic area is always charged */
669 ASSERT(DynamicCharged != 0);
670
671 /*
672 * Take into account the default DACL if
673 * the token has one. Otherwise the occupied
674 * space is just the present primary group.
675 */
676 DynamicAvailable = DynamicCharged - RtlLengthSid(PrimaryGroup);
677 if (DefaultDacl)
678 {
679 DynamicAvailable -= DefaultDacl->AclSize;
680 }
681
682 return DynamicAvailable;
683}
_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 _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID PrimaryGroup
Definition: rtlfuncs.h:1599

Referenced by NtQueryInformationToken(), and SeQueryInformationToken().

◆ SepCreateImpersonationTokenDacl()

NTSTATUS NTAPI SepCreateImpersonationTokenDacl ( _In_ PTOKEN  Token,
_In_ PTOKEN  PrimaryToken,
_Out_ PACL Dacl 
)

Allocates a discretionary access control list based on certain properties of a regular and primary access tokens.

Parameters
[in]TokenAn access token.
[in]PrimaryTokenA primary access token.
[out]DaclThe returned allocated DACL.
Returns
Returns STATUS_SUCCESS if DACL creation from tokens has completed successfully. STATUS_INSUFFICIENT_RESOURCES is returned if DACL allocation from memory pool fails otherwise.

Definition at line 277 of file acl.c.

281{
283 PACL TokenDacl;
284
285 PAGED_CODE();
286
287 *Dacl = NULL;
288
289 AclLength = sizeof(ACL) +
290 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
291 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
293 (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) +
294 (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid));
295
297 if (TokenDacl == NULL)
298 {
300 }
301
304 Token->UserAndGroups->Sid);
306 PrimaryToken->UserAndGroups->Sid);
311
312 if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL)
313 {
316 }
317
318 *Dacl = TokenDacl;
319
320 return STATUS_SUCCESS;
321}
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
struct _ACL ACL
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
#define GENERIC_ALL
Definition: nt_native.h:92
PSID SeLocalSystemSid
Definition: sid.c:38
PSID SeAliasAdminsSid
Definition: sid.c:41
PSID SeRestrictedCodeSid
Definition: sid.c:40
Definition: rtltypes.h:993
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#define ACL_REVISION
Definition: setypes.h:39

Referenced by SepOpenThreadToken().

◆ SepCreateSystemAnonymousLogonToken()

PTOKEN SepCreateSystemAnonymousLogonToken ( VOID  )

Creates the anonymous logon token for the system. The difference between this token and the other one is the inclusion of everyone SID group (being SeWorldSid). The other token lacks such group.

Returns
Returns the system's anonymous logon token if the operations have completed successfully.

Definition at line 1868 of file token.c.

1869{
1870 SID_AND_ATTRIBUTES UserSid;
1872 PTOKEN Token;
1873 ULONG GroupsLength;
1874 LARGE_INTEGER Expiration;
1877
1878 /* The token never expires */
1879 Expiration.QuadPart = -1;
1880
1881 /* The user is the anonymous logon */
1882 UserSid.Sid = SeAnonymousLogonSid;
1883 UserSid.Attributes = 0;
1884
1885 /* The primary group is also the anonymous logon */
1887
1888 /* The only group for the token is the World */
1889 SID_AND_ATTRIBUTES Groups[] =
1890 {
1892 };
1893 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1894 SeLengthSid(Groups[0].Sid);
1895 ASSERT(GroupsLength <= (sizeof(Groups) * sizeof(ULONG)));
1896
1897 /* Initialise the object attributes for the token */
1900
1901 /* Create token */
1903 KernelMode,
1904 0,
1909 &Expiration,
1910 &UserSid,
1911 RTL_NUMBER_OF(Groups),
1912 Groups,
1913 GroupsLength,
1914 0,
1915 NULL,
1916 NULL,
1920 TRUE);
1922
1923 /* Return the anonymous logon token */
1924 return Token;
1925}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
@ SecurityAnonymous
Definition: lsa.idl:55
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
#define SE_GROUP_ENABLED
Definition: setypes.h:92
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
PSID SeAnonymousLogonSid
Definition: se.h:213
NTSTATUS NTAPI SepCreateToken(_Out_ PHANDLE TokenHandle, _In_ KPROCESSOR_MODE PreviousMode, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PSID_AND_ATTRIBUTES User, _In_ ULONG GroupCount, _In_ PSID_AND_ATTRIBUTES Groups, _In_ ULONG GroupsLength, _In_ ULONG PrivilegeCount, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_opt_ PSID Owner, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl, _In_ PTOKEN_SOURCE TokenSource, _In_ BOOLEAN SystemToken)
Internal function responsible for access token object creation in the kernel. A fully created token o...
Definition: tokenlif.c:97
TOKEN_SOURCE SeSystemTokenSource
Definition: token.c:19
LUID SeAnonymousAuthenticationId
Definition: token.c:21
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
LONGLONG QuadPart
Definition: typedefs.h:114
#define SeLengthSid(Sid)
Definition: sefuncs.h:570

Referenced by SepInitializationPhase0().

◆ SepCreateSystemAnonymousLogonTokenNoEveryone()

PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone ( VOID  )

Creates the anonymous logon token for the system. This kind of token doesn't include the everyone SID group (being SeWorldSid).

Returns
Returns the system's anonymous logon token if the operations have completed successfully.

Definition at line 1938 of file token.c.

1939{
1940 SID_AND_ATTRIBUTES UserSid;
1942 PTOKEN Token;
1943 LARGE_INTEGER Expiration;
1946
1947 /* The token never expires */
1948 Expiration.QuadPart = -1;
1949
1950 /* The user is the anonymous logon */
1951 UserSid.Sid = SeAnonymousLogonSid;
1952 UserSid.Attributes = 0;
1953
1954 /* The primary group is also the anonymous logon */
1956
1957 /* Initialise the object attributes for the token */
1960
1961 /* Create token */
1963 KernelMode,
1964 0,
1969 &Expiration,
1970 &UserSid,
1971 0,
1972 NULL,
1973 0,
1974 0,
1975 NULL,
1976 NULL,
1980 TRUE);
1982
1983 /* Return the anonymous (not including everyone) logon token */
1984 return Token;
1985}

Referenced by SepInitializationPhase0().

◆ SepCreateSystemProcessToken()

PTOKEN NTAPI SepCreateSystemProcessToken ( VOID  )

Creates the system process token.

Returns
Returns the system process token if the operations have completed successfully.

Definition at line 1753 of file token.c.

1754{
1755 ULONG GroupAttributes, OwnerAttributes;
1756 LARGE_INTEGER Expiration;
1757 SID_AND_ATTRIBUTES UserSid;
1758 ULONG GroupsLength;
1761 PSID Owner;
1762 PTOKEN Token;
1764
1765 /* Don't ever expire */
1766 Expiration.QuadPart = -1;
1767
1768 /* All groups mandatory and enabled */
1771
1772 /* User is Local System */
1773 UserSid.Sid = SeLocalSystemSid;
1774 UserSid.Attributes = 0;
1775
1776 /* Primary group is Local System */
1778
1779 /* Owner is Administrators */
1781
1782 /* Groups are Administrators, World, and Authenticated Users */
1783 SID_AND_ATTRIBUTES Groups[] =
1784 {
1785 {SeAliasAdminsSid, OwnerAttributes},
1786 {SeWorldSid, GroupAttributes},
1787 {SeAuthenticatedUsersSid, GroupAttributes},
1788 {SeLocalSid, SE_GROUP_ENABLED} // HACK: Temporarily add the local group. See CORE-18250.
1789 };
1790 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1791 SeLengthSid(Groups[0].Sid) +
1792 SeLengthSid(Groups[1].Sid) +
1793 SeLengthSid(Groups[2].Sid) +
1794 SeLengthSid(Groups[3].Sid); // HACK
1795 ASSERT(GroupsLength <= (sizeof(Groups) * sizeof(ULONG)));
1796
1797 /* Setup the privileges */
1799 {
1814 {SeBackupPrivilege, 0},
1815 {SeRestorePrivilege, 0},
1820 {SeUndockPrivilege, 0},
1824 };
1825
1826 /* Setup the object attributes */
1829
1830 /* Create the token */
1832 KernelMode,
1833 0,
1838 &Expiration,
1839 &UserSid,
1840 RTL_NUMBER_OF(Groups),
1841 Groups,
1842 GroupsLength,
1844 Privileges,
1845 Owner,
1849 TRUE);
1851
1852 /* Return the token */
1853 return Token;
1854}
static const LUID SeCreateGlobalPrivilege
Definition: authpackage.c:168
static const LUID SeChangeNotifyPrivilege
Definition: authpackage.c:167
static const LUID SeImpersonatePrivilege
Definition: authpackage.c:169
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597
#define SE_GROUP_OWNER
Definition: setypes.h:93
const LUID SeDebugPrivilege
Definition: priv.c:39
const LUID SeCreateTokenPrivilege
Definition: priv.c:21
const LUID SeBackupPrivilege
Definition: priv.c:36
const LUID SeAssignPrimaryTokenPrivilege
Definition: priv.c:22
const LUID SeSystemtimePrivilege
Definition: priv.c:31
const LUID SeTcbPrivilege
Definition: priv.c:26
const LUID SeManageVolumePrivilege
Definition: priv.c:47
const LUID SeRestorePrivilege
Definition: priv.c:37
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:33
const LUID SeLockMemoryPrivilege
Definition: priv.c:23
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
PSID SeLocalSid
Definition: sid.c:26
const LUID SeUndockPrivilege
Definition: priv.c:44
const LUID SeCreatePagefilePrivilege
Definition: priv.c:34
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
const LUID SeProfileSingleProcessPrivilege
Definition: priv.c:32
const LUID SeShutdownPrivilege
Definition: priv.c:38
const LUID SeSystemEnvironmentPrivilege
Definition: priv.c:41
const LUID SeSecurityPrivilege
Definition: priv.c:27
PSID SeAuthenticatedUsersSid
Definition: sid.c:49
const LUID SeAuditPrivilege
Definition: priv.c:40
const LUID SeIncreaseQuotaPrivilege
Definition: priv.c:24
PACL SeSystemDefaultDacl
Definition: acl.c:17
LUID SeSystemAuthenticationId
Definition: token.c:20
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT
Definition: setypes.h:62

Referenced by SepInitializationPhase0().

◆ SepCreateToken()

NTSTATUS NTAPI SepCreateToken ( _Out_ PHANDLE  TokenHandle,
_In_ KPROCESSOR_MODE  PreviousMode,
_In_ ACCESS_MASK  DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ TOKEN_TYPE  TokenType,
_In_ SECURITY_IMPERSONATION_LEVEL  ImpersonationLevel,
_In_ PLUID  AuthenticationId,
_In_ PLARGE_INTEGER  ExpirationTime,
_In_ PSID_AND_ATTRIBUTES  User,
_In_ ULONG  GroupCount,
_In_ PSID_AND_ATTRIBUTES  Groups,
_In_ ULONG  GroupsLength,
_In_ ULONG  PrivilegeCount,
_In_ PLUID_AND_ATTRIBUTES  Privileges,
_In_opt_ PSID  Owner,
_In_ PSID  PrimaryGroup,
_In_opt_ PACL  DefaultDacl,
_In_ PTOKEN_SOURCE  TokenSource,
_In_ BOOLEAN  SystemToken 
)

Internal function responsible for access token object creation in the kernel. A fully created token objected is inserted into the token handle, thus the handle becoming a valid handle to an access token object and ready for use.

Parameters
[out]TokenHandleValid token handle that's ready for use after token creation and object insertion.
[in]PreviousModeProcessor request level mode.
[in]DesiredAccessDesired access right for the token object to be granted. This kind of access right impacts how the token can be used and who.
[in]ObjectAttributesObject attributes for the token to be created.
[in]TokenTypeType of token to assign upon creation.
[in]ImpersonationLevelSecurity impersonation level of token to assign upon creation.
[in]AuthenticationIdAuthentication ID that represents the authentication information of the token.
[in]ExpirationTimeExpiration time of the token to assign. A value of -1 means that the token never expires and its life depends upon the amount of references this token object has.
[in]UserUser entry to assign to the token.
[in]GroupCountThe total number of groups count for the token.
[in]GroupsThe group entries for the token.
[in]GroupsLengthThe length size of the groups array, pointed by the Groups parameter.
[in]PrivilegeCountThe total number of priivleges that the newly created token has.
[in]PrivilegesThe privileges for the token.
[in]OwnerThe main user (or also owner) that represents the token that we create.
[in]PrimaryGroupThe main group that represents the token that we create.
[in]DefaultDaclA discretionary access control list for the token.
[in]TokenSourceSource (or the origin) of the access token that creates it.
[in]SystemTokenIf set to TRUE, the newly created token is a system token and only in charge by the internal system. The function directly returns a pointer to the created token object for system kernel use. Otherwise if set to FALSE, the function inserts the object to a handle making it a regular access token.
Returns
Returns STATUS_SUCCESS if token creation has completed successfully. STATUS_INSUFFICIENT_RESOURCES is returned if the dynamic area of memory of the token hasn't been allocated because of lack of memory resources. A failure NTSTATUS code is returned otherwise.

Definition at line 97 of file tokenlif.c.

117{
119 PTOKEN AccessToken;
120 ULONG TokenFlags = 0;
121 ULONG PrimaryGroupIndex, DefaultOwnerIndex;
122 LUID TokenId;
123 LUID ModifiedId;
124 PVOID EndMem;
125 ULONG PrivilegesLength;
126 ULONG UserGroupsLength;
127 ULONG VariableLength;
128 ULONG DynamicPartSize, TotalSize;
129 ULONG TokenPagedCharges;
130 ULONG i;
131
132 PAGED_CODE();
133
134 /* Loop all groups */
135 for (i = 0; i < GroupCount; i++)
136 {
137 /* Check for mandatory groups */
138 if (Groups[i].Attributes & SE_GROUP_MANDATORY)
139 {
140 /* Force them to be enabled */
141 Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT);
142 }
143
144 /* Check of the group is an admin group */
145 if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid))
146 {
147 /* Remember this so we can optimize queries later */
148 TokenFlags |= TOKEN_HAS_ADMIN_GROUP;
149 }
150 }
151
152 /* Allocate unique IDs for the token */
154 ExAllocateLocallyUniqueId(&ModifiedId);
155
156 /* Compute how much size we need to allocate for the token */
157
158 /* Privileges size */
159 PrivilegesLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
160 PrivilegesLength = ALIGN_UP_BY(PrivilegesLength, sizeof(PVOID));
161
162 /* User and groups size */
163 UserGroupsLength = (1 + GroupCount) * sizeof(SID_AND_ATTRIBUTES);
164 UserGroupsLength += RtlLengthSid(User->Sid);
165 for (i = 0; i < GroupCount; i++)
166 {
167 UserGroupsLength += RtlLengthSid(Groups[i].Sid);
168 }
169 UserGroupsLength = ALIGN_UP_BY(UserGroupsLength, sizeof(PVOID));
170
171 /* Add the additional groups array length */
172 UserGroupsLength += ALIGN_UP_BY(GroupsLength, sizeof(PVOID));
173
174 VariableLength = PrivilegesLength + UserGroupsLength;
175 TotalSize = FIELD_OFFSET(TOKEN, VariablePart) + VariableLength;
176
177 /*
178 * A token is considered slim if it has the default dynamic
179 * contents, or in other words, the primary group and ACL.
180 * We judge if such contents are default by checking their
181 * total size if it's over the range. On Windows this range
182 * is 0x1F4 (aka 500). If the size of the whole dynamic contents
183 * is over that range then the token is considered fat and
184 * the token will be charged the whole of its token body length
185 * plus the dynamic size.
186 */
187 DynamicPartSize = DefaultDacl ? DefaultDacl->AclSize : 0;
188 DynamicPartSize += RtlLengthSid(PrimaryGroup);
189 if (DynamicPartSize > SE_TOKEN_DYNAMIC_SLIM)
190 {
191 TokenPagedCharges = DynamicPartSize + TotalSize;
192 }
193 else
194 {
195 TokenPagedCharges = SE_TOKEN_DYNAMIC_SLIM + TotalSize;
196 }
197
202 NULL,
203 TotalSize,
204 TokenPagedCharges,
205 0,
206 (PVOID*)&AccessToken);
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT1("ObCreateObject() failed (Status 0x%lx)\n", Status);
210 return Status;
211 }
212
213 /* Zero out the buffer and initialize the token */
214 RtlZeroMemory(AccessToken, TotalSize);
215
216 AccessToken->TokenId = TokenId;
217 AccessToken->TokenType = TokenType;
219
220 /* Initialise the lock for the access token */
221 Status = SepCreateTokenLock(AccessToken);
222 if (!NT_SUCCESS(Status))
223 goto Quit;
224
225 AccessToken->TokenSource.SourceIdentifier = TokenSource->SourceIdentifier;
227 TokenSource->SourceName,
228 sizeof(TokenSource->SourceName));
229
230 AccessToken->ExpirationTime = *ExpirationTime;
231 AccessToken->ModifiedId = ModifiedId;
232 AccessToken->DynamicCharged = TokenPagedCharges - TotalSize;
233
234 AccessToken->TokenFlags = TokenFlags & ~TOKEN_SESSION_NOT_REFERENCED;
235
236 /* Copy and reference the logon session */
237 AccessToken->AuthenticationId = *AuthenticationId;
239 if (!NT_SUCCESS(Status))
240 {
241 /* No logon session could be found, bail out */
242 DPRINT1("SepRmReferenceLogonSession() failed (Status 0x%lx)\n", Status);
243 /* Set the flag for proper cleanup by the delete procedure */
245 goto Quit;
246 }
247
248 /* Insert the referenced logon session into the token */
250 if (!NT_SUCCESS(Status))
251 {
252 /* Failed to insert the logon session into the token, bail out */
253 DPRINT1("SepRmInsertLogonSessionIntoToken() failed (Status 0x%lx)\n", Status);
254 goto Quit;
255 }
256
257 /* Fill in token debug information */
258#if DBG
259 /*
260 * We must determine ourselves that the current
261 * process is not the initial CPU one. The initial
262 * process is not a "real" process, that is, the
263 * Process Manager has not yet been initialized and
264 * as a matter of fact we are creating a token before
265 * any process gets created by Ps. If it turns out
266 * that the current process is the initial CPU process
267 * where token creation execution takes place, don't
268 * do anything.
269 */
271 {
272 RtlCopyMemory(AccessToken->ImageFileName,
273 PsGetCurrentProcess()->ImageFileName,
274 min(sizeof(AccessToken->ImageFileName), sizeof(PsGetCurrentProcess()->ImageFileName)));
275
276 AccessToken->ProcessCid = PsGetCurrentProcessId();
277 AccessToken->ThreadCid = PsGetCurrentThreadId();
278 }
279
280 AccessToken->CreateMethod = TOKEN_CREATE_METHOD;
281#endif
282
283 /* Assign the data that reside in the token's variable information area */
284 AccessToken->VariableLength = VariableLength;
285 EndMem = (PVOID)&AccessToken->VariablePart;
286
287 /* Copy the privileges */
288 AccessToken->PrivilegeCount = PrivilegeCount;
289 AccessToken->Privileges = NULL;
290 if (PrivilegeCount > 0)
291 {
292 AccessToken->Privileges = EndMem;
293 EndMem = (PVOID)((ULONG_PTR)EndMem + PrivilegesLength);
294 VariableLength -= PrivilegesLength;
295
297 {
299 {
300 RtlCopyMemory(AccessToken->Privileges,
302 PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
303 }
305 {
307 }
308 _SEH2_END;
309 }
310 else
311 {
312 RtlCopyMemory(AccessToken->Privileges,
314 PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
315 }
316
317 if (!NT_SUCCESS(Status))
318 goto Quit;
319 }
320
321 /* Update the privilege flags */
322 SepUpdatePrivilegeFlagsToken(AccessToken);
323
324 /* Copy the user and groups */
325 AccessToken->UserAndGroupCount = 1 + GroupCount;
326 AccessToken->UserAndGroups = EndMem;
327 EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
328 VariableLength -= ((ULONG_PTR)EndMem - (ULONG_PTR)AccessToken->UserAndGroups);
329
331 User,
332 VariableLength,
333 &AccessToken->UserAndGroups[0],
334 EndMem,
335 &EndMem,
336 &VariableLength);
337 if (!NT_SUCCESS(Status))
338 goto Quit;
339
341 Groups,
342 VariableLength,
343 &AccessToken->UserAndGroups[1],
344 EndMem,
345 &EndMem,
346 &VariableLength);
347 if (!NT_SUCCESS(Status))
348 goto Quit;
349
350 /* Find the token primary group and default owner */
353 Owner,
354 &PrimaryGroupIndex,
355 &DefaultOwnerIndex);
356 if (!NT_SUCCESS(Status))
357 {
358 DPRINT1("SepFindPrimaryGroupAndDefaultOwner failed (Status 0x%lx)\n", Status);
359 goto Quit;
360 }
361
362 /*
363 * Now allocate the token's dynamic information area
364 * and set the data. The dynamic part consists of two
365 * contents, the primary group SID and the default DACL
366 * of the token, in this strict order.
367 */
369 DynamicPartSize,
371 if (AccessToken->DynamicPart == NULL)
372 {
374 goto Quit;
375 }
376
377 /* Unused memory in the dynamic area */
378 AccessToken->DynamicAvailable = 0;
379
380 /*
381 * Assign the primary group to the token
382 * and put it in the dynamic part as well.
383 */
384 EndMem = (PVOID)AccessToken->DynamicPart;
385 AccessToken->PrimaryGroup = EndMem;
386 RtlCopySid(RtlLengthSid(AccessToken->UserAndGroups[PrimaryGroupIndex].Sid),
387 EndMem,
388 AccessToken->UserAndGroups[PrimaryGroupIndex].Sid);
389 AccessToken->DefaultOwnerIndex = DefaultOwnerIndex;
390 EndMem = (PVOID)((ULONG_PTR)EndMem + RtlLengthSid(AccessToken->UserAndGroups[PrimaryGroupIndex].Sid));
391
392 /*
393 * We have assigned a primary group and put it in the
394 * dynamic part, now it's time to copy the provided
395 * default DACL (if it's provided to begin with) into
396 * the DACL field of the token and put it at the end
397 * tail of the dynamic part too.
398 */
399 if (DefaultDacl != NULL)
400 {
401 AccessToken->DefaultDacl = EndMem;
402
403 RtlCopyMemory(EndMem,
404 DefaultDacl,
405 DefaultDacl->AclSize);
406 }
407
408 /* Insert the token only if it's not the system token, otherwise return it directly */
409 if (!SystemToken)
410 {
411 Status = ObInsertObject(AccessToken,
412 NULL,
414 0,
415 NULL,
417 if (!NT_SUCCESS(Status))
418 {
419 DPRINT1("ObInsertObject() failed (Status 0x%lx)\n", Status);
420 }
421 }
422 else
423 {
424 /* Return pointer instead of handle */
425 *TokenHandle = (HANDLE)AccessToken;
426 }
427
428Quit:
429 if (!NT_SUCCESS(Status))
430 {
431 /* Dereference the token, the delete procedure will clean it up */
432 ObDereferenceObject(AccessToken);
433 }
434
435 return Status;
436}
#define ULONG_PTR
Definition: config.h:101
PsGetCurrentThreadId
Definition: CrNtStubs.h:8
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
if(dx< 0)
Definition: linetemp.h:194
#define min(a, b)
Definition: monoChain.cc:55
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:726
NTSYSAPI NTSTATUS NTAPI RtlCopySidAndAttributesArray(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src, _In_ ULONG SidAreaSize, _In_ PSID_AND_ATTRIBUTES Dest, _In_ PSID SidArea, _Out_ PSID *RemainingSidArea, _Out_ PULONG RemainingSidAreaSize)
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:411
VOID NTAPI ExAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
Definition: uuid.c:335
EPROCESS KiInitialProcess
Definition: krnlinit.c:45
NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken(_Inout_ PTOKEN Token)
Inserts a logon session into an access token specified by the caller.
Definition: srm.c:368
NTSTATUS SepFindPrimaryGroupAndDefaultOwner(_In_ PTOKEN Token, _In_ PSID PrimaryGroup, _In_opt_ PSID DefaultOwner, _Out_opt_ PULONG PrimaryGroupIndex, _Out_opt_ PULONG DefaultOwnerIndex)
Finds the primary group and default owner entity based on the submitted primary group instance and an...
Definition: token.c:1011
NTSTATUS SepCreateTokenLock(_Inout_ PTOKEN Token)
Creates a lock for the token.
Definition: token.c:45
#define TOKEN_CREATE_METHOD
Definition: se.h:80
VOID SepUpdatePrivilegeFlagsToken(_Inout_ PTOKEN Token)
Updates the token's flags based upon the privilege that the token has been granted....
Definition: token.c:554
NTSTATUS SepRmReferenceLogonSession(_Inout_ PLUID LogonLuid)
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
CCHAR SourceName[TOKEN_SOURCE_LENGTH]
Definition: imports.h:278
LUID SourceIdentifier
Definition: imports.h:279
ULONG DynamicCharged
Definition: setypes.h:230
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:240
LUID ModifiedId
Definition: setypes.h:224
ULONG DefaultOwnerIndex
Definition: setypes.h:232
LARGE_INTEGER ExpirationTime
Definition: setypes.h:221
ULONG VariablePart
Definition: setypes.h:253
ULONG PrivilegeCount
Definition: setypes.h:228
PLUID_AND_ATTRIBUTES Privileges
Definition: setypes.h:236
PSID_AND_ATTRIBUTES UserAndGroups
Definition: setypes.h:233
ULONG TokenFlags
Definition: setypes.h:241
ULONG DynamicAvailable
Definition: setypes.h:231
ULONG VariableLength
Definition: setypes.h:229
PACL DefaultDacl
Definition: setypes.h:238
PSID PrimaryGroup
Definition: setypes.h:235
PULONG DynamicPart
Definition: setypes.h:237
ULONG UserAndGroupCount
Definition: setypes.h:226
TOKEN_SOURCE TokenSource
Definition: setypes.h:217
#define TAG_TOKEN_DYNAMIC
Definition: tag.h:158
#define SE_TOKEN_DYNAMIC_SLIM
Definition: tokenlif.c:17
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1184
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
@ TokenSource
Definition: setypes.h:972
#define TOKEN_HAS_ADMIN_GROUP
Definition: setypes.h:1182

Referenced by NtCreateToken(), SepCreateSystemAnonymousLogonToken(), SepCreateSystemAnonymousLogonTokenNoEveryone(), and SepCreateSystemProcessToken().

◆ SepCreateTokenLock()

NTSTATUS SepCreateTokenLock ( _Inout_ PTOKEN  Token)

Creates a lock for the token.

Parameters
[in,out]TokenA token which lock has to be created.
Returns
STATUS_SUCCESS if the pool allocation and resource initialisation have completed successfully, otherwise STATUS_INSUFFICIENT_RESOURCES on a pool allocation failure.

Definition at line 45 of file token.c.

47{
48 PAGED_CODE();
49
51 sizeof(ERESOURCE),
53 if (Token->TokenLock == NULL)
54 {
55 DPRINT1("SepCreateTokenLock(): Failed to allocate memory!\n");
57 }
58
60 return STATUS_SUCCESS;
61}
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define TAG_SE_TOKEN_LOCK
Definition: tag.h:162

Referenced by SepCreateToken(), SepDuplicateToken(), and SepPerformTokenFiltering().

◆ SepDeleteTokenLock()

VOID SepDeleteTokenLock ( _Inout_ PTOKEN  Token)

Deletes a lock of a token.

Parameters
[in,out]TokenA token which contains the lock.
Returns
Nothing.

Definition at line 74 of file token.c.

76{
77 PAGED_CODE();
78
79 ExDeleteResourceLite(Token->TokenLock);
81}
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647

Referenced by SepDeleteToken().

◆ SepDuplicateToken()

NTSTATUS NTAPI SepDuplicateToken ( _In_ PTOKEN  Token,
_In_opt_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ BOOLEAN  EffectiveOnly,
_In_ TOKEN_TYPE  TokenType,
_In_ SECURITY_IMPERSONATION_LEVEL  Level,
_In_ KPROCESSOR_MODE  PreviousMode,
_Out_ PTOKEN NewAccessToken 
)

Duplicates an access token, from an existing valid token.

Parameters
[in]TokenAccess token to duplicate.
[in]ObjectAttributesObject attributes for the new token.
[in]EffectiveOnlyIf set to TRUE, the function removes all the disabled privileges and groups of the token to duplicate.
[in]TokenTypeType of token.
[in]LevelSecurity impersonation level of a token.
[in]PreviousModeThe processor request level mode.
[out]NewAccessTokenThe duplicated token.
Returns
Returns STATUS_SUCCESS if the token has been duplicated. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation of the dynamic part of the token for duplication has failed due to the lack of memory resources. A failure NTSTATUS code is returned otherwise.

Definition at line 471 of file tokenlif.c.

479{
481 PTOKEN AccessToken;
482 PVOID EndMem;
483 ULONG PrimaryGroupIndex;
484 ULONG VariableLength;
485 ULONG DynamicPartSize, TotalSize;
486 ULONG PrivilegesIndex, GroupsIndex;
487
488 PAGED_CODE();
489
490 /* Compute how much size we need to allocate for the token */
491 VariableLength = Token->VariableLength;
492 TotalSize = FIELD_OFFSET(TOKEN, VariablePart) + VariableLength;
493
494 /*
495 * Compute how much size we need to allocate
496 * the dynamic part of the newly duplicated
497 * token.
498 */
499 DynamicPartSize = Token->DefaultDacl ? Token->DefaultDacl->AclSize : 0;
500 DynamicPartSize += RtlLengthSid(Token->PrimaryGroup);
501
506 NULL,
507 TotalSize,
508 Token->DynamicCharged,
509 TotalSize,
510 (PVOID*)&AccessToken);
511 if (!NT_SUCCESS(Status))
512 {
513 DPRINT1("ObCreateObject() failed (Status 0x%lx)\n", Status);
514 return Status;
515 }
516
517 /* Zero out the buffer and initialize the token */
518 RtlZeroMemory(AccessToken, TotalSize);
519
520 ExAllocateLocallyUniqueId(&AccessToken->TokenId);
521
522 AccessToken->TokenType = TokenType;
523 AccessToken->ImpersonationLevel = Level;
524
525 /* Initialise the lock for the access token */
526 Status = SepCreateTokenLock(AccessToken);
527 if (!NT_SUCCESS(Status))
528 {
529 ObDereferenceObject(AccessToken);
530 return Status;
531 }
532
533 /* Copy the immutable fields */
534 AccessToken->TokenSource.SourceIdentifier = Token->TokenSource.SourceIdentifier;
536 Token->TokenSource.SourceName,
537 sizeof(Token->TokenSource.SourceName));
538
539 AccessToken->AuthenticationId = Token->AuthenticationId;
540 AccessToken->ParentTokenId = Token->ParentTokenId;
541 AccessToken->ExpirationTime = Token->ExpirationTime;
542 AccessToken->OriginatingLogonSession = Token->OriginatingLogonSession;
543 AccessToken->DynamicCharged = Token->DynamicCharged;
544
545 /* Lock the source token and copy the mutable fields */
547
548 AccessToken->SessionId = Token->SessionId;
549 AccessToken->ModifiedId = Token->ModifiedId;
550
551 AccessToken->TokenFlags = Token->TokenFlags & ~TOKEN_SESSION_NOT_REFERENCED;
552
553 /* Reference the logon session */
555 if (!NT_SUCCESS(Status))
556 {
557 /* No logon session could be found, bail out */
558 DPRINT1("SepRmReferenceLogonSession() failed (Status 0x%lx)\n", Status);
559 /* Set the flag for proper cleanup by the delete procedure */
561 goto Quit;
562 }
563
564 /* Insert the referenced logon session into the token */
566 if (!NT_SUCCESS(Status))
567 {
568 /* Failed to insert the logon session into the token, bail out */
569 DPRINT1("SepRmInsertLogonSessionIntoToken() failed (Status 0x%lx)\n", Status);
570 goto Quit;
571 }
572
573 /* Fill in token debug information */
574#if DBG
575 RtlCopyMemory(AccessToken->ImageFileName,
576 PsGetCurrentProcess()->ImageFileName,
577 min(sizeof(AccessToken->ImageFileName), sizeof(PsGetCurrentProcess()->ImageFileName)));
578
579 AccessToken->ProcessCid = PsGetCurrentProcessId();
580 AccessToken->ThreadCid = PsGetCurrentThreadId();
581 AccessToken->CreateMethod = TOKEN_DUPLICATE_METHOD;
582#endif
583
584 /* Assign the data that reside in the token's variable information area */
585 AccessToken->VariableLength = VariableLength;
586 EndMem = (PVOID)&AccessToken->VariablePart;
587
588 /* Copy the privileges */
589 AccessToken->PrivilegeCount = 0;
590 AccessToken->Privileges = NULL;
591 if (Token->Privileges && (Token->PrivilegeCount > 0))
592 {
593 ULONG PrivilegesLength = Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
594 PrivilegesLength = ALIGN_UP_BY(PrivilegesLength, sizeof(PVOID));
595
596 ASSERT(VariableLength >= PrivilegesLength);
597
598 AccessToken->PrivilegeCount = Token->PrivilegeCount;
599 AccessToken->Privileges = EndMem;
600 EndMem = (PVOID)((ULONG_PTR)EndMem + PrivilegesLength);
601 VariableLength -= PrivilegesLength;
602
603 RtlCopyMemory(AccessToken->Privileges,
604 Token->Privileges,
605 AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
606 }
607
608 /* Copy the user and groups */
609 AccessToken->UserAndGroupCount = 0;
610 AccessToken->UserAndGroups = NULL;
611 if (Token->UserAndGroups && (Token->UserAndGroupCount > 0))
612 {
613 AccessToken->UserAndGroupCount = Token->UserAndGroupCount;
614 AccessToken->UserAndGroups = EndMem;
615 EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
616 VariableLength -= ((ULONG_PTR)EndMem - (ULONG_PTR)AccessToken->UserAndGroups);
617
619 Token->UserAndGroups,
620 VariableLength,
621 AccessToken->UserAndGroups,
622 EndMem,
623 &EndMem,
624 &VariableLength);
625 if (!NT_SUCCESS(Status))
626 {
627 DPRINT1("RtlCopySidAndAttributesArray(UserAndGroups) failed (Status 0x%lx)\n", Status);
628 goto Quit;
629 }
630 }
631
632 /* Find the token primary group */
634 Token->PrimaryGroup,
635 NULL,
636 &PrimaryGroupIndex,
637 NULL);
638 if (!NT_SUCCESS(Status))
639 {
640 DPRINT1("SepFindPrimaryGroupAndDefaultOwner failed (Status 0x%lx)\n", Status);
641 goto Quit;
642 }
643
644 /* Copy the restricted SIDs */
645 AccessToken->RestrictedSidCount = 0;
646 AccessToken->RestrictedSids = NULL;
647 if (Token->RestrictedSids && (Token->RestrictedSidCount > 0))
648 {
649 AccessToken->RestrictedSidCount = Token->RestrictedSidCount;
650 AccessToken->RestrictedSids = EndMem;
651 EndMem = &AccessToken->RestrictedSids[AccessToken->RestrictedSidCount];
652 VariableLength -= ((ULONG_PTR)EndMem - (ULONG_PTR)AccessToken->RestrictedSids);
653
655 Token->RestrictedSids,
656 VariableLength,
657 AccessToken->RestrictedSids,
658 EndMem,
659 &EndMem,
660 &VariableLength);
661 if (!NT_SUCCESS(Status))
662 {
663 DPRINT1("RtlCopySidAndAttributesArray(RestrictedSids) failed (Status 0x%lx)\n", Status);
664 goto Quit;
665 }
666 }
667
668 /* Now allocate the token's dynamic information area and set the data */
670 DynamicPartSize,
672 if (AccessToken->DynamicPart == NULL)
673 {
675 goto Quit;
676 }
677
678 /* Unused memory in the dynamic area */
679 AccessToken->DynamicAvailable = 0;
680
681 /*
682 * Assign the primary group to the token
683 * and put it in the dynamic part as well.
684 */
685 EndMem = (PVOID)AccessToken->DynamicPart;
686 AccessToken->PrimaryGroup = EndMem;
687 RtlCopySid(RtlLengthSid(AccessToken->UserAndGroups[PrimaryGroupIndex].Sid),
688 EndMem,
689 AccessToken->UserAndGroups[PrimaryGroupIndex].Sid);
690 AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex;
691 EndMem = (PVOID)((ULONG_PTR)EndMem + RtlLengthSid(AccessToken->UserAndGroups[PrimaryGroupIndex].Sid));
692
693 /*
694 * The existing token has a default DACL only
695 * if it has an allocated dynamic part.
696 */
697 if (Token->DynamicPart && Token->DefaultDacl)
698 {
699 AccessToken->DefaultDacl = EndMem;
700
701 RtlCopyMemory(EndMem,
702 Token->DefaultDacl,
703 Token->DefaultDacl->AclSize);
704 }
705
706 /*
707 * Filter the token by removing the disabled privileges
708 * and groups if the caller wants to duplicate an access
709 * token as effective only.
710 */
711 if (EffectiveOnly)
712 {
713 /*
714 * Begin querying the groups and search for disabled ones. Do not touch the
715 * user which is at the first position because it cannot be disabled, no
716 * matter what attributes it has.
717 */
718 for (GroupsIndex = 1; GroupsIndex < AccessToken->UserAndGroupCount; GroupsIndex++)
719 {
720 /*
721 * A group is considered disabled if its attributes is either
722 * 0 or SE_GROUP_ENABLED is not included in the attributes flags list.
723 * That is because a certain user and/or group can have several attributes
724 * that bear no influence on whether a user/group is enabled or not
725 * (SE_GROUP_ENABLED_BY_DEFAULT for example which is a mere indicator
726 * that the group has just been enabled by default). A mandatory
727 * group (that is, the group has SE_GROUP_MANDATORY attribute)
728 * by standards it's always enabled and no one can disable it.
729 */
730 if (AccessToken->UserAndGroups[GroupsIndex].Attributes == 0 ||
731 (AccessToken->UserAndGroups[GroupsIndex].Attributes & SE_GROUP_ENABLED) == 0)
732 {
733 /*
734 * If this group is an administrators group
735 * and the token belongs to such group,
736 * we've to take away TOKEN_HAS_ADMIN_GROUP
737 * for the fact that's not enabled and as
738 * such the token no longer belongs to
739 * this group.
740 */
742 &AccessToken->UserAndGroups[GroupsIndex].Sid))
743 {
744 AccessToken->TokenFlags &= ~TOKEN_HAS_ADMIN_GROUP;
745 }
746
747 /*
748 * A group is not enabled, it's time to remove
749 * from the token and update the groups index
750 * accordingly and continue with the next group.
751 */
752 SepRemoveUserGroupToken(AccessToken, GroupsIndex);
753 GroupsIndex--;
754 }
755 }
756
757 /* Begin querying the privileges and search for disabled ones */
758 for (PrivilegesIndex = 0; PrivilegesIndex < AccessToken->PrivilegeCount; PrivilegesIndex++)
759 {
760 /*
761 * A privilege is considered disabled if its attributes is either
762 * 0 or SE_PRIVILEGE_ENABLED is not included in the attributes flags list.
763 * That is because a certain privilege can have several attributes
764 * that bear no influence on whether a privilege is enabled or not
765 * (SE_PRIVILEGE_ENABLED_BY_DEFAULT for example which is a mere indicator
766 * that the privilege has just been enabled by default).
767 */
768 if (AccessToken->Privileges[PrivilegesIndex].Attributes == 0 ||
769 (AccessToken->Privileges[PrivilegesIndex].Attributes & SE_PRIVILEGE_ENABLED) == 0)
770 {
771 /*
772 * A privilege is not enabled, therefor it's time
773 * to strip it from the token and continue with the next
774 * privilege. Of course we must also want to update the
775 * privileges index accordingly.
776 */
777 SepRemovePrivilegeToken(AccessToken, PrivilegesIndex);
778 PrivilegesIndex--;
779 }
780 }
781 }
782
783 /* Return the token to the caller */
784 *NewAccessToken = AccessToken;
786
787Quit:
788 if (!NT_SUCCESS(Status))
789 {
790 /* Dereference the token, the delete procedure will clean it up */
791 ObDereferenceObject(AccessToken);
792 }
793
794 /* Unlock the source token */
796
797 return Status;
798}
VOID SepRemovePrivilegeToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a privilege from the token.
Definition: token.c:582
VOID SepRemoveUserGroupToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a group from the token.
Definition: token.c:618
#define TOKEN_DUPLICATE_METHOD
Definition: se.h:81
PSID_AND_ATTRIBUTES RestrictedSids
Definition: setypes.h:234
LUID OriginatingLogonSession
Definition: setypes.h:246
ULONG RestrictedSidCount
Definition: setypes.h:227

Referenced by NtDuplicateToken(), SeCopyClientToken(), SepOpenThreadToken(), and SeSubProcessToken().

◆ SepFindPrimaryGroupAndDefaultOwner()

NTSTATUS SepFindPrimaryGroupAndDefaultOwner ( _In_ PTOKEN  Token,
_In_ PSID  PrimaryGroup,
_In_opt_ PSID  DefaultOwner,
_Out_opt_ PULONG  PrimaryGroupIndex,
_Out_opt_ PULONG  DefaultOwnerIndex 
)

Finds the primary group and default owner entity based on the submitted primary group instance and an access token.

Parameters
[in]TokenAccess token to begin the search query of primary group and default owner.
[in]PrimaryGroupA primary group SID to be used for search query, determining if user & groups of a token and the submitted primary group do match.
[in]DefaultOwnerThe default owner. If specified, it's used to determine if the token belongs to the actual user, that is, being the owner himself.
[out]PrimaryGroupIndexReturns the primary group index.
[out]DefaultOwnerIndexReturns the default owner index.
Returns
Returns STATUS_SUCCESS if the find query operation has completed successfully and that at least one search result is requested by the caller. STATUS_INVALID_PARAMETER is returned if the caller hasn't requested any search result. STATUS_INVALID_OWNER is returned if the specified default user owner does not match with the other user from the token. STATUS_INVALID_PRIMARY_GROUP is returned if the specified default primary group does not match with the other group from the token.

Definition at line 1011 of file token.c.

1017{
1018 ULONG i;
1019
1020 /* We should return at least a search result */
1021 if (!PrimaryGroupIndex && !DefaultOwnerIndex)
1023
1024 if (PrimaryGroupIndex)
1025 {
1026 /* Initialize with an invalid index */
1027 // Token->PrimaryGroup = NULL;
1028 *PrimaryGroupIndex = Token->UserAndGroupCount;
1029 }
1030
1031 if (DefaultOwnerIndex)
1032 {
1033 if (DefaultOwner)
1034 {
1035 /* An owner is specified: check whether this is actually the user */
1036 if (RtlEqualSid(Token->UserAndGroups[0].Sid, DefaultOwner))
1037 {
1038 /*
1039 * It's the user (first element in array): set it
1040 * as the owner and stop the search for it.
1041 */
1042 *DefaultOwnerIndex = 0;
1043 DefaultOwnerIndex = NULL;
1044 }
1045 else
1046 {
1047 /* An owner is specified: initialize with an invalid index */
1048 *DefaultOwnerIndex = Token->UserAndGroupCount;
1049 }
1050 }
1051 else
1052 {
1053 /*
1054 * No owner specified: set the user (first element in array)
1055 * as the owner and stop the search for it.
1056 */
1057 *DefaultOwnerIndex = 0;
1058 DefaultOwnerIndex = NULL;
1059 }
1060 }
1061
1062 /* Validate and set the primary group and default owner indices */
1063 for (i = 0; i < Token->UserAndGroupCount; i++)
1064 {
1065 /* Stop the search if we have found what we searched for */
1066 if (!PrimaryGroupIndex && !DefaultOwnerIndex)
1067 break;
1068
1069 if (DefaultOwnerIndex && DefaultOwner &&
1070 RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner) &&
1071 (Token->UserAndGroups[i].Attributes & SE_GROUP_OWNER))
1072 {
1073 /* Owner is found, stop the search for it */
1074 *DefaultOwnerIndex = i;
1075 DefaultOwnerIndex = NULL;
1076 }
1077
1078 if (PrimaryGroupIndex &&
1079 RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup))
1080 {
1081 /* Primary group is found, stop the search for it */
1082 // Token->PrimaryGroup = Token->UserAndGroups[i].Sid;
1083 *PrimaryGroupIndex = i;
1084 PrimaryGroupIndex = NULL;
1085 }
1086 }
1087
1088 if (DefaultOwnerIndex)
1089 {
1090 if (*DefaultOwnerIndex == Token->UserAndGroupCount)
1091 return STATUS_INVALID_OWNER;
1092 }
1093
1094 if (PrimaryGroupIndex)
1095 {
1096 if (*PrimaryGroupIndex == Token->UserAndGroupCount)
1097 // if (Token->PrimaryGroup == NULL)
1099 }
1100
1101 return STATUS_SUCCESS;
1102}
#define STATUS_INVALID_PRIMARY_GROUP
Definition: ntstatus.h:327
#define STATUS_INVALID_OWNER
Definition: ntstatus.h:326

Referenced by NtSetInformationToken(), SepCreateToken(), SepDuplicateToken(), and SepPerformTokenFiltering().

◆ SepGetDaclFromDescriptor()

FORCEINLINE PACL SepGetDaclFromDescriptor ( _Inout_ PSECURITY_DESCRIPTOR  _Descriptor)

Definition at line 129 of file se.h.

131{
134
135 if (!(Descriptor->Control & SE_DACL_PRESENT)) return NULL;
136
137 if (Descriptor->Control & SE_SELF_RELATIVE)
138 {
140 if (!SdRel->Dacl) return NULL;
141 return (PACL)((ULONG_PTR)Descriptor + SdRel->Dacl);
142 }
143 else
144 {
145 return Descriptor->Dacl;
146 }
147}
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
struct _SECURITY_DESCRIPTOR_RELATIVE * PISECURITY_DESCRIPTOR_RELATIVE
struct _SECURITY_DESCRIPTOR * PISECURITY_DESCRIPTOR
#define SE_SELF_RELATIVE
Definition: setypes.h:834
#define SE_DACL_PRESENT
Definition: setypes.h:821

Referenced by _IRQL_requires_max_(), RtlGetDaclSecurityDescriptor(), RtlLengthSecurityDescriptor(), RtlpQuerySecurityDescriptor(), RtlValidSecurityDescriptor(), SeCaptureSecurityDescriptor(), SeFastTraverseCheck(), and SepDumpSdDebugInfo().

◆ SepGetGroupFromDescriptor()

◆ SepGetObjectTypeGuidFromAce()

PGUID SepGetObjectTypeGuidFromAce ( _In_ PACE  Ace,
_In_ BOOLEAN  IsAceDenied 
)

Captures an object type GUID from an object access control entry (ACE).

Parameters
[in]AceA pointer to an access control entry, of which the object type GUID is to be captured from.
[in]IsAceDeniedIf set to TRUE, the function will capture the GUID from a denied object ACE, otherwise from the allowed object ACE.
Returns
Returns a pointer to an object type GUID, otherwise NULL is returned if the target ACE does not have an object type GUID.

Definition at line 180 of file objtype.c.

183{
184 PGUID ObjectTypeGuid = NULL;
185
186 PAGED_CODE();
187
188 /* This Ace must not be NULL */
189 ASSERT(Ace);
190
191 /* Grab the GUID based on the object type ACE header */
192 ObjectTypeGuid = IsAceDenied ? (PGUID)&((PACCESS_DENIED_OBJECT_ACE)Ace)->ObjectType :
193 (PGUID)&((PACCESS_ALLOWED_OBJECT_ACE)Ace)->ObjectType;
194 return ObjectTypeGuid;
195}
GUID * PGUID
Definition: bdasup.h:12
ObjectType
Definition: metafile.c:81
struct _ACCESS_ALLOWED_OBJECT_ACE * PACCESS_ALLOWED_OBJECT_ACE

Referenced by SepAnalyzeAcesFromDacl().

◆ SepGetOwnerFromDescriptor()

◆ SepGetSaclFromDescriptor()

FORCEINLINE PACL SepGetSaclFromDescriptor ( _Inout_ PSECURITY_DESCRIPTOR  _Descriptor)

Definition at line 151 of file se.h.

153{
156
157 if (!(Descriptor->Control & SE_SACL_PRESENT)) return NULL;
158
159 if (Descriptor->Control & SE_SELF_RELATIVE)
160 {
162 if (!SdRel->Sacl) return NULL;
163 return (PACL)((ULONG_PTR)Descriptor + SdRel->Sacl);
164 }
165 else
166 {
167 return Descriptor->Sacl;
168 }
169}
#define SE_SACL_PRESENT
Definition: setypes.h:823

Referenced by _IRQL_requires_max_(), RtlGetSaclSecurityDescriptor(), RtlLengthSecurityDescriptor(), RtlpQuerySecurityDescriptor(), RtlValidSecurityDescriptor(), SeCaptureSecurityDescriptor(), and SepDumpSdDebugInfo().

◆ SepGetSidFromAce()

PSID NTAPI SepGetSidFromAce ( _In_ PACE  Ace)

Captures a security identifier from a given access control entry. This identifier is valid for the whole of its lifetime.

Parameters
[in]AceA pointer to an access control entry, which can be obtained from a DACL.
Returns
Returns a pointer to a security identifier (SID), otherwise NULL is returned if an unsupported ACE type was given to the function.

Definition at line 572 of file sid.c.

574{
576 ULONG GuidSize = 0;
577 PSID Sid = NULL;
578 PAGED_CODE();
579
580 /* Sanity check */
581 ASSERT(Ace);
582
583 /* Obtain the SID based upon ACE type */
584 switch (Ace->Header.AceType)
585 {
590 {
591 Sid = (PSID)&((PKNOWN_ACE)Ace)->SidStart;
592 break;
593 }
594
597 {
600 {
601 GuidSize += sizeof(GUID);
602 }
603
605 {
606 GuidSize += sizeof(GUID);
607 }
608
609 Sid = (PSID)((ULONG_PTR)&((PKNOWN_OBJECT_ACE)Ace)->SidStart + GuidSize);
610 break;
611 }
612
613 default:
614 {
615 DPRINT1("SepGetSidFromAce(): Unknown ACE type (Ace 0x%p, Type %u)\n", Ace, Ace->Header.AceType);
616 break;
617 }
618 }
619
620 return Sid;
621}
struct _KNOWN_OBJECT_ACE * PKNOWN_OBJECT_ACE
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ACE_INHERITED_OBJECT_TYPE_PRESENT
Definition: setypes.h:806
#define ACCESS_DENIED_OBJECT_ACE_TYPE
Definition: setypes.h:726
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:719
#define SYSTEM_ALARM_ACE_TYPE
Definition: setypes.h:720
#define ACE_OBJECT_TYPE_PRESENT
Definition: setypes.h:805
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE
Definition: setypes.h:725

Referenced by SepAnalyzeAcesFromDacl().

◆ SepInitDACLs()

BOOLEAN NTAPI SepInitDACLs ( VOID  )

Initializes known discretionary access control lists in the system upon kernel and Executive initialization procedure.

Returns
Returns TRUE if all the DACLs have been successfully initialized, FALSE otherwise.

Definition at line 38 of file acl.c.

39{
41
42 /* create PublicDefaultDacl */
43 AclLength = sizeof(ACL) +
44 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
45 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
47
50 TAG_ACL);
52 return FALSE;
53
57
62
67
72
73 /* create PublicDefaultUnrestrictedDacl */
74 AclLength = sizeof(ACL) +
75 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
76 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
77 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
79
82 TAG_ACL);
84 return FALSE;
85
89
94
99
104
109
110 /* create PublicOpenDacl */
111 AclLength = sizeof(ACL) +
112 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
113 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
114 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
115
117 AclLength,
118 TAG_ACL);
119 if (SePublicOpenDacl == NULL)
120 return FALSE;
121
123 AclLength,
125
129 SeWorldSid);
130
135
140
141 /* create PublicOpenUnrestrictedDacl */
142 AclLength = sizeof(ACL) +
143 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
144 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
145 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
147
149 AclLength,
150 TAG_ACL);
152 return FALSE;
153
155 AclLength,
157
161 SeWorldSid);
162
167
172
177
178 /* create SystemDefaultDacl */
179 AclLength = sizeof(ACL) +
180 (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
181 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
182
184 AclLength,
185 TAG_ACL);
187 return FALSE;
188
190 AclLength,
192
197
202
203 /* create UnrestrictedDacl */
204 AclLength = sizeof(ACL) +
205 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
207
209 AclLength,
210 TAG_ACL);
212 return FALSE;
213
215 AclLength,
217
221 SeWorldSid);
222
227
228 /* create SystemAnonymousLogonDacl */
229 AclLength = sizeof(ACL) +
230 (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
232
234 AclLength,
235 TAG_ACL);
237 return FALSE;
238
240 AclLength,
242
246 SeWorldSid);
247
252
253 return TRUE;
254}
#define GENERIC_READ
Definition: compat.h:135
#define READ_CONTROL
Definition: nt_native.h:58
#define GENERIC_WRITE
Definition: nt_native.h:90
#define GENERIC_EXECUTE
Definition: nt_native.h:91
PACL SePublicOpenDacl
Definition: acl.c:19
PACL SePublicDefaultUnrestrictedDacl
Definition: acl.c:18
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
PACL SePublicOpenUnrestrictedDacl
Definition: acl.c:20
PACL SeUnrestrictedDacl
Definition: acl.c:21
PACL SePublicDefaultDacl
Definition: acl.c:16

Referenced by SepInitializationPhase0().

◆ SepInitializeTokenImplementation()

VOID NTAPI SepInitializeTokenImplementation ( VOID  )

Internal function that initializes critical kernel data for access token implementation in SRM.

Returns
Nothing.

Definition at line 1649 of file token.c.

1650{
1652 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1653
1654 DPRINT("Creating Token Object Type\n");
1655
1656 /* Initialize the Token type */
1657 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
1658 RtlInitUnicodeString(&Name, L"Token");
1659 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
1660 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
1661 ObjectTypeInitializer.SecurityRequired = TRUE;
1662 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(TOKEN);
1663 ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1664 ObjectTypeInitializer.PoolType = PagedPool;
1665 ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1666 ObjectTypeInitializer.UseDefaultObject = TRUE;
1667 ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1668 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1669}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define OBJ_OPENLINK
Definition: winternl.h:230
struct _TOKEN TOKEN
VOID NTAPI SepDeleteToken(_In_ PVOID ObjectBody)
Internal function that deals with access token object destruction and deletion. The function is used ...
Definition: token.c:1605
static GENERIC_MAPPING SepTokenMapping
Definition: token.c:23
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
#define DPRINT
Definition: sndvol32.h:71
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
#define TOKEN_ALL_ACCESS
Definition: setypes.h:946

Referenced by SepInitializationPhase0().

◆ 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().

◆ SepInitSDs()

BOOLEAN NTAPI SepInitSDs ( VOID  )

Initializes the known security descriptors in the system.

Returns
Returns TRUE if all the security descriptors have been initialized, FALSE otherwise.

Definition at line 37 of file sd.c.

38{
39 /* Create PublicDefaultSd */
43 return FALSE;
44
48 TRUE,
50 FALSE);
51
52 /* Create PublicDefaultUnrestrictedSd */
56 return FALSE;
57
61 TRUE,
63 FALSE);
64
65 /* Create PublicOpenSd */
68 if (SePublicOpenSd == NULL)
69 return FALSE;
70
74 TRUE,
76 FALSE);
77
78 /* Create PublicOpenUnrestrictedSd */
82 return FALSE;
83
87 TRUE,
89 FALSE);
90
91 /* Create SystemDefaultSd */
95 return FALSE;
96
100 TRUE,
102 FALSE);
103
104 /* Create UnrestrictedSd */
106 sizeof(SECURITY_DESCRIPTOR), TAG_SD);
107 if (SeUnrestrictedSd == NULL)
108 return FALSE;
109
113 TRUE,
115 FALSE);
116
117 /* Create SystemAnonymousLogonSd */
119 sizeof(SECURITY_DESCRIPTOR), TAG_SD);
121 return FALSE;
122
126 TRUE,
128 FALSE);
129
130 return TRUE;
131}
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
PACL SePublicOpenDacl
Definition: acl.c:19
PACL SePublicDefaultUnrestrictedDacl
Definition: acl.c:18
PACL SePublicOpenUnrestrictedDacl
Definition: acl.c:20
PACL SeUnrestrictedDacl
Definition: acl.c:21
PSECURITY_DESCRIPTOR SeSystemDefaultSd
Definition: sd.c:20
PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
Definition: sd.c:19
PSECURITY_DESCRIPTOR SePublicOpenSd
Definition: sd.c:18
PSECURITY_DESCRIPTOR SeUnrestrictedSd
Definition: sd.c:21
PSECURITY_DESCRIPTOR SePublicDefaultSd
Definition: sd.c:16
PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd
Definition: sd.c:22
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
Definition: sd.c:17
#define TAG_SD
Definition: tag.h:153
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58

Referenced by SepInitializationPhase0().

◆ SepInitSecurityIDs()

BOOLEAN NTAPI SepInitSecurityIDs ( VOID  )

Initializes all the SIDs known in the system.

Returns
Returns TRUE if all the SIDs have been initialized, FALSE otherwise.

Definition at line 115 of file sid.c.

116{
117 ULONG SidLength0;
118 ULONG SidLength1;
119 ULONG SidLength2;
120 PULONG SubAuthority;
121
122 SidLength0 = RtlLengthRequiredSid(0);
123 SidLength1 = RtlLengthRequiredSid(1);
124 SidLength2 = RtlLengthRequiredSid(2);
125
126 /* create NullSid */
157
158 if (SeNullSid == NULL || SeWorldSid == NULL ||
173 {
175 return FALSE;
176 }
177
208
209 SubAuthority = RtlSubAuthoritySid(SeNullSid, 0);
210 *SubAuthority = SECURITY_NULL_RID;
211 SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0);
212 *SubAuthority = SECURITY_WORLD_RID;
213 SubAuthority = RtlSubAuthoritySid(SeLocalSid, 0);
214 *SubAuthority = SECURITY_LOCAL_RID;
215 SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid, 0);
216 *SubAuthority = SECURITY_CREATOR_OWNER_RID;
217 SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid, 0);
218 *SubAuthority = SECURITY_CREATOR_GROUP_RID;
220 *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID;
222 *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID;
223 SubAuthority = RtlSubAuthoritySid(SeDialupSid, 0);
224 *SubAuthority = SECURITY_DIALUP_RID;
225 SubAuthority = RtlSubAuthoritySid(SeNetworkSid, 0);
226 *SubAuthority = SECURITY_NETWORK_RID;
227 SubAuthority = RtlSubAuthoritySid(SeBatchSid, 0);
228 *SubAuthority = SECURITY_BATCH_RID;
229 SubAuthority = RtlSubAuthoritySid(SeInteractiveSid, 0);
230 *SubAuthority = SECURITY_INTERACTIVE_RID;
231 SubAuthority = RtlSubAuthoritySid(SeServiceSid, 0);
232 *SubAuthority = SECURITY_SERVICE_RID;
233 SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid, 0);
234 *SubAuthority = SECURITY_PRINCIPAL_SELF_RID;
235 SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid, 0);
236 *SubAuthority = SECURITY_LOCAL_SYSTEM_RID;
238 *SubAuthority = SECURITY_AUTHENTICATED_USER_RID;
239 SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid, 0);
240 *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
241 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 0);
242 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
243 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 1);
244 *SubAuthority = DOMAIN_ALIAS_RID_ADMINS;
245 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 0);
246 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
247 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 1);
248 *SubAuthority = DOMAIN_ALIAS_RID_USERS;
249 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 0);
250 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
251 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 1);
252 *SubAuthority = DOMAIN_ALIAS_RID_GUESTS;
253 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 0);
254 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
255 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 1);
256 *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS;
257 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 0);
258 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
259 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 1);
260 *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
261 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 0);
262 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
263 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 1);
264 *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS;
265 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 0);
266 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
267 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 1);
268 *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS;
269 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 0);
270 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
271 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 1);
272 *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS;
274 *SubAuthority = SECURITY_AUTHENTICATED_USER_RID;
275 SubAuthority = RtlSubAuthoritySid(SeRestrictedSid, 0);
276 *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
277 SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0);
278 *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID;
279 SubAuthority = RtlSubAuthoritySid(SeLocalServiceSid, 0);
280 *SubAuthority = SECURITY_LOCAL_SERVICE_RID;
281 SubAuthority = RtlSubAuthoritySid(SeNetworkServiceSid, 0);
282 *SubAuthority = SECURITY_NETWORK_SERVICE_RID;
283
284 return TRUE;
285}
NTSYSAPI PULONG NTAPI RtlSubAuthoritySid(_In_ PSID Sid, _In_ ULONG SubAuthority)
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
PSID SeLocalSystemSid
Definition: sid.c:38
SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority
Definition: sid.c:21
PSID SeAliasAccountOpsSid
Definition: sid.c:45
PSID SeRestrictedSid
Definition: sid.c:50
SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority
Definition: sid.c:19
PSID SeNetworkServiceSid
Definition: sid.c:53
PSID SeBatchSid
Definition: sid.c:34
PSID SeCreatorOwnerServerSid
Definition: sid.c:29
PSID SeAliasAdminsSid
Definition: sid.c:41
PSID SeAnonymousLogonSid
Definition: sid.c:51
PSID SeRestrictedCodeSid
Definition: sid.c:40
PSID SeAliasPowerUsersSid
Definition: sid.c:44
PSID SeInteractiveSid
Definition: sid.c:35
PSID SeWorldSid
Definition: sid.c:25
PSID SeAuthenticatedUserSid
Definition: sid.c:39
PSID SeServiceSid
Definition: sid.c:36
PSID SeNetworkSid
Definition: sid.c:33
PSID SeCreatorGroupSid
Definition: sid.c:28
VOID NTAPI FreeInitializedSids(VOID)
Frees all the known initialized SIDs in the system from the memory.
Definition: sid.c:72
PSID SeNtAuthoritySid
Definition: sid.c:31
SID_IDENTIFIER_AUTHORITY SeNullSidAuthority
Definition: sid.c:18
PSID SeCreatorGroupServerSid
Definition: sid.c:30
SID_IDENTIFIER_AUTHORITY SeNtSidAuthority
Definition: sid.c:22
PSID SeLocalSid
Definition: sid.c:26
PSID SeDialupSid
Definition: sid.c:32
PSID SeCreatorOwnerSid
Definition: sid.c:27
SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority
Definition: sid.c:20
PSID SeAliasUsersSid
Definition: sid.c:42
PSID SeAliasBackupOpsSid
Definition: sid.c:48
PSID SeAuthenticatedUsersSid
Definition: sid.c:49
PSID SeAliasGuestsSid
Definition: sid.c:43
PSID SeAliasSystemOpsSid
Definition: sid.c:46
PSID SeAliasPrintOpsSid
Definition: sid.c:47
PSID SePrincipalSelfSid
Definition: sid.c:37
PSID SeLocalServiceSid
Definition: sid.c:52
PSID SeNullSid
Definition: sid.c:24
#define SECURITY_ANONYMOUS_LOGON_RID
Definition: setypes.h:563
#define DOMAIN_ALIAS_RID_USERS
Definition: setypes.h:653
#define DOMAIN_ALIAS_RID_GUESTS
Definition: setypes.h:654
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_LOCAL_RID
Definition: setypes.h:542
#define SECURITY_DIALUP_RID
Definition: setypes.h:556
#define SECURITY_SERVICE_RID
Definition: setypes.h:562
#define SECURITY_INTERACTIVE_RID
Definition: setypes.h:559
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_CREATOR_GROUP_SERVER_RID
Definition: setypes.h:548
#define DOMAIN_ALIAS_RID_SYSTEM_OPS
Definition: setypes.h:658
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define SECURITY_AUTHENTICATED_USER_RID
Definition: setypes.h:568
#define SECURITY_NULL_RID
Definition: setypes.h:540
#define DOMAIN_ALIAS_RID_ACCOUNT_OPS
Definition: setypes.h:657
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:569
#define DOMAIN_ALIAS_RID_BACKUP_OPS
Definition: setypes.h:660
#define SECURITY_BATCH_RID
Definition: setypes.h:558
#define DOMAIN_ALIAS_RID_PRINT_OPS
Definition: setypes.h:659
#define SECURITY_CREATOR_OWNER_SERVER_RID
Definition: setypes.h:547
#define SECURITY_LOCAL_SERVICE_RID
Definition: setypes.h:575
#define SECURITY_PRINCIPAL_SELF_RID
Definition: setypes.h:567
#define SECURITY_CREATOR_OWNER_RID
Definition: setypes.h:545
#define DOMAIN_ALIAS_RID_POWER_USERS
Definition: setypes.h:655
#define SECURITY_NETWORK_RID
Definition: setypes.h:557
#define SECURITY_NETWORK_SERVICE_RID
Definition: setypes.h:576
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
#define SECURITY_CREATOR_GROUP_RID
Definition: setypes.h:546

Referenced by SepInitializationPhase0().

◆ SepObjectTypeGuidInList()

BOOLEAN SepObjectTypeGuidInList ( _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST_INTERNAL  ObjectTypeList,
_In_ ULONG  ObjectTypeListLength,
_In_ PGUID  ObjectTypeGuid,
_Out_ PULONG  ObjectIndex 
)

Searches for an object type GUID if it exists on an object type list.

Parameters
[in]ObjectTypeListA pointer to an object type list.
[in]ObjectTypeListLengthThe length of the list, representing the number of object elements in that list.
[in]ObjectTypeGuidA pointer to an object type GUID to search in the list of interest.
[out]ObjectIndexIf the function found the target GUID, the function returns a pointer to the object index location to this parameter.
Returns
Returns TRUE if the object type GUID of interest exists in the target list, FALSE otherwise.

Definition at line 223 of file objtype.c.

228{
229 ULONG ObjectTypeIndex;
230 GUID ObjectTypeGuidToSearch;
231
232 PAGED_CODE();
233
234 /* Loop over the object elements */
235 for (ObjectTypeIndex = 0;
236 ObjectTypeIndex < ObjectTypeListLength;
237 ObjectTypeIndex++)
238 {
239 /* Is this the object we are searching for? */
240 ObjectTypeGuidToSearch = ObjectTypeList[ObjectTypeIndex].ObjectTypeGuid;
241 if (SepIsEqualObjectTypeGuid(ObjectTypeGuid, &ObjectTypeGuidToSearch))
242 {
243 /* Return the indext of that object to caller */
244 *ObjectIndex = ObjectTypeIndex;
245 return TRUE;
246 }
247 }
248
249 return FALSE;
250}
static BOOLEAN SepIsEqualObjectTypeGuid(_In_ CONST GUID *Guid1, _In_ CONST GUID *Guid2)
Compares two object type GUIDs for equality.
Definition: objtype.c:151

Referenced by SepAllowAccessObjectTypeList(), SepAllowAccessObjectTypeResultList(), SepDenyAccessObjectTypeList(), and SepDenyAccessObjectTypeResultList().

◆ 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;
114
115 DPRINT("SepPrivilegeCheck() called\n");
116
117 PAGED_CODE();
118
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}
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_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN _Inout_ PMM_REQUIRED_RESOURCES Required
Definition: newmm.h:210
#define SE_PRIVILEGE_USED_FOR_ACCESS
Definition: setypes.h:65

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

◆ SepPropagateAcl()

NTSTATUS SepPropagateAcl ( _Out_writes_bytes_opt_(DaclLength) PACL  AclDest,
_Inout_ PULONG  AclLength,
_In_reads_bytes_(AclSource->AclSize) PACL  AclSource,
_In_ PSID  Owner,
_In_ PSID  Group,
_In_ BOOLEAN  IsInherited,
_In_ BOOLEAN  IsDirectoryObject,
_In_ PGENERIC_MAPPING  GenericMapping 
)

◆ SepRebuildDynamicPartOfToken()

NTSTATUS SepRebuildDynamicPartOfToken ( _In_ PTOKEN  Token,
_In_ ULONG  NewDynamicPartSize 
)

Referenced by NtSetInformationToken().

◆ SepRegQueryHelper()

NTSTATUS NTAPI SepRegQueryHelper ( _In_ PCWSTR  KeyName,
_In_ PCWSTR  ValueName,
_In_ ULONG  ValueType,
_In_ ULONG  DataLength,
_Out_ PVOID  ValueData 
)

A private registry helper that returns the desired value data based on the specifics requested by the caller.

Parameters
[in]KeyNameName of the key.
[in]ValueNameName of the registry value.
[in]ValueTypeThe type of the registry value.
[in]DataLengthThe data length, in bytes, representing the size of the registry value.
[out]ValueDataThe requested value data provided by the function.
Returns
Returns STATUS_SUCCESS if the operations have completed successfully, otherwise a failure NTSTATUS code is returned.

Definition at line 93 of file srm.c.

99{
100 UNICODE_STRING ValueNameString;
101 UNICODE_STRING KeyNameString;
105 struct
106 {
108 UCHAR Buffer[64];
109 } KeyValueInformation;
110 NTSTATUS Status, CloseStatus;
111 PAGED_CODE();
112
113 RtlInitUnicodeString(&KeyNameString, KeyName);
115 &KeyNameString,
117 NULL,
118 NULL);
119
121 if (!NT_SUCCESS(Status))
122 {
123 return Status;
124 }
125
126 RtlInitUnicodeString(&ValueNameString, ValueName);
127 Status = ZwQueryValueKey(KeyHandle,
128 &ValueNameString,
130 &KeyValueInformation.Partial,
131 sizeof(KeyValueInformation),
132 &ResultLength);
133 if (!NT_SUCCESS(Status))
134 {
135 goto Cleanup;
136 }
137
138 if ((KeyValueInformation.Partial.Type != ValueType) ||
139 (KeyValueInformation.Partial.DataLength != DataLength))
140 {
142 goto Cleanup;
143 }
144
145 if (ValueType == REG_BINARY)
146 {
147 RtlCopyMemory(ValueData, KeyValueInformation.Partial.Data, DataLength);
148 }
149 else if (ValueType == REG_DWORD)
150 {
151 *(PULONG)ValueData = *(PULONG)KeyValueInformation.Partial.Data;
152 }
153 else
154 {
156 }
157
158Cleanup:
159 CloseStatus = ZwClose(KeyHandle);
160 ASSERT(NT_SUCCESS( CloseStatus ));
161
162 return Status;
163}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define REG_BINARY
Definition: nt_native.h:1496
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define REG_DWORD
Definition: sdbapi.c:596
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by SepAdtInitializeBounds(), and SepImpersonateAnonymousToken().

◆ SepReleaseAcl()

VOID NTAPI SepReleaseAcl ( _In_ PACL  CapturedAcl,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases (frees) a captured ACL from the memory pool.

Parameters
[in]CapturedAclA valid captured ACL to free.
[in]AccessModeProcessor level access mode.
[in]CaptureIfKernelIf set to TRUE and the processor access mode being KernelMode, we're releasing an ACL directly in the kernel. Otherwise we're releasing within a kernel mode driver.
Returns
Nothing.

Definition at line 464 of file acl.c.

468{
469 PAGED_CODE();
470
471 if (CapturedAcl != NULL &&
473 (AccessMode == KernelMode && CaptureIfKernel)))
474 {
475 ExFreePoolWithTag(CapturedAcl, TAG_ACL);
476 }
477}

Referenced by NtCreateToken(), and NtSetInformationToken().

◆ SepReleaseSecurityQualityOfService()

VOID NTAPI SepReleaseSecurityQualityOfService ( _In_opt_ PSECURITY_QUALITY_OF_SERVICE  CapturedSecurityQualityOfService,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases (frees) the captured SQOS data from an object in the memory pool.

Parameters
[in]CapturedSecurityQualityOfServiceThe captured SQOS data to be released.
[in]AccessModeProcessor access mode.
[in]CaptureIfKernelCapture access condition. To be set to TRUE if the capture is done within the kernel, FALSE if the capture is done in a kernel mode driver or user mode otherwise.
Returns
Nothing.

Definition at line 225 of file sqos.c.

229{
230 PAGED_CODE();
231
232 if (CapturedSecurityQualityOfService != NULL &&
233 (AccessMode != KernelMode || CaptureIfKernel))
234 {
235 ExFreePoolWithTag(CapturedSecurityQualityOfService, TAG_QOS);
236 }
237}

Referenced by NtDuplicateToken().

◆ SepReleaseSid()

VOID NTAPI SepReleaseSid ( _In_ PSID  CapturedSid,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases a captured SID.

Parameters
[in]CapturedSidThe captured SID to be released.
[in]AccessModeProcessor level access mode.
[in]CaptureIfKernelIf set to TRUE, the releasing is done within the kernel. Otherwise the releasing is done in a kernel mode driver.
Returns
Nothing.

Definition at line 400 of file sid.c.

404{
405 PAGED_CODE();
406
407 if (CapturedSid != NULL &&
409 (AccessMode == KernelMode && CaptureIfKernel)))
410 {
411 ExFreePoolWithTag(CapturedSid, TAG_SID);
412 }
413}

Referenced by NtCreateToken(), NtSecureConnectPort(), NtSetInformationToken(), SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SepRemovePrivilegeToken()

VOID SepRemovePrivilegeToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

Removes a privilege from the token.

Parameters
[in,out]TokenThe token where the privilege is to be removed.
[in]IndexThe index count which represents the number position of the privilege we want to remove.
Returns
Nothing.

Definition at line 582 of file token.c.

585{
586 ULONG MoveCount;
587 ASSERT(Index < Token->PrivilegeCount);
588
589 /* Calculate the number of trailing privileges */
590 MoveCount = Token->PrivilegeCount - Index - 1;
591 if (MoveCount != 0)
592 {
593 /* Move them one location ahead */
594 RtlMoveMemory(&Token->Privileges[Index],
595 &Token->Privileges[Index + 1],
596 MoveCount * sizeof(LUID_AND_ATTRIBUTES));
597 }
598
599 /* Update privilege count */
600 Token->PrivilegeCount--;
601}
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by SepAdjustPrivileges(), SepDuplicateToken(), and SepPerformTokenFiltering().

◆ SepRemoveUserGroupToken()

VOID SepRemoveUserGroupToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

Removes a group from the token.

Parameters
[in,out]TokenThe token where the group is to be removed.
[in]IndexThe index count which represents the number position of the group we want to remove.
Returns
Nothing.

Definition at line 618 of file token.c.

621{
622 ULONG MoveCount;
623 ASSERT(Index < Token->UserAndGroupCount);
624
625 /* Calculate the number of trailing groups */
626 MoveCount = Token->UserAndGroupCount - Index - 1;
627 if (MoveCount != 0)
628 {
629 /* Time to remove the group by moving one location ahead */
630 RtlMoveMemory(&Token->UserAndGroups[Index],
631 &Token->UserAndGroups[Index + 1],
632 MoveCount * sizeof(SID_AND_ATTRIBUTES));
633 }
634
635 /* Remove one group count */
636 Token->UserAndGroupCount--;
637}

Referenced by SepDuplicateToken().

◆ SePrivilegedServiceAuditAlarm()

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.

Parameters
[in]ServiceNameA Unicode string that represents the name of a privileged service request for auditing.
[in]SubjectContextA security subject context used for the auditing process.
[in]PrivilegeSetAn array set of privileges used to check if the privileged service does actually have all the required set of privileges for security access.
[in]AccessGrantedWhen auditing is done, the function will return TRUE to the caller if access is granted, FALSE otherwise.
Returns
Nothing.

Definition at line 369 of file audit.c.

374{
375 PTOKEN EffectiveToken;
376 PSID UserSid;
377 PAGED_CODE();
378
379 /* Get the effective token */
380 if (SubjectContext->ClientToken != NULL)
381 EffectiveToken = SubjectContext->ClientToken;
382 else
383 EffectiveToken = SubjectContext->PrimaryToken;
384
385 /* Get the user SID */
386 UserSid = EffectiveToken->UserAndGroups->Sid;
387
388 /* Check if this is the local system SID */
389 if (RtlEqualSid(UserSid, SeLocalSystemSid))
390 {
391 /* Nothing to do */
392 return;
393 }
394
395 /* Check if this is the network service or local service SID */
398 {
399 // FIXME: should continue for a certain set of privileges
400 return;
401 }
402
403 /* Call the worker function */
407 SubjectContext->ClientToken,
408 SubjectContext->PrimaryToken,
409 PrivilegeSet,
411
412}
static WCHAR ServiceName[]
Definition: browser.c:19
UNICODE_STRING SeSubsystemName
Definition: audit.c:17
VOID NTAPI SepAdtPrivilegedServiceAuditAlarm(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_opt_ PUNICODE_STRING SubsystemName, _In_opt_ PUNICODE_STRING ServiceName, _In_ PTOKEN Token, _In_ PTOKEN PrimaryToken, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted)
Performs an audit alarm to a privileged service request. This is a worker function.
Definition: audit.c:332
PSE_EXPORTS SeExports
Definition: semgr.c:21
PSID SeNetworkServiceSid
Definition: setypes.h:1244
PSID SeLocalServiceSid
Definition: setypes.h:1243
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE _In_ BOOLEAN _In_ BOOLEAN AccessGranted
Definition: sefuncs.h:419

Referenced by SeCheckAuditPrivilege(), and SeSinglePrivilegeCheck().

◆ 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 */
286 {
287 /* Do the privilege check */
289 {
290 /* Remember this access flag */
292 PrivilegeCount++;
293 }
294 }
295
296 /* Update the access masks */
298 *DesiredAccess &= ~AccessMask;
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
319 {
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
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define WRITE_OWNER
Definition: nt_native.h:60
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
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
const LUID SeSecurityPrivilege
Definition: priv.c:27
#define TAG_PRIVILEGE_SET
Definition: tag.h:157
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_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:20

Referenced by SepAccessCheck(), and SepAccessCheckWorker().

◆ SepRmDereferenceLogonSession()

NTSTATUS SepRmDereferenceLogonSession ( _Inout_ PLUID  LogonLuid)

◆ SepRmInsertLogonSessionIntoToken()

NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken ( _Inout_ PTOKEN  Token)

Inserts a logon session into an access token specified by the caller.

Parameters
[in,out]TokenAn access token where the logon session is about to be inserted in.
Returns
STATUS_SUCCESS is returned if the logon session has been inserted into the token successfully. STATUS_NO_SUCH_LOGON_SESSION is returned when no logon session has been found with the matching ID of the token and as such we've failed to add the logon session to the token. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the new session has failed.

Definition at line 368 of file srm.c.

370{
372 PAGED_CODE();
373
374 /* Ensure that our token is not some plain garbage */
375 ASSERT(Token);
376
377 /* Acquire the database lock */
379
380 for (LogonSession = SepLogonSessions;
381 LogonSession != NULL;
382 LogonSession = LogonSession->Next)
383 {
384 /*
385 * The insertion of a logon session into the token has to be done
386 * only IF the authentication ID of the token matches with the ID
387 * of the logon itself.
388 */
389 if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
390 {
391 break;
392 }
393 }
394
395 /* If we reach this then we cannot proceed further */
396 if (LogonSession == NULL)
397 {
398 DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't insert the logon session into the specific access token!\n");
401 }
402
403 /*
404 * Allocate the session that we are going
405 * to insert it to the token.
406 */
407 Token->LogonSession = ExAllocatePoolWithTag(PagedPool,
410 if (Token->LogonSession == NULL)
411 {
412 DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't allocate new logon session into the memory pool!\n");
415 }
416
417 /*
418 * Begin copying the logon session references data from the
419 * session whose ID matches with the token authentication ID to
420 * the new session we've allocated blocks of pool memory for it.
421 */
422 Token->LogonSession->Next = LogonSession->Next;
423 Token->LogonSession->LogonId = LogonSession->LogonId;
424 Token->LogonSession->ReferenceCount = LogonSession->ReferenceCount;
425 Token->LogonSession->Flags = LogonSession->Flags;
426 Token->LogonSession->pDeviceMap = LogonSession->pDeviceMap;
427 InsertHeadList(&LogonSession->TokenList, &Token->LogonSession->TokenList);
428
429 /* Release the database lock and we're done */
431 return STATUS_SUCCESS;
432}
#define InsertHeadList(ListHead, Entry)
#define TAG_LOGON_SESSION
Definition: tag.h:163

Referenced by SepCreateToken(), SepDuplicateToken(), and SepPerformTokenFiltering().

◆ SepRmReferenceLogonSession()

NTSTATUS SepRmReferenceLogonSession ( _Inout_ PLUID  LogonLuid)

◆ SepRmRemoveLogonSessionFromToken()

NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken ( _Inout_ PTOKEN  Token)

Removes a logon session from an access token.

Parameters
[in,out]TokenAn access token whose logon session is to be removed from it.
Returns
STATUS_SUCCESS is returned if the logon session has been removed from the token successfully. STATUS_NO_SUCH_LOGON_SESSION is returned when no logon session has been found with the matching ID of the token and as such we've failed to remove the logon session from the token.

Definition at line 449 of file srm.c.

451{
453 PAGED_CODE();
454
455 /* Ensure that our token is not some plain garbage */
456 ASSERT(Token);
457
458 /* Acquire the database lock */
460
461 for (LogonSession = SepLogonSessions;
462 LogonSession != NULL;
463 LogonSession = LogonSession->Next)
464 {
465 /*
466 * Remove the logon session only when the IDs of the token and the
467 * logon match.
468 */
469 if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
470 {
471 break;
472 }
473 }
474
475 /* They don't match */
476 if (LogonSession == NULL)
477 {
478 DPRINT1("SepRmRemoveLogonSessionFromToken(): Couldn't remove the logon session from the access token!\n");
481 }
482
483 /* Now it's time to delete the logon session from the token */
484 RemoveEntryList(&Token->LogonSession->TokenList);
486
487 /* Release the database lock and we're done */
489 return STATUS_SUCCESS;
490}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by NtSetInformationToken(), and SepDeleteToken().

◆ SepSelectAcl()

PACL SepSelectAcl ( _In_opt_ PACL  ExplicitAcl,
_In_ BOOLEAN  ExplicitPresent,
_In_ BOOLEAN  ExplicitDefaulted,
_In_opt_ PACL  ParentAcl,
_In_opt_ PACL  DefaultAcl,
_Out_ PULONG  AclLength,
_In_ PSID  Owner,
_In_ PSID  Group,
_Out_ PBOOLEAN  AclPresent,
_Out_ PBOOLEAN  IsInherited,
_In_ BOOLEAN  IsDirectoryObject,
_In_ PGENERIC_MAPPING  GenericMapping 
)

Selects an ACL and returns it to the caller.

Parameters
[in]ExplicitAclIf specified, the specified ACL to the call will be the selected ACL for the caller.
[in]ExplicitPresentIf set to TRUE and with specific ACL filled to the call, the function will immediately return the specific ACL as the selected ACL for the caller.
[in]ExplicitDefaultedIf set to FALSE and with specific ACL filled to the call, the ACL is not a default ACL. Otherwise it's a default ACL that we cannot select it as is.
[in]ParentAclIf specified, the parent ACL will be used to determine the exact ACL length to check if the ACL in question is not empty. If the list is not empty then the function will select such ACL to the caller.
[in]DefaultAclIf specified, the default ACL will be the selected one for the caller.
[out]AclLengthThe size length of an ACL.
[in]OwnerA SID that represents the main user that identifies the ACL.
[in]GroupA SID that represents a group that identifies the ACL.
[out]AclPresentThe returned boolean value, indicating if the ACL that we want to select does actually exist.
[out]IsInheritedThe returned boolean value, indicating if the ACL we want to select it is actually inherited or not.
[in]IsDirectoryObjectIf set to TRUE, the object inherits this ACL.
[in]GenericMappingGeneric mapping of access rights to map only certain effective ACEs of an ACL that we want to select it.
Returns
Returns the selected access control list (ACL) to the caller, NULL otherwise.

Definition at line 804 of file acl.c.

817{
818 PACL Acl;
820
821 *AclPresent = TRUE;
822 if (ExplicitPresent && !ExplicitDefaulted)
823 {
824 Acl = ExplicitAcl;
825 }
826 else
827 {
828 if (ParentAcl)
829 {
830 *IsInherited = TRUE;
831 *AclLength = 0;
833 AclLength,
834 ParentAcl,
835 Owner,
836 Group,
837 *IsInherited,
841
842 /* Use the parent ACL only if it's not empty */
843 if (*AclLength != sizeof(ACL))
844 return ParentAcl;
845 }
846
847 if (ExplicitPresent)
848 {
849 Acl = ExplicitAcl;
850 }
851 else if (DefaultAcl)
852 {
853 Acl = DefaultAcl;
854 }
855 else
856 {
857 *AclPresent = FALSE;
858 Acl = NULL;
859 }
860 }
861
862 *IsInherited = FALSE;
863 *AclLength = 0;
864 if (Acl)
865 {
866 /* Get the length */
868 AclLength,
869 Acl,
870 Owner,
871 Group,
872 *IsInherited,
876 }
877 return Acl;
878}
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
NTSTATUS SepPropagateAcl(_Out_writes_bytes_opt_(AclLength) PACL AclDest, _Inout_ PULONG AclLength, _In_reads_bytes_(AclSource->AclSize) PACL AclSource, _In_ PSID Owner, _In_ PSID Group, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
Propagates (copies) an access control list.
Definition: acl.c:587
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR _In_ BOOLEAN IsDirectoryObject
Definition: sefuncs.h:31

◆ SepSidInToken()

BOOLEAN NTAPI SepSidInToken ( _In_ PACCESS_TOKEN  _Token,
_In_ PSID  Sid 
)

Checks if a SID is present in a token.

Parameters
[in]_TokenA valid token object.
[in]_SidA regular SID.
Returns
Returns TRUE if the specified SID in the call is present in the token, FALSE otherwise.

Definition at line 547 of file sid.c.

550{
551 /* Call extended API */
552 return SepSidInTokenEx(_Token, NULL, Sid, FALSE, FALSE);
553}
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

Referenced by SepTokenIsOwner().

◆ SepSidInTokenEx()

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.

Parameters
[in]_TokenA valid token object.
[in]PrincipalSelfSidA principal self SID.
[in]_SidA regular SID.
[in]DenyIf set to TRUE, the caller expected that a SID in a token must be a deny-only SID, that is, access checks are performed only for deny-only ACEs of the said SID.
[in]RestrictedIf set to TRUE, the caller expects that a SID in a token is restricted (by the general definition, a token is restricted).
Returns
Returns TRUE if the specified SID in the call is present in the token, FALSE otherwise.

Definition at line 443 of file sid.c.

449{
450 ULONG SidIndex;
451 PTOKEN Token = (PTOKEN)_Token;
452 PISID TokenSid, Sid = (PISID)_Sid;
453 PSID_AND_ATTRIBUTES SidAndAttributes;
454 ULONG SidCount, SidLength;
455 USHORT SidMetadata;
456 PAGED_CODE();
457
458 /* Check if a principal SID was given, and this is our current SID already */
459 if ((PrincipalSelfSid) && (RtlEqualSid(SePrincipalSelfSid, Sid)))
460 {
461 /* Just use the principal SID in this case */
462 Sid = PrincipalSelfSid;
463 }
464
465 /* Check if this is a restricted token or not */
466 if (Restricted)
467 {
468 /* Use the restricted SIDs and count */
469 SidAndAttributes = Token->RestrictedSids;
470 SidCount = Token->RestrictedSidCount;
471 }
472 else
473 {
474 /* Use the normal SIDs and count */
475 SidAndAttributes = Token->UserAndGroups;
476 SidCount = Token->UserAndGroupCount;
477 }
478
479 /* Do checks here by hand instead of the usual 4 function calls */
480 SidLength = FIELD_OFFSET(SID,
481 SubAuthority[Sid->SubAuthorityCount]);
482 SidMetadata = *(PUSHORT)&Sid->Revision;
483
484 /* Loop every SID */
485 for (SidIndex = 0; SidIndex < SidCount; SidIndex++)
486 {
487 TokenSid = (PISID)SidAndAttributes->Sid;
488#if SE_SID_DEBUG
489 UNICODE_STRING sidString;
490 RtlConvertSidToUnicodeString(&sidString, TokenSid, TRUE);
491 DPRINT1("SID in Token: %wZ\n", &sidString);
492 RtlFreeUnicodeString(&sidString);
493#endif
494 /* Check if the SID metadata matches */
495 if (*(PUSHORT)&TokenSid->Revision == SidMetadata)
496 {
497 /* Check if the SID data matches */
498 if (RtlEqualMemory(Sid, TokenSid, SidLength))
499 {
500 /*
501 * Check if the group is enabled, or used for deny only.
502 * Otherwise we have to check if this is the first user.
503 * We understand that by looking if this SID is not
504 * restricted, this is the first element we are iterating
505 * and that it doesn't have SE_GROUP_USE_FOR_DENY_ONLY
506 * attribute.
507 */
508 if ((!Restricted && (SidIndex == 0) && !(SidAndAttributes->Attributes & SE_GROUP_USE_FOR_DENY_ONLY)) ||
509 (SidAndAttributes->Attributes & SE_GROUP_ENABLED) ||
510 ((Deny) && (SidAndAttributes->Attributes & SE_GROUP_USE_FOR_DENY_ONLY)))
511 {
512 /* SID is present */
513 return TRUE;
514 }
515 else
516 {
517 /* SID is not present */
518 return FALSE;
519 }
520 }
521 }
522
523 /* Move to the next SID */
524 SidAndAttributes++;
525 }
526
527 /* SID is not present */
528 return FALSE;
529}
UNICODE_STRING Restricted
Definition: utils.c:24
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define for
Definition: utility.h:88
#define SE_GROUP_USE_FOR_DENY_ONLY
Definition: setypes.h:94
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI NTSTATUS NTAPI RtlConvertSidToUnicodeString(OUT PUNICODE_STRING DestinationString, IN PVOID Sid, IN BOOLEAN AllocateDestinationString)
unsigned short USHORT
Definition: pedump.c:61
BYTE Revision
Definition: ms-dtyp.idl:199
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by SepAnalyzeAcesFromDacl(), SepSidInToken(), and SepTokenIsOwner().

◆ SepTokenIsOwner()

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.

Parameters
[in]_TokenA valid token object.
[in]SecurityDescriptorA security descriptor where the owner is to be found.
[in]TokenLockedIf set to TRUE, the token has been already locked and there's no need to lock it again. Otherwise the function will acquire the lock.
Returns
Returns TRUE if the token belongs to a owner, FALSE otherwise.

Definition at line 511 of file token.c.

515{
516 PSID Sid;
518 PTOKEN Token = _Token;
519
520 /* Get the owner SID */
522 ASSERT(Sid != NULL);
523
524 /* Lock the token if needed */
525 if (!TokenLocked) SepAcquireTokenLockShared(Token);
526
527 /* Check if the owner SID is found, handling restricted case as well */
529 if ((Result) && (Token->TokenFlags & TOKEN_IS_RESTRICTED))
530 {
532 }
533
534 /* Release the lock if we had acquired it */
535 if (!TokenLocked) SepReleaseTokenLock(Token);
536
537 /* Return the result */
538 return Result;
539}
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:109
BOOLEAN NTAPI SepSidInToken(_In_ PACCESS_TOKEN _Token, _In_ PSID Sid)
Checks if a SID is present in a token.
Definition: sid.c:547
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

Referenced by SeAccessCheck(), and SepAccessCheck().

◆ SepUpdatePrivilegeFlagsToken()

VOID SepUpdatePrivilegeFlagsToken ( _Inout_ PTOKEN  Token)

Updates the token's flags based upon the privilege that the token has been granted. The function uses the private helper, SepUpdateSinglePrivilegeFlagToken, in order to update the flags of a token.

Parameters
[in,out]TokenThe token where the flags are to be changed.
Returns
Nothing.

Definition at line 554 of file token.c.

556{
557 ULONG i;
558
559 /* Loop all privileges */
560 for (i = 0; i < Token->PrivilegeCount; i++)
561 {
562 /* Updates the flags for this privilege */
564 }
565}
VOID SepUpdateSinglePrivilegeFlagToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Updates the token's flags based upon the privilege that the token has been granted....
Definition: token.c:442

Referenced by SepCreateToken().

◆ SepUpdateSinglePrivilegeFlagToken()

VOID SepUpdateSinglePrivilegeFlagToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

Updates the token's flags based upon the privilege that the token has been granted. The flag can either be taken out or given to the token if the attributes of the specified privilege is enabled or not.

Parameters
[in,out]TokenThe token where the flags are to be changed.
[in]IndexThe index count which represents the total sum of privileges. The count in question MUST NOT exceed the expected privileges count of the token.
Returns
Nothing.

Definition at line 442 of file token.c.

445{
446 ULONG TokenFlag;
447 ASSERT(Index < Token->PrivilegeCount);
448
449 /* The high part of all values we are interested in is 0 */
450 if (Token->Privileges[Index].Luid.HighPart != 0)
451 {
452 return;
453 }
454
455 /* Check for certain privileges to update flags */
456 if (Token->Privileges[Index].Luid.LowPart == SE_CHANGE_NOTIFY_PRIVILEGE)
457 {
459 }
460 else if (Token->Privileges[Index].Luid.LowPart == SE_BACKUP_PRIVILEGE)
461 {
462 TokenFlag = TOKEN_HAS_BACKUP_PRIVILEGE;
463 }
464 else if (Token->Privileges[Index].Luid.LowPart == SE_RESTORE_PRIVILEGE)
465 {
466 TokenFlag = TOKEN_HAS_RESTORE_PRIVILEGE;
467 }
468 else if (Token->Privileges[Index].Luid.LowPart == SE_IMPERSONATE_PRIVILEGE)
469 {
471 }
472 else
473 {
474 /* Nothing to do */
475 return;
476 }
477
478 /* Check if the specified privilege is enabled */
479 if (Token->Privileges[Index].Attributes & SE_PRIVILEGE_ENABLED)
480 {
481 /* It is enabled, so set the flag */
482 Token->TokenFlags |= TokenFlag;
483 }
484 else
485 {
486 /* Is is disabled, so remove the flag */
487 Token->TokenFlags &= ~TokenFlag;
488 }
489}
#define SE_IMPERSONATE_PRIVILEGE
Definition: security.c:683
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
#define SE_CHANGE_NOTIFY_PRIVILEGE
Definition: security.c:677
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1178
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1179
#define TOKEN_HAS_IMPERSONATE_PRIVILEGE
Definition: setypes.h:1186
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1180

Referenced by SepAdjustPrivileges(), SepPerformTokenFiltering(), and SepUpdatePrivilegeFlagsToken().

◆ SeQuerySecurityAccessMask()

VOID NTAPI SeQuerySecurityAccessMask ( _In_ SECURITY_INFORMATION  SecurityInformation,
_Out_ PACCESS_MASK  DesiredAccess 
)

Queries the access mask from a security information context.

Parameters
[in]SecurityInformationThe security information context where the access mask is to be gathered.
[out]DesiredAccessThe queried access mask right.
Returns
Nothing.

Definition at line 427 of file semgr.c.

430{
431 *DesiredAccess = 0;
432
435 {
437 }
438
440 {
442 }
443}
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126

Referenced by NtQuerySecurityObject().

◆ 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}
#define TAG_LUID
Definition: tag.h:155

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

◆ SeReleaseObjectTypeList()

VOID SeReleaseObjectTypeList ( _In_ _Post_invalid_ POBJECT_TYPE_LIST_INTERNAL  CapturedObjectTypeList,
_In_ KPROCESSOR_MODE  PreviousMode 
)

Releases a buffer list of object types.

Parameters
[in]CapturedObjectTypeListA list of object types to free.
[in]PreviousModeProcessor access level mode.

Definition at line 378 of file objtype.c.

381{
382 PAGED_CODE();
383
384 if ((PreviousMode != KernelMode) && (CapturedObjectTypeList != NULL))
385 {
386 ExFreePoolWithTag(CapturedObjectTypeList, TAG_SEPA);
387 }
388}

Referenced by SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SeReleaseSidAndAttributesArray()

VOID NTAPI SeReleaseSidAndAttributesArray ( _In_ _Post_invalid_ PSID_AND_ATTRIBUTES  CapturedSidAndAttributes,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases a captured SID with attributes.

Parameters
[in]CapturedSidAndAttributesThe captured SID with attributes to be released.
[in]AccessModeProcessor access level mode.
[in]CaptureIfKernelIf set to TRUE, the releasing is done within the kernel. Otherwise the releasing is done in a kernel mode driver.
Returns
Nothing.

Definition at line 976 of file sid.c.

980{
981 PAGED_CODE();
982
983 if ((CapturedSidAndAttributes != NULL) &&
984 ((AccessMode != KernelMode) || CaptureIfKernel))
985 {
986 ExFreePoolWithTag(CapturedSidAndAttributes, TAG_SID_AND_ATTRIBUTES);
987 }
988}

Referenced by NtAdjustGroupsToken(), NtCreateToken(), and NtFilterToken().

◆ SeRmInitPhase0()

BOOLEAN NTAPI SeRmInitPhase0 ( VOID  )

Manages the phase 0 initialization of the security reference monitoring module of the kernel.

Returns
Returns TRUE when phase 0 initialization has completed without problems, FALSE otherwise.

Definition at line 176 of file srm.c.

177{
179
180 /* Initialize the database lock */
182
183 /* Create the system logon session */
186 {
187 return FALSE;
188 }
189
190 /* Create the anonymous logon session */
193 {
194 return FALSE;
195 }
196
197 return TRUE;
198}
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
LUID SeSystemAuthenticationId
Definition: token.c:20
static NTSTATUS SepRmCreateLogonSession(_In_ PLUID LogonLuid)
Creates a logon session. The security reference monitoring (SRM) module of Executive uses this as an ...
Definition: srm.c:512
LUID SeAnonymousAuthenticationId
Definition: token.c:21
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287

Referenced by SepInitializationPhase0().

◆ SeRmInitPhase1()

BOOLEAN NTAPI SeRmInitPhase1 ( VOID  )

Manages the phase 1 initialization of the security reference monitoring module of the kernel.

Returns
Returns TRUE when phase 1 initialization has completed without problems, FALSE otherwise.

Definition at line 211 of file srm.c.

212{
215 HANDLE ThreadHandle;
217
218 /* Create the SeRm command port */
219 RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
223 sizeof(ULONG),
225 2 * PAGE_SIZE);
226 if (!NT_SUCCESS(Status))
227 {
228 DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status);
229 return FALSE;
230 }
231
232 /* Create SeLsaInitEvent */
233 RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
235 Status = ZwCreateEvent(&SeLsaInitEvent,
239 FALSE);
240 if (!NT_VERIFY((NT_SUCCESS(Status))))
241 {
242 DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status);
243 return FALSE;
244 }
245
246 /* Create the SeRm server thread */
247 Status = PsCreateSystemThread(&ThreadHandle,
249 NULL,
250 NULL,
251 NULL,
253 NULL);
254 if (!NT_SUCCESS(Status))
255 {
256 DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status);
257 return FALSE;
258 }
259
260 ObCloseHandle(ThreadHandle, KernelMode);
261
262 return TRUE;
263}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSYSAPI NTSTATUS NTAPI ZwCreatePort(_Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectionInfoLength, _In_ ULONG MaxMessageLength, _In_ ULONG MaxPoolUsage)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
@ NotificationEvent
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
HANDLE SeLsaInitEvent
Definition: srm.c:46
VOID NTAPI SepRmCommandServerThread(_In_ PVOID StartContext)
Manages the SRM server API commands, that is, receiving such API command messages from the user mode ...
Definition: srm.c:1226
HANDLE SeRmCommandPort
Definition: srm.c:45
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
#define PORT_MAXIMUM_MESSAGE_LENGTH
Definition: iotypes.h:2029

Referenced by Phase1InitializationDiscard().

◆ SeSetSecurityAccessMask()

VOID NTAPI SeSetSecurityAccessMask ( _In_ SECURITY_INFORMATION  SecurityInformation,
_Out_ PACCESS_MASK  DesiredAccess 
)

Sets the access mask for a security information context.

Parameters
[in]SecurityInformationThe security information context to apply a new access right.
[out]DesiredAccessThe returned access mask right.
Returns
Nothing.

Definition at line 460 of file semgr.c.

Referenced by NtSetSecurityObject().

◆ SeSetWorldSecurityDescriptor()

NTSTATUS NTAPI SeSetWorldSecurityDescriptor ( _In_ SECURITY_INFORMATION  SecurityInformation,
_In_ PISECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ PULONG  BufferLength 
)

Sets a "World" security descriptor.

Parameters
[in]SecurityInformationSecurity information details, alongside with the security descriptor to set the World SD.
[in]SecurityDescriptorA security descriptor buffer.
[in]BufferLengthLength size of the buffer.
Returns
Returns STATUS_SUCCESS if the World security descriptor has been set. STATUS_ACCESS_DENIED is returned if the caller hasn't provided security information details thus the SD cannot be set.

Definition at line 155 of file sd.c.

159{
160 ULONG Current;
161 ULONG SidSize;
162 ULONG SdSize;
165
166 DPRINT("SeSetWorldSecurityDescriptor() called\n");
167
168 if (SecurityInformation == 0)
169 {
171 }
172
173 /* calculate the minimum size of the buffer */
174 SidSize = RtlLengthSid(SeWorldSid);
175 SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
177 SdSize += SidSize;
179 SdSize += SidSize;
181 {
182 SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
183 }
185 {
186 SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
187 }
188
189 if (*BufferLength < SdSize)
190 {
191 *BufferLength = SdSize;
193 }
194
195 *BufferLength = SdSize;
196
199 if (!NT_SUCCESS(Status))
200 {
201 return Status;
202 }
203
204 Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
205
207 {
208 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
209 SdRel->Owner = Current;
210 Current += SidSize;
211 }
212
214 {
215 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
216 SdRel->Group = Current;
217 Current += SidSize;
218 }
219
221 {
222 PACL Dacl = (PACL)((PUCHAR)SdRel + Current);
223
225 sizeof(ACL) + sizeof(ACE) + SidSize,
227 if (!NT_SUCCESS(Status))
228 return Status;
229
233 SeWorldSid);
234 if (!NT_SUCCESS(Status))
235 return Status;
236
237 SdRel->Control |= SE_DACL_PRESENT;
238 SdRel->Dacl = Current;
239 Current += SidSize;
240 }
241
243 {
244 PACL Sacl = (PACL)((PUCHAR)SdRel + Current);
245
247 sizeof(ACL) + sizeof(ACE) + SidSize,
249 if (!NT_SUCCESS(Status))
250 return Status;
251
256 TRUE,
257 TRUE);
258 if (!NT_SUCCESS(Status))
259 return Status;
260
261 SdRel->Control |= SE_SACL_PRESENT;
262 SdRel->Sacl = Current;
263 Current += SidSize;
264 }
265
266 return STATUS_SUCCESS;
267}
struct _ACL * PACL
Definition: security.c:105
NTSYSAPI NTSTATUS NTAPI RtlAddAuditAccessAce(_Inout_ PACL Acl, _In_ ULONG Revision, _In_ ACCESS_MASK AccessMask, _In_ PSID Sid, _In_ BOOLEAN Success, _In_ BOOLEAN Failure)
_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 Sacl
Definition: rtlfuncs.h:1595
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptorRelative(_Out_ PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor, _In_ ULONG Revision)
#define STANDARD_RIGHTS_ALL
Definition: nt_native.h:69
SECURITY_DESCRIPTOR_CONTROL Control
Definition: setypes.h:839
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE

Referenced by IopGetSetSecurityObject().

◆ SeSubProcessToken()

NTSTATUS NTAPI SeSubProcessToken ( _In_ PTOKEN  ParentToken,
_Out_ PTOKEN Token,
_In_ BOOLEAN  InUse,
_In_ ULONG  SessionId 
)

Subtracts a token in exchange of duplicating a new one.

Parameters
[in]ParentTokenThe parent access token for duplication.
[out]TokenThe new duplicated token.
[in]InUseSet this to TRUE if the token is about to be used immediately after the call execution of this function, FALSE otherwise.
[in]SessionIdSession ID for the token to be assigned.
Returns
Returns STATUS_SUCCESS if token subtracting and duplication have completed successfully. A failure NTSTATUS code is returned otherwise.

Definition at line 1373 of file token.c.

1378{
1379 PTOKEN NewToken;
1382
1383 /* Initialize the attributes and duplicate it */
1385 Status = SepDuplicateToken(ParentToken,
1387 FALSE,
1389 ParentToken->ImpersonationLevel,
1390 KernelMode,
1391 &NewToken);
1392 if (NT_SUCCESS(Status))
1393 {
1394 /* Insert it */
1395 Status = ObInsertObject(NewToken,
1396 NULL,
1397 0,
1398 0,
1399 NULL,
1400 NULL);
1401 if (NT_SUCCESS(Status))
1402 {
1403 /* Set the session ID */
1404 NewToken->SessionId = SessionId;
1405 NewToken->TokenInUse = InUse;
1406
1407 /* Return the token */
1408 *Token = NewToken;
1409 }
1410 }
1411
1412 /* Return status */
1413 return Status;
1414}
ULONG SessionId
Definition: dllmain.c:28

Referenced by PspInitializeProcessSecurity().

◆ SeTokenCanImpersonate()

BOOLEAN NTAPI SeTokenCanImpersonate ( _In_ PTOKEN  ProcessToken,
_In_ PTOKEN  TokenToImpersonate,
_In_ SECURITY_IMPERSONATION_LEVEL  ImpersonationLevel 
)

Determines whether the server is allowed to impersonate on behalf of a client or not. For further details, see Remarks.

Parameters
[in]ProcessTokenA pointer to the primary access token of the server process that requests impersonation of the client target.
[in]TokenToImpersonateA pointer to an access token that represents a client that is to be impersonated.
[in]ImpersonationLevelThe requested impersonation level.
Returns
Returns TRUE if the conditions checked are met for token impersonation, FALSE otherwise.
Remarks
The server has to meet the following criteria in order to impersonate a client, that is:
  • The server must not impersonate a client beyond the level that the client imposed on itself.
  • The server must be authenticated on the same logon session of the target client.
  • IF NOT then the server's user ID has to match to that of the target client.
  • The server must not be restricted in order to impersonate a client that is not restricted.

If the associated access token that represents the security properties of the server is granted the SeImpersonatePrivilege privilege the server is given immediate impersonation, regardless of the conditions above. If the client in question is associated with an anonymous token then the server is given immediate impersonation. Or if the server simply doesn't ask for impersonation but instead it wants to get the security identification of a client, the server is given immediate impersonation.

Definition at line 2207 of file token.c.

2211{
2212 BOOLEAN CanImpersonate;
2213 PAGED_CODE();
2214
2215 /*
2216 * The server may want to obtain identification details of a client
2217 * instead of impersonating so just give the server a pass.
2218 */
2220 {
2221 DPRINT("The server doesn't ask for impersonation\n");
2222 return TRUE;
2223 }
2224
2225 /* Time to lock our tokens */
2226 SepAcquireTokenLockShared(ProcessToken);
2227 SepAcquireTokenLockShared(TokenToImpersonate);
2228
2229 /*
2230 * As the name implies, an anonymous token has invisible security
2231 * identification details. By the general rule these tokens do not
2232 * pose a danger in terms of power escalation so give the server a pass.
2233 */
2234 if (RtlEqualLuid(&TokenToImpersonate->AuthenticationId,
2236 {
2237 DPRINT("The token to impersonate has an anonymous authentication ID, allow impersonation either way\n");
2238 CanImpersonate = TRUE;
2239 goto Quit;
2240 }
2241
2242 /* Allow impersonation for the process server if it's granted the impersonation privilege */
2243 if ((ProcessToken->TokenFlags & TOKEN_HAS_IMPERSONATE_PRIVILEGE) != 0)
2244 {
2245 DPRINT("The process is granted the impersonation privilege, allow impersonation\n");
2246 CanImpersonate = TRUE;
2247 goto Quit;
2248 }
2249
2250 /*
2251 * Deny impersonation for the server if it wants to impersonate a client
2252 * beyond what the impersonation level originally permits.
2253 */
2254 if (ImpersonationLevel > TokenToImpersonate->ImpersonationLevel)
2255 {
2256 DPRINT1("Cannot impersonate a client above the permitted impersonation level!\n");
2257 CanImpersonate = FALSE;
2258 goto Quit;
2259 }
2260
2261 /* Is the server authenticated on the same client originating session? */
2262 if (!RtlEqualLuid(&ProcessToken->AuthenticationId,
2263 &TokenToImpersonate->OriginatingLogonSession))
2264 {
2265 /* It's not, check that at least both the server and client are the same user */
2266 if (!RtlEqualSid(ProcessToken->UserAndGroups[0].Sid,
2267 TokenToImpersonate->UserAndGroups[0].Sid))
2268 {
2269 DPRINT1("Server and client aren't the same user!\n");
2270 CanImpersonate = FALSE;
2271 goto Quit;
2272 }
2273
2274 /*
2275 * Make sure the tokens haven't diverged in terms of restrictions
2276 * that is one token is restricted but the other one isn't. If that
2277 * would have been the case then the server would have impersonated
2278 * a less restricted client thus potentially triggering an elevation,
2279 * which is not what we want.
2280 */
2281 if (SeTokenIsRestricted(ProcessToken) !=
2282 SeTokenIsRestricted(TokenToImpersonate))
2283 {
2284 DPRINT1("Attempting to impersonate a less restricted client token, bail out!\n");
2285 CanImpersonate = FALSE;
2286 goto Quit;
2287 }
2288 }
2289
2290 /* If we've reached that far then we can impersonate! */
2291 DPRINT("We can impersonate\n");
2292 CanImpersonate = TRUE;
2293
2294Quit:
2295 SepReleaseTokenLock(TokenToImpersonate);
2296 SepReleaseTokenLock(ProcessToken);
2297 return CanImpersonate;
2298}
@ SecurityIdentification
Definition: lsa.idl:56
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:2126

Referenced by PsImpersonateClient().

◆ SeTokenIsInert()

BOOLEAN NTAPI SeTokenIsInert ( _In_ PTOKEN  Token)

Determines if a token is a sandbox inert token or not, based upon the token flags.

Parameters
[in]TokenA valid access token to determine if such token is inert.
Returns
Returns TRUE if the token is inert, FALSE otherwise.

Definition at line 1583 of file token.c.

1585{
1586 PAGED_CODE();
1587
1588 return (((PTOKEN)Token)->TokenFlags & TOKEN_SANDBOX_INERT) != 0;
1589}
#define TOKEN_SANDBOX_INERT
Definition: setypes.h:1185

Referenced by NtQueryInformationToken().

Variable Documentation

◆ SeAliasAccountOpsSid

PSID SeAliasAccountOpsSid
extern

Definition at line 45 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasAdminsSid

◆ SeAliasBackupOpsSid

PSID SeAliasBackupOpsSid
extern

Definition at line 48 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasGuestsSid

PSID SeAliasGuestsSid
extern

Definition at line 43 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasPowerUsersSid

PSID SeAliasPowerUsersSid
extern

Definition at line 44 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasPrintOpsSid

PSID SeAliasPrintOpsSid
extern

Definition at line 47 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasSystemOpsSid

PSID SeAliasSystemOpsSid
extern

Definition at line 46 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAliasUsersSid

PSID SeAliasUsersSid
extern

Definition at line 42 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeAnonymousLogonSid

◆ SeAnonymousLogonToken

PTOKEN SeAnonymousLogonToken
extern

Definition at line 19 of file semgr.c.

Referenced by SepImpersonateAnonymousToken(), and SepInitializationPhase0().

◆ SeAnonymousLogonTokenNoEveryone

PTOKEN SeAnonymousLogonTokenNoEveryone
extern

Definition at line 20 of file semgr.c.

Referenced by SepImpersonateAnonymousToken(), and SepInitializationPhase0().

◆ SeAssignPrimaryTokenPrivilege

const LUID SeAssignPrimaryTokenPrivilege
extern

Definition at line 22 of file priv.c.

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

◆ SeAuditPrivilege

const LUID SeAuditPrivilege
extern

Definition at line 40 of file priv.c.

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

◆ SeAuthenticatedUserSid

PSID SeAuthenticatedUserSid
extern

Definition at line 39 of file sid.c.

Referenced by FreeInitializedSids(), and SepInitSecurityIDs().

◆ SeAuthenticatedUsersSid

PSID SeAuthenticatedUsersSid
extern

◆ SeBackupPrivilege

const LUID SeBackupPrivilege
extern

◆ SeBatchSid

PSID SeBatchSid
extern

Definition at line 34 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeChangeNotifyPrivilege

const LUID SeChangeNotifyPrivilege
extern

Definition at line 42 of file priv.c.

◆ SeCreateGlobalPrivilege

const LUID SeCreateGlobalPrivilege
extern

Definition at line 49 of file priv.c.

◆ SeCreatePagefilePrivilege

const LUID SeCreatePagefilePrivilege
extern

Definition at line 34 of file priv.c.

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

◆ SeCreatePermanentPrivilege

const LUID SeCreatePermanentPrivilege
extern

◆ SeCreateSymbolicLinkPrivilege

const LUID SeCreateSymbolicLinkPrivilege
extern

Definition at line 54 of file priv.c.

◆ SeCreateTokenPrivilege

const LUID SeCreateTokenPrivilege
extern

Definition at line 21 of file priv.c.

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

◆ SeCreatorGroupServerSid

PSID SeCreatorGroupServerSid
extern

Definition at line 30 of file sid.c.

Referenced by FreeInitializedSids(), and SepInitSecurityIDs().

◆ SeCreatorGroupSid

PSID SeCreatorGroupSid
extern

Definition at line 28 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), SepInitSecurityIDs(), and SepPropagateAcl().

◆ SeCreatorOwnerServerSid

PSID SeCreatorOwnerServerSid
extern

Definition at line 29 of file sid.c.

Referenced by FreeInitializedSids(), and SepInitSecurityIDs().

◆ SeCreatorOwnerSid

PSID SeCreatorOwnerSid
extern

◆ SeCreatorSidAuthority

SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority
extern

Definition at line 21 of file sid.c.

Referenced by SepInitSecurityIDs().

◆ SeDebugPrivilege

◆ SeDialupSid

PSID SeDialupSid
extern

Definition at line 32 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeEnableDelegationPrivilege

const LUID SeEnableDelegationPrivilege
extern

Definition at line 46 of file priv.c.

Referenced by SepInitExports().

◆ SeImpersonatePrivilege

const LUID SeImpersonatePrivilege
extern

Definition at line 48 of file priv.c.

◆ SeIncreaseBasePriorityPrivilege

const LUID SeIncreaseBasePriorityPrivilege
extern

◆ SeIncreaseQuotaPrivilege

const LUID SeIncreaseQuotaPrivilege
extern

Definition at line 24 of file priv.c.

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

◆ SeIncreaseWorkingSetPrivilege

const LUID SeIncreaseWorkingSetPrivilege
extern

Definition at line 52 of file priv.c.

◆ SeInteractiveSid

PSID SeInteractiveSid
extern

Definition at line 35 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeLoadDriverPrivilege

const LUID SeLoadDriverPrivilege
extern

◆ SeLocalServiceSid

PSID SeLocalServiceSid
extern

Definition at line 52 of file sid.c.

Referenced by SepInitExports(), and SepInitSecurityIDs().

◆ SeLocalSid

PSID SeLocalSid
extern

◆ SeLocalSidAuthority

SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority
extern

Definition at line 20 of file sid.c.

Referenced by SepInitSecurityIDs().

◆ SeLocalSystemSid

◆ SeLockMemoryPrivilege

const LUID SeLockMemoryPrivilege
extern

◆ SeManageVolumePrivilege

const LUID SeManageVolumePrivilege
extern

Definition at line 47 of file priv.c.

Referenced by SepCreateSystemProcessToken(), and SepInitExports().

◆ SeNetworkServiceSid

PSID SeNetworkServiceSid
extern

Definition at line 53 of file sid.c.

Referenced by SepInitExports(), and SepInitSecurityIDs().

◆ SeNetworkSid

PSID SeNetworkSid
extern

Definition at line 33 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeNtAuthoritySid

PSID SeNtAuthoritySid
extern

Definition at line 31 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeNtSidAuthority

SID_IDENTIFIER_AUTHORITY SeNtSidAuthority
extern

Definition at line 22 of file sid.c.

Referenced by SepInitSecurityIDs().

◆ SeNullSid

PSID SeNullSid
extern

Definition at line 24 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeNullSidAuthority

SID_IDENTIFIER_AUTHORITY SeNullSidAuthority
extern

Definition at line 18 of file sid.c.

Referenced by SepInitSecurityIDs().

◆ SePrincipalSelfSid

PSID SePrincipalSelfSid
extern

Definition at line 37 of file sid.c.

Referenced by FreeInitializedSids(), SepInitSecurityIDs(), and SepSidInTokenEx().

◆ SeProfileSingleProcessPrivilege

const LUID SeProfileSingleProcessPrivilege
extern

Definition at line 32 of file priv.c.

Referenced by SepCreateSystemProcessToken(), and SepInitExports().

◆ SePublicDefaultSd

PSECURITY_DESCRIPTOR SePublicDefaultSd
extern

◆ SePublicDefaultUnrestrictedDacl

PACL SePublicDefaultUnrestrictedDacl
extern

◆ SePublicDefaultUnrestrictedSd

PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
extern

Definition at line 17 of file sd.c.

Referenced by ExpCreateSystemRootLink(), ObInitSystem(), and SepInitSDs().

◆ SePublicOpenDacl

PACL SePublicOpenDacl
extern

Definition at line 19 of file acl.c.

Referenced by IopCreateSecurityDescriptorPerType(), SepInitDACLs(), and SepInitSDs().

◆ SePublicOpenSd

PSECURITY_DESCRIPTOR SePublicOpenSd
extern

Definition at line 18 of file sd.c.

Referenced by SepInitSDs().

◆ SePublicOpenUnrestrictedDacl

PACL SePublicOpenUnrestrictedDacl
extern

Definition at line 20 of file acl.c.

Referenced by IopCreateSecurityDescriptorPerType(), SepInitDACLs(), and SepInitSDs().

◆ SePublicOpenUnrestrictedSd

PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
extern

Definition at line 19 of file sd.c.

Referenced by SepInitSDs().

◆ SeRelabelPrivilege

const LUID SeRelabelPrivilege
extern

Definition at line 51 of file priv.c.

◆ SeRemoteShutdownPrivilege

const LUID SeRemoteShutdownPrivilege
extern

Definition at line 43 of file priv.c.

Referenced by SepInitExports().

◆ SeRestorePrivilege

const LUID SeRestorePrivilege
extern

◆ SeRestrictedCodeSid

PSID SeRestrictedCodeSid
extern

◆ SeRestrictedSid

PSID SeRestrictedSid
extern

Definition at line 50 of file sid.c.

Referenced by FreeInitializedSids(), SepInitExports(), and SepInitSecurityIDs().

◆ SeSecurityPrivilege

const LUID SeSecurityPrivilege
extern

Definition at line 27 of file priv.c.

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

◆ SeServiceSid

PSID SeServiceSid
extern

Definition at line 36 of file sid.c.

Referenced by FreeInitializedSids(), and SepInitSecurityIDs().

◆ SeShutdownPrivilege

const LUID SeShutdownPrivilege
extern

◆ SeSyncAgentPrivilege

const LUID SeSyncAgentPrivilege
extern

Definition at line 45 of file priv.c.

Referenced by SepInitExports().

◆ SeSystemAnonymousLogonDacl

PACL SeSystemAnonymousLogonDacl
extern

◆ SeSystemAnonymousLogonSd

PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd
extern

Definition at line 22 of file sd.c.

Referenced by SepInitSDs().

◆ SeSystemDefaultSd

PSECURITY_DESCRIPTOR SeSystemDefaultSd
extern

Definition at line 20 of file sd.c.

Referenced by SepInitSDs().

◆ SeSystemEnvironmentPrivilege

const LUID SeSystemEnvironmentPrivilege
extern

◆ SeSystemProfilePrivilege

const LUID SeSystemProfilePrivilege
extern

Definition at line 30 of file priv.c.

Referenced by NtCreateProfile(), and SepInitExports().

◆ SeSystemtimePrivilege

const LUID SeSystemtimePrivilege
extern

Definition at line 31 of file priv.c.

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

◆ SeTakeOwnershipPrivilege

const LUID SeTakeOwnershipPrivilege
extern

Definition at line 28 of file priv.c.

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

◆ SeTcbPrivilege

◆ SeTimeZonePrivilege

const LUID SeTimeZonePrivilege
extern

Definition at line 53 of file priv.c.

◆ SeTrustedCredmanPrivilege

const LUID SeTrustedCredmanPrivilege
extern

Definition at line 50 of file priv.c.

◆ SeUndockPrivilege

const LUID SeUndockPrivilege
extern

Definition at line 44 of file priv.c.

Referenced by SepCreateSystemProcessToken(), and SepInitExports().

◆ SeUnrestrictedDacl

PACL SeUnrestrictedDacl
extern

Definition at line 21 of file acl.c.

Referenced by SepInitDACLs(), and SepInitSDs().

◆ SeUnrestrictedSd

PSECURITY_DESCRIPTOR SeUnrestrictedSd
extern

Definition at line 21 of file sd.c.

Referenced by SepInitSDs().

◆ SeUnsolicitedInputPrivilege

const LUID SeUnsolicitedInputPrivilege
extern

Definition at line 25 of file priv.c.

Referenced by SepInitExports().

◆ SeWorldSid

◆ SeWorldSidAuthority

SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority
extern

Definition at line 19 of file sid.c.

Referenced by SepInitSecurityIDs().