ReactOS 0.4.15-dev-8102-g108db8f
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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#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:169
#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:73
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