ReactOS 0.4.15-dev-6055-g36cdd34
sefuncs.h File Reference
#include <umtypes.h>
Include dependency graph for sefuncs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

NTKERNELAPI NTSTATUS NTAPI SeCaptureSecurityDescriptor (_In_ PSECURITY_DESCRIPTOR OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
 Captures a security descriptor.
 
NTKERNELAPI NTSTATUS NTAPI SeReleaseSecurityDescriptor (_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
 Releases a captured security descriptor buffer.
 
NTKERNELAPI NTSTATUS NTAPI SeCreateAccessState (_In_ PACCESS_STATE AccessState, _In_ PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
 
NTKERNELAPI VOID NTAPI SeDeleteAccessState (_In_ PACCESS_STATE AccessState)
 Deletes an allocated access state from the memory.
 
NTKERNELAPI SECURITY_IMPERSONATION_LEVEL NTAPI SeTokenImpersonationLevel (_In_ PACCESS_TOKEN Token)
 Gathers the security impersonation level of an access token.
 
NTSYSCALLAPI NTSTATUS NTAPI NtAccessCheck (_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ PGENERIC_MAPPING GenericMapping, _Out_ PPRIVILEGE_SET PrivilegeSet, _Out_ PULONG ReturnLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
 
NTSTATUS NTAPI NtAccessCheckByType (_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSID PrincipalSelfSid, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeLength, _In_ PGENERIC_MAPPING GenericMapping, _In_ PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
 Determines whether security access could be granted or not on an object by the requestor who wants such access through type.
 
NTSTATUS NTAPI NtAccessCheckByTypeResultList (_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSID PrincipalSelfSid, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeLength, _In_ PGENERIC_MAPPING GenericMapping, _In_ PPRIVILEGE_SET PrivilegeSet, _Inout_ PULONG PrivilegeSetLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
 Determines whether security access could be granted or not on an object by the requestor who wants such access through type list.
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAccessCheckAndAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_opt_ PVOID HandleId, _In_ PUNICODE_STRING ObjectTypeName, _In_ PUNICODE_STRING ObjectName, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ACCESS_MASK DesiredAccess, _In_ PGENERIC_MAPPING GenericMapping, _In_ BOOLEAN ObjectCreation, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus, _Out_ PBOOLEAN GenerateOnClose)
 Raises an alarm audit message when a caller attempts to access an object and determine if the access can be made.
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAdjustGroupsToken (_In_ HANDLE TokenHandle, _In_ BOOLEAN ResetToDefault, _In_opt_ PTOKEN_GROUPS NewState, _In_opt_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_GROUPS PreviousState, _When_(PreviousState !=NULL, _Out_) PULONG ReturnLength)
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAdjustPrivilegesToken (_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState !=NULL, _Out_) PULONG ReturnLength)
 
NTSYSCALLAPI NTSTATUS NTAPI NtAllocateLocallyUniqueId (_Out_ LUID *LocallyUniqueId)
 
NTSYSCALLAPI NTSTATUS NTAPI NtAllocateUuids (_Out_ PULARGE_INTEGER Time, _Out_ PULONG Range, _Out_ PULONG Sequence, _Out_ PUCHAR Seed)
 
NTSYSCALLAPI NTSTATUS NTAPI NtCompareTokens (_In_ HANDLE FirstTokenHandle, _In_ HANDLE SecondTokenHandle, _Out_ PBOOLEAN Equal)
 Compares tokens if they're equal or not.
 
__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtCreateToken (_Out_ PHANDLE TokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PTOKEN_USER TokenUser, _In_ PTOKEN_GROUPS TokenGroups, _In_ PTOKEN_PRIVILEGES TokenPrivileges, _In_opt_ PTOKEN_OWNER TokenOwner, _In_ PTOKEN_PRIMARY_GROUP TokenPrimaryGroup, _In_opt_ PTOKEN_DEFAULT_DACL TokenDefaultDacl, _In_ PTOKEN_SOURCE TokenSource)
 Creates an access token.
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtDuplicateToken (_In_ HANDLE ExistingTokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _Out_ PHANDLE NewTokenHandle)
 Duplicates a token.
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtFilterToken (_In_ HANDLE ExistingTokenHandle, _In_ ULONG Flags, _In_opt_ PTOKEN_GROUPS SidsToDisable, _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, _In_opt_ PTOKEN_GROUPS RestrictedSids, _Out_ PHANDLE NewTokenHandle)
 Creates an access token in a restricted form from the original existing token, that is, such action is called filtering.
 
NTSYSCALLAPI NTSTATUS NTAPI NtImpersonateAnonymousToken (_In_ HANDLE ThreadHandle)
 Allows the calling thread to impersonate the system's anonymous logon token.
 
__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtOpenObjectAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_opt_ PVOID HandleId, _In_ PUNICODE_STRING ObjectTypeName, _In_ PUNICODE_STRING ObjectName, _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK GrantedAccess, _In_opt_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN ObjectCreation, _In_ BOOLEAN AccessGranted, _Out_ PBOOLEAN GenerateOnClose)
 Raises an alarm audit message when an object is about to be opened.
 
NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcessTokenEx (_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegeCheck (_In_ HANDLE ClientToken, _Inout_ PPRIVILEGE_SET RequiredPrivileges, _Out_ PBOOLEAN Result)
 
NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegedServiceAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_ PUNICODE_STRING ServiceName, _In_ HANDLE ClientToken, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted)
 
__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegeObjectAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_opt_ PVOID HandleId, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted)
 
 _When_ (TokenInformationClass==TokenAccessInformation, _At_(TokenInformationLength, _In_range_(>=, sizeof(TOKEN_ACCESS_INFORMATION)))) _Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtQueryInformationToken(_In_ HANDLE TokenHandle
 
_In_ TOKEN_INFORMATION_CLASS _Out_writes_bytes_to_opt_ (TokenInformationLength, *ReturnLength) PVOID TokenInformation
 
_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationToken (_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _In_reads_bytes_(TokenInformationLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength)
 Sets (modifies) some specific information in regard of an access token. The calling thread must have specific access rights in order to modify token's information data.
 
NTSYSAPI NTSTATUS NTAPI ZwAccessCheck (_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ HANDLE ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ PGENERIC_MAPPING GenericMapping, _Out_ PPRIVILEGE_SET PrivilegeSet, _Out_ PULONG ReturnLength, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
 
NTSYSAPI NTSTATUS NTAPI ZwAdjustGroupsToken (_In_ HANDLE TokenHandle, _In_ BOOLEAN ResetToDefault, _In_ PTOKEN_GROUPS NewState, _In_ ULONG BufferLength, _Out_opt_ PTOKEN_GROUPS PreviousState, _Out_ PULONG ReturnLength)
 
_Must_inspect_result_ NTSYSAPI NTSTATUS NTAPI ZwAdjustPrivilegesToken (_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState !=NULL, _Out_) PULONG ReturnLength)
 
NTSYSAPI NTSTATUS NTAPI ZwAllocateLocallyUniqueId (_Out_ LUID *LocallyUniqueId)
 
NTSYSAPI NTSTATUS NTAPI ZwAllocateUuids (_Out_ PULARGE_INTEGER Time, _Out_ PULONG Range, _Out_ PULONG Sequence, _Out_ PUCHAR Seed)
 
NTSYSAPI NTSTATUS NTAPI ZwCreateToken (_Out_ PHANDLE TokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PTOKEN_USER TokenUser, _In_ PTOKEN_GROUPS TokenGroups, _In_ PTOKEN_PRIVILEGES TokenPrivileges, _In_ PTOKEN_OWNER TokenOwner, _In_ PTOKEN_PRIMARY_GROUP TokenPrimaryGroup, _In_ PTOKEN_DEFAULT_DACL TokenDefaultDacl, _In_ PTOKEN_SOURCE TokenSource)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL) NTSYSAPI NTSTATUS NTAPI ZwDuplicateToken(_In_ HANDLE ExistingTokenHandle
 Queries information details about a security descriptor.
 
NTSYSAPI NTSTATUS NTAPI ZwImpersonateAnonymousToken (_In_ HANDLE Thread)
 
NTSYSAPI NTSTATUS NTAPI ZwOpenObjectAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_ PVOID HandleId, _In_ PUNICODE_STRING ObjectTypeName, _In_ PUNICODE_STRING ObjectName, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ HANDLE ClientToken, _In_ ULONG DesiredAccess, _In_ ULONG GrantedAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN ObjectCreation, _In_ BOOLEAN AccessGranted, _Out_ PBOOLEAN GenerateOnClose)
 
NTSYSAPI NTSTATUS NTAPI ZwOpenProcessTokenEx (_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
 
NTSYSAPI NTSTATUS NTAPI ZwPrivilegeCheck (_In_ HANDLE ClientToken, _In_ PPRIVILEGE_SET RequiredPrivileges, _In_ PBOOLEAN Result)
 
NTSYSAPI NTSTATUS NTAPI ZwPrivilegedServiceAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_ PUNICODE_STRING ServiceName, _In_ HANDLE ClientToken, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted)
 
NTSYSAPI NTSTATUS NTAPI ZwPrivilegeObjectAuditAlarm (_In_ PUNICODE_STRING SubsystemName, _In_ PVOID HandleId, _In_ HANDLE ClientToken, _In_ ULONG DesiredAccess, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted)
 
_In_ TOKEN_INFORMATION_CLASS _Out_writes_bytes_to_opt_ (Length, *ResultLength) PVOID TokenInformation
 
NTSYSAPI NTSTATUS NTAPI ZwSetInformationToken (_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_ PVOID TokenInformation, _In_ ULONG TokenInformationLength)
 

Variables

_In_ TOKEN_INFORMATION_CLASS TokenInformationClass
 
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG TokenInformationLength
 
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG _Out_ PULONG ReturnLength
 
_In_ ACCESS_MASK DesiredAccess
 
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes
 
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
 
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
 
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE _Out_ PHANDLE NewTokenHandle
 
_In_ ACCESS_MASK _Out_ PHANDLE TokenHandle
 
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG Length
 
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG _Out_ PULONG ResultLength
 

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Queries information details about a security descriptor.

Computes the quota size of a security descriptor.

Assigns a security descriptor for a new object.

An extended function that assigns a security descriptor for a new object.

Frees a security descriptor.

An extended function that sets new information data to a security descriptor.

Modifies some information data about a security descriptor.

Parameters
[in]SecurityInformationSecurity information details to be queried from a security descriptor.
[out]SecurityDescriptorThe returned security descriptor with security information data.
[in,out]LengthThe returned length of a security descriptor.
[in,out]ObjectsSecurityDescriptorThe returned object security descriptor.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the specific information about the security descriptor has been queried. STATUS_BUFFER_TOO_SMALL is returned if the buffer size is too small to contain the queried info about the security descriptor.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
See SeSetSecurityDescriptorInfoEx.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]AutoInheritFlagsFlags bitmask inheritation, influencing how the security descriptor can be inherited and if it can be in the first place.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
Returns STATUS_SUCCESS if the operations have been completed without problems and that new info has been set to the security descriptor. STATUS_NO_SECURITY_ON_OBJECT is returned if the object does not have a security descriptor. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the new security descriptor with new info set has failed.
Parameters
[in]SecurityDescriptorA security descriptor to be freed from memory.
Returns
Returns STATUS_SUCCESS.
Parameters
[in]_ParentDescriptorA security descriptor of the parent object that is being created.
[in]_ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]ObjectTypeThe type of the new object.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]AutoInheritFlagsAutomatic inheritance flags that influence how access control entries within ACLs from security descriptors are inherited.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the security descriptor has been assigned to the new object. STATUS_NO_TOKEN is returned if the caller hasn't supplied a valid argument to a security subject context. STATUS_INVALID_OWNER is returned if the caller hasn't supplied a parent descriptor that belongs to the main user (owner). STATUS_INVALID_PRIMARY_GROUP is returned by the same reason as with the previous NTSTATUS code. The two NTSTATUS codes are returned if the calling thread stated that the owner and/or group is defaulted to the parent descriptor (SEF_DEFAULT_OWNER_FROM_PARENT and/or SEF_DEFAULT_GROUP_FROM_PARENT respectively). STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the descriptor buffer has failed. A failure NTSTATUS is returned otherwise.
Parameters
[in]ParentDescriptorA security descriptor of the parent object that is being created.
[in]ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
See SeAssignSecurityEx.
Parameters
[in]SecurityDescriptorA security descriptor.
[out]QuotaInfoSizeThe returned quota size of the given security descriptor to the caller. The function may return 0 to this parameter if the descriptor doesn't have a group or a discretionary access control list (DACL) even.
Returns
Returns STATUS_SUCCESS if the quota size of a security descriptor has been computed successfully. STATUS_UNKNOWN_REVISION is returned if the security descriptor has an invalid revision.

Definition at line 923 of file Messaging.c.

75{
76 PFLT_SERVER_PORT_OBJECT PortObject;
78
79 /* The caller must allow at least one connection */
80 if (MaxConnections == 0)
81 {
83 }
84
85 /* The request must be for a kernel handle */
86 if (!(ObjectAttributes->Attributes & OBJ_KERNEL_HANDLE))
87 {
89 }
90
91 /*
92 * Get rundown protection on the target to stop the owner
93 * from unloading whilst this port object is open. It gets
94 * removed in the FltpServerPortClose callback
95 */
97 if (!NT_SUCCESS(Status))
98 {
99 return Status;
100 }
101
102 /* Create the server port object for this filter */
107 NULL,
109 0,
110 0,
111 (PVOID *)&PortObject);
112 if (NT_SUCCESS(Status))
113 {
114 /* Zero out the struct */
115 RtlZeroMemory(PortObject, sizeof(FLT_SERVER_PORT_OBJECT));
116
117 /* Increment the ref count on the target filter */
119
120 /* Setup the filter port object */
121 PortObject->Filter = Filter;
125 PortObject->Cookie = ServerPortCookie;
126 PortObject->MaxConnections = MaxConnections;
127
128 /* Insert the object */
129 Status = ObInsertObject(PortObject,
130 NULL,
132 0,
133 NULL,
135 if (NT_SUCCESS(Status))
136 {
137 /* Lock the connection list */
139
140 /* Add the new port object to the connection list and increment the count */
143
144 /* Unlock the connection list*/
146 }
147 }
148
149 if (!NT_SUCCESS(Status))
150 {
151 /* Allow the filter to be cleaned up */
153 }
154
155 return Status;
156}
static const INTERNET_PORT ServerPort
Definition: CWebService.cpp:11
POBJECT_TYPE ServerPortObjectType
Definition: Messaging.c:24
VOID FLTAPI FltObjectDereference(_Inout_ PVOID Object)
Definition: Object.c:53
NTSTATUS FLTAPI FltObjectReference(_Inout_ PVOID Object)
Definition: Object.c:41
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY _In_ PFLT_DISCONNECT_NOTIFY _In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback
Definition: fltkernel.h:1877
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback
Definition: fltkernel.h:1875
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID ServerPortCookie
Definition: fltkernel.h:1874
_Must_inspect_result_ _Outptr_ PFLT_PORT _In_ POBJECT_ATTRIBUTES _In_opt_ PVOID _In_ PFLT_CONNECT_NOTIFY _In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback
Definition: fltkernel.h:1876
ULONG FltpObjectPointerReference(_In_ PFLT_OBJECT Object)
Definition: Object.c:322
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
static LONG MaxConnections
#define KernelMode
Definition: asm.h:34
#define FILE_READ_DATA
Definition: nt_native.h:628
#define STANDARD_RIGHTS_ALL
Definition: nt_native.h:69
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
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
FLT_MUTEX_LIST_HEAD ConnectionList
Definition: fltmgrint.h:121
LIST_ENTRY mList
Definition: fltmgrint.h:56
FAST_MUTEX mLock
Definition: fltmgrint.h:55
PFLT_DISCONNECT_NOTIFY DisconnectNotify
Definition: fltmgrint.h:192
PFLT_MESSAGE_NOTIFY MessageNotify
Definition: fltmgrint.h:193
PFLT_CONNECT_NOTIFY ConnectNotify
Definition: fltmgrint.h:191
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ _Out_writes_bytes_to_opt_() [1/2]

_In_ TOKEN_INFORMATION_CLASS _Out_writes_bytes_to_opt_ ( Length  ,
ResultLength 
)

◆ _Out_writes_bytes_to_opt_() [2/2]

_In_ TOKEN_INFORMATION_CLASS _Out_writes_bytes_to_opt_ ( TokenInformationLength  ,
ReturnLength 
)

◆ _When_()

◆ NtAccessCheck()

NTSYSCALLAPI NTSTATUS NTAPI NtAccessCheck ( _In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ HANDLE  ClientToken,
_In_ ACCESS_MASK  DesiredAccess,
_In_ PGENERIC_MAPPING  GenericMapping,
_Out_ PPRIVILEGE_SET  PrivilegeSet,
_Out_ PULONG  ReturnLength,
_Out_ PACCESS_MASK  GrantedAccess,
_Out_ PNTSTATUS  AccessStatus 
)

◆ NtAccessCheckAndAuditAlarm()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAccessCheckAndAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_opt_ PVOID  HandleId,
_In_ PUNICODE_STRING  ObjectTypeName,
_In_ PUNICODE_STRING  ObjectName,
_In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ ACCESS_MASK  DesiredAccess,
_In_ PGENERIC_MAPPING  GenericMapping,
_In_ BOOLEAN  ObjectCreation,
_Out_ PACCESS_MASK  GrantedAccess,
_Out_ PNTSTATUS  AccessStatus,
_Out_ PBOOLEAN  GenerateOnClose 
)

Raises an alarm audit message when a caller attempts to access an object and determine if the access can be made.

Parameters
[in]SubsystemNameA Unicode string that points to a name of the subsystem.
[in]HandleIdA handle to an ID that is used as identification instance for auditing.
[in]ObjectTypeNameThe name of the object type.
[in]ObjectNameThe object name.
[in]SecurityDescriptorA security descriptor.
[in]DesiredAccessThe desired access rights masks requested by the caller.
[in]GenericMappingThe generic mapping of access mask rights.
[in]ObjectCreationSet this to TRUE if the object has just been created.
[out]GrantedAccessReturns the granted access rights.
[out]AccessStatusReturns a NTSTATUS status code indicating whether access check can be granted or not.
[out]GenerateOnCloseReturns TRUE if the function has generated a list of granted access rights and status codes on termination, FALSE otherwise.
Returns
See SepAccessCheckAndAuditAlarm.

Definition at line 2125 of file audit.c.

2137{
2138 /* Call the internal function */
2139 return SepAccessCheckAndAuditAlarm(SubsystemName,
2140 HandleId,
2141 NULL,
2143 ObjectName,
2145 NULL,
2148 0,
2149 NULL,
2150 0,
2155 FALSE);
2156}
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
#define FALSE
Definition: types.h:117
static POBJECTS_AND_NAME_A SE_OBJECT_TYPE LPSTR ObjectTypeName
Definition: security.c:79
_Must_inspect_result_ NTSTATUS NTAPI SepAccessCheckAndAuditAlarm(_In_ PUNICODE_STRING SubsystemName, _In_opt_ PVOID HandleId, _In_ PHANDLE ClientTokenHandle, _In_ PUNICODE_STRING ObjectTypeName, _In_ PUNICODE_STRING ObjectName, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_opt_ PSID PrincipalSelfSid, _In_ ACCESS_MASK DesiredAccess, _In_ AUDIT_EVENT_TYPE AuditType, _In_ ULONG Flags, _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, _In_ ULONG ObjectTypeListLength, _In_ PGENERIC_MAPPING GenericMapping, _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccessList, _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatusList, _Out_ PBOOLEAN GenerateOnClose, _In_ BOOLEAN UseResultList)
Performs security auditing, if the specific object can be granted security access or not.
Definition: audit.c:614
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_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_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE _In_ BOOLEAN _In_ BOOLEAN _In_ KPROCESSOR_MODE _In_opt_ GUID _Out_ PBOOLEAN GenerateOnClose
Definition: sefuncs.h:422
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK _Out_ PNTSTATUS AccessStatus
Definition: sefuncs.h:21
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20
@ AuditEventObjectAccess
Definition: setypes.h:864

◆ NtAccessCheckByType()

NTSTATUS NTAPI NtAccessCheckByType ( _In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ PSID  PrincipalSelfSid,
_In_ HANDLE  ClientToken,
_In_ ACCESS_MASK  DesiredAccess,
_In_ POBJECT_TYPE_LIST  ObjectTypeList,
_In_ ULONG  ObjectTypeLength,
_In_ PGENERIC_MAPPING  GenericMapping,
_In_ PPRIVILEGE_SET  PrivilegeSet,
_Inout_ PULONG  PrivilegeSetLength,
_Out_ PACCESS_MASK  GrantedAccess,
_Out_ PNTSTATUS  AccessStatus 
)

Determines whether security access could be granted or not on an object by the requestor who wants such access through type.

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

Definition at line 1330 of file accesschk.c.

1342{
1345}
#define UNIMPLEMENTED
Definition: debug.h:115
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ NtAccessCheckByTypeResultList()

NTSTATUS NTAPI NtAccessCheckByTypeResultList ( _In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ PSID  PrincipalSelfSid,
_In_ HANDLE  ClientToken,
_In_ ACCESS_MASK  DesiredAccess,
_In_ POBJECT_TYPE_LIST  ObjectTypeList,
_In_ ULONG  ObjectTypeLength,
_In_ PGENERIC_MAPPING  GenericMapping,
_In_ PPRIVILEGE_SET  PrivilegeSet,
_Inout_ PULONG  PrivilegeSetLength,
_Out_ PACCESS_MASK  GrantedAccess,
_Out_ PNTSTATUS  AccessStatus 
)

Determines whether security access could be granted or not on an object by the requestor who wants such access through type list.

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

Definition at line 1392 of file accesschk.c.

1404{
1407}

◆ NtAdjustGroupsToken()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAdjustGroupsToken ( _In_ HANDLE  TokenHandle,
_In_ BOOLEAN  ResetToDefault,
_In_opt_ PTOKEN_GROUPS  NewState,
_In_opt_ ULONG  BufferLength,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_GROUPS  PreviousState,
_When_(PreviousState !=NULL, _Out_) PULONG  ReturnLength 
)

◆ NtAdjustPrivilegesToken()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtAdjustPrivilegesToken ( _In_ HANDLE  TokenHandle,
_In_ BOOLEAN  DisableAllPrivileges,
_In_opt_ PTOKEN_PRIVILEGES  NewState,
_In_ ULONG  BufferLength,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES  PreviousState,
_When_(PreviousState !=NULL, _Out_) PULONG  ReturnLength 
)

◆ NtAllocateLocallyUniqueId()

NTSYSCALLAPI NTSTATUS NTAPI NtAllocateLocallyUniqueId ( _Out_ LUID LocallyUniqueId)

◆ NtAllocateUuids()

NTSYSCALLAPI NTSTATUS NTAPI NtAllocateUuids ( _Out_ PULARGE_INTEGER  Time,
_Out_ PULONG  Range,
_Out_ PULONG  Sequence,
_Out_ PUCHAR  Seed 
)

◆ NtCompareTokens()

NTSYSCALLAPI NTSTATUS NTAPI NtCompareTokens ( _In_ HANDLE  FirstTokenHandle,
_In_ HANDLE  SecondTokenHandle,
_Out_ PBOOLEAN  Equal 
)

Compares tokens if they're equal or not.

Parameters
[in]FirstTokenThe first token.
[in]SecondTokenThe second token.
[out]EqualThe retrieved value which determines if the tokens are equal or not.
Returns
Returns STATUS_SUCCESS, otherwise it returns a failure NTSTATUS code.

Definition at line 2310 of file token.c.

2314{
2316 PTOKEN FirstToken, SecondToken;
2319
2320 PAGED_CODE();
2321
2323
2324 if (PreviousMode != KernelMode)
2325 {
2326 _SEH2_TRY
2327 {
2328 ProbeForWriteBoolean(Equal);
2329 }
2331 {
2332 /* Return the exception code */
2334 }
2335 _SEH2_END;
2336 }
2337
2338 Status = ObReferenceObjectByHandle(FirstTokenHandle,
2342 (PVOID*)&FirstToken,
2343 NULL);
2344 if (!NT_SUCCESS(Status))
2345 {
2346 DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2347 return Status;
2348 }
2349
2350 Status = ObReferenceObjectByHandle(SecondTokenHandle,
2354 (PVOID*)&SecondToken,
2355 NULL);
2356 if (!NT_SUCCESS(Status))
2357 {
2358 DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2359 ObDereferenceObject(FirstToken);
2360 return Status;
2361 }
2362
2363 if (FirstToken != SecondToken)
2364 {
2365 Status = SepCompareTokens(FirstToken,
2366 SecondToken,
2367 &IsEqual);
2368 }
2369 else
2370 {
2371 IsEqual = TRUE;
2372 }
2373
2374 ObDereferenceObject(SecondToken);
2375 ObDereferenceObject(FirstToken);
2376
2377 if (NT_SUCCESS(Status))
2378 {
2379 _SEH2_TRY
2380 {
2381 *Equal = IsEqual;
2382 }
2384 {
2386 }
2387 _SEH2_END;
2388 }
2389
2390 return Status;
2391}
#define PAGED_CODE()
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define ExGetPreviousMode
Definition: ex.h:139
@ IsEqual
Definition: fatprocs.h:1886
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
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
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define ProbeForWriteBoolean(Ptr)
Definition: probe.h:31
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TOKEN_QUERY
Definition: setypes.h:924

Referenced by START_TEST().

◆ NtCreateToken()

__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtCreateToken ( _Out_ PHANDLE  TokenHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ TOKEN_TYPE  TokenType,
_In_ PLUID  AuthenticationId,
_In_ PLARGE_INTEGER  ExpirationTime,
_In_ PTOKEN_USER  TokenUser,
_In_ PTOKEN_GROUPS  TokenGroups,
_In_ PTOKEN_PRIVILEGES  TokenPrivileges,
_In_opt_ PTOKEN_OWNER  TokenOwner,
_In_ PTOKEN_PRIMARY_GROUP  TokenPrimaryGroup,
_In_opt_ PTOKEN_DEFAULT_DACL  TokenDefaultDacl,
_In_ PTOKEN_SOURCE  TokenSource 
)

Creates an access token.

Parameters
[out]TokenHandleThe returned created token handle to the caller.
[in]DesiredAccessThe desired access rights for the token that we're creating.
[in]ObjectAttributesThe object attributes for the token object that we're creating.
[in]TokenTypeThe type of token to assign for the newly created token.
[in]AuthenticationIdAuthentication ID that represents the token's identity.
[in]ExpirationTimeExpiration time for the token. If set to -1, the token never expires.
[in]TokenUserThe main user entity for the token to assign.
[in]TokenGroupsGroup list of SIDs for the token to assign.
[in]TokenPrivilegesPrivileges for the token.
[in]TokenOwnerThe main user that owns the newly created token.
[in]TokenPrimaryGroupThe primary group that represents as the main group of the token.
[in]TokenDefaultDaclDiscretionary access control list for the token. This limits on how the token can be used, accessed and used by whom.
[in]TokenSourceThe source origin of the token who creates it.
Returns
Returns STATUS_SUCCESS if the function has successfully created the token. A failure NTSTATUS code is returned otherwise.

Definition at line 1554 of file tokenlif.c.

1568{
1569 HANDLE hToken;
1571 ULONG PrivilegeCount, GroupCount;
1572 PSID OwnerSid, PrimaryGroupSid;
1573 PACL DefaultDacl;
1574 LARGE_INTEGER LocalExpirationTime = {{0, 0}};
1575 LUID LocalAuthenticationId;
1576 TOKEN_SOURCE LocalTokenSource;
1577 SECURITY_QUALITY_OF_SERVICE LocalSecurityQos;
1578 PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL;
1579 PSID_AND_ATTRIBUTES CapturedUser = NULL;
1580 PSID_AND_ATTRIBUTES CapturedGroups = NULL;
1581 PSID CapturedOwnerSid = NULL;
1582 PSID CapturedPrimaryGroupSid = NULL;
1583 PACL CapturedDefaultDacl = NULL;
1584 ULONG PrivilegesLength, UserLength, GroupsLength;
1586
1587 PAGED_CODE();
1588
1590
1591 if (PreviousMode != KernelMode)
1592 {
1593 _SEH2_TRY
1594 {
1596
1597 if (ObjectAttributes != NULL)
1598 {
1600 sizeof(OBJECT_ATTRIBUTES),
1601 sizeof(ULONG));
1602 LocalSecurityQos = *(SECURITY_QUALITY_OF_SERVICE*)ObjectAttributes->SecurityQualityOfService;
1603 }
1604
1605 ProbeForRead(AuthenticationId,
1606 sizeof(LUID),
1607 sizeof(ULONG));
1608 LocalAuthenticationId = *AuthenticationId;
1609
1610 LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime);
1611
1613 sizeof(TOKEN_USER),
1614 sizeof(ULONG));
1615
1617 sizeof(TOKEN_GROUPS),
1618 sizeof(ULONG));
1619 GroupCount = TokenGroups->GroupCount;
1620
1622 sizeof(TOKEN_PRIVILEGES),
1623 sizeof(ULONG));
1624 PrivilegeCount = TokenPrivileges->PrivilegeCount;
1625
1626 if (TokenOwner != NULL)
1627 {
1629 sizeof(TOKEN_OWNER),
1630 sizeof(ULONG));
1631 OwnerSid = TokenOwner->Owner;
1632 }
1633 else
1634 {
1635 OwnerSid = NULL;
1636 }
1637
1639 sizeof(TOKEN_PRIMARY_GROUP),
1640 sizeof(ULONG));
1641 PrimaryGroupSid = TokenPrimaryGroup->PrimaryGroup;
1642
1643 if (TokenDefaultDacl != NULL)
1644 {
1646 sizeof(TOKEN_DEFAULT_DACL),
1647 sizeof(ULONG));
1648 DefaultDacl = TokenDefaultDacl->DefaultDacl;
1649 }
1650 else
1651 {
1652 DefaultDacl = NULL;
1653 }
1654
1656 sizeof(TOKEN_SOURCE),
1657 sizeof(ULONG));
1658 LocalTokenSource = *TokenSource;
1659 }
1661 {
1662 /* Return the exception code */
1664 }
1665 _SEH2_END;
1666 }
1667 else
1668 {
1669 if (ObjectAttributes != NULL)
1670 LocalSecurityQos = *(SECURITY_QUALITY_OF_SERVICE*)ObjectAttributes->SecurityQualityOfService;
1671 LocalAuthenticationId = *AuthenticationId;
1672 LocalExpirationTime = *ExpirationTime;
1673 GroupCount = TokenGroups->GroupCount;
1674 PrivilegeCount = TokenPrivileges->PrivilegeCount;
1675 OwnerSid = TokenOwner ? TokenOwner->Owner : NULL;
1676 PrimaryGroupSid = TokenPrimaryGroup->PrimaryGroup;
1677 DefaultDacl = TokenDefaultDacl ? TokenDefaultDacl->DefaultDacl : NULL;
1678 LocalTokenSource = *TokenSource;
1679 }
1680
1681 /* Check token type */
1682 if ((TokenType < TokenPrimary) ||
1684 {
1685 return STATUS_BAD_TOKEN_TYPE;
1686 }
1687
1688 /* Check for token creation privilege */
1690 {
1692 }
1693
1694 /* Capture the user SID and attributes */
1696 1,
1698 NULL,
1699 0,
1700 PagedPool,
1701 FALSE,
1702 &CapturedUser,
1703 &UserLength);
1704 if (!NT_SUCCESS(Status))
1705 {
1706 goto Cleanup;
1707 }
1708
1709 /* Capture the groups SID and attributes array */
1711 GroupCount,
1713 NULL,
1714 0,
1715 PagedPool,
1716 FALSE,
1717 &CapturedGroups,
1718 &GroupsLength);
1719 if (!NT_SUCCESS(Status))
1720 {
1721 goto Cleanup;
1722 }
1723
1724 /* Capture privileges */
1726 PrivilegeCount,
1728 NULL,
1729 0,
1730 PagedPool,
1731 FALSE,
1732 &CapturedPrivileges,
1733 &PrivilegesLength);
1734 if (!NT_SUCCESS(Status))
1735 {
1736 goto Cleanup;
1737 }
1738
1739 /* Capture the token owner SID */
1740 if (TokenOwner != NULL)
1741 {
1742 Status = SepCaptureSid(OwnerSid,
1744 PagedPool,
1745 FALSE,
1746 &CapturedOwnerSid);
1747 if (!NT_SUCCESS(Status))
1748 {
1749 goto Cleanup;
1750 }
1751 }
1752
1753 /* Capture the token primary group SID */
1754 Status = SepCaptureSid(PrimaryGroupSid,
1756 PagedPool,
1757 FALSE,
1758 &CapturedPrimaryGroupSid);
1759 if (!NT_SUCCESS(Status))
1760 {
1761 goto Cleanup;
1762 }
1763
1764 /* Capture DefaultDacl */
1765 if (DefaultDacl != NULL)
1766 {
1767 Status = SepCaptureAcl(DefaultDacl,
1770 FALSE,
1771 &CapturedDefaultDacl);
1772 if (!NT_SUCCESS(Status))
1773 {
1774 goto Cleanup;
1775 }
1776 }
1777
1778 /* Call the internal function */
1779 Status = SepCreateToken(&hToken,
1783 TokenType,
1784 LocalSecurityQos.ImpersonationLevel,
1785 &LocalAuthenticationId,
1786 &LocalExpirationTime,
1787 CapturedUser,
1788 GroupCount,
1789 CapturedGroups,
1790 GroupsLength,
1791 PrivilegeCount,
1792 CapturedPrivileges,
1793 CapturedOwnerSid,
1794 CapturedPrimaryGroupSid,
1795 CapturedDefaultDacl,
1796 &LocalTokenSource,
1797 FALSE);
1798 if (NT_SUCCESS(Status))
1799 {
1800 _SEH2_TRY
1801 {
1802 *TokenHandle = hToken;
1803 }
1805 {
1807 }
1808 _SEH2_END;
1809 }
1810
1811Cleanup:
1812
1813 /* Release what we captured */
1817 SepReleaseSid(CapturedOwnerSid, PreviousMode, FALSE);
1818 SepReleaseSid(CapturedPrimaryGroupSid, PreviousMode, FALSE);
1819 SepReleaseAcl(CapturedDefaultDacl, PreviousMode, FALSE);
1820
1821 return Status;
1822}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
static const WCHAR Cleanup[]
Definition: register.c:80
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
@ TokenImpersonation
Definition: imports.h:274
@ TokenPrimary
Definition: imports.h:273
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:718
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:404
VOID NTAPI SepReleaseSid(_In_ PSID CapturedSid, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
Releases a captured SID.
Definition: sid.c:400
NTSTATUS NTAPI SepCaptureSid(_In_ PSID InputSid, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSID *CapturedSid)
Captures a SID.
Definition: sid.c:314
const LUID SeCreateTokenPrivilege
Definition: priv.c:21
VOID NTAPI SeReleaseSidAndAttributesArray(_In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
Releases a captured SID with attributes.
Definition: sid.c:994
VOID NTAPI SepReleaseAcl(_In_ PACL CapturedAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
Releases (frees) a captured ACL from the memory pool.
Definition: acl.c:464
VOID NTAPI SeReleaseLuidAndAttributesArray(_In_ PLUID_AND_ATTRIBUTES Privilege, _In_ KPROCESSOR_MODE PreviousMode, _In_ BOOLEAN CaptureIfKernel)
Releases a LUID with attributes structure.
Definition: priv.c:554
NTSTATUS NTAPI 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.
Definition: acl.c:352
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.
Definition: sid.c:711
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)
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_BAD_TOKEN_TYPE
Definition: ntstatus.h:404
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
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
uint32_t ULONG
Definition: typedefs.h:59
@ TokenDefaultDacl
Definition: setypes.h:967
@ TokenSource
Definition: setypes.h:968
@ TokenGroups
Definition: setypes.h:963
@ TokenPrivileges
Definition: setypes.h:964
@ TokenUser
Definition: setypes.h:962
@ TokenPrimaryGroup
Definition: setypes.h:966
@ TokenOwner
Definition: setypes.h:965

Referenced by LsapLogonUser().

◆ NtDuplicateToken()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtDuplicateToken ( _In_ HANDLE  ExistingTokenHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ BOOLEAN  EffectiveOnly,
_In_ TOKEN_TYPE  TokenType,
_Out_ PHANDLE  NewTokenHandle 
)

Duplicates a token.

Parameters
[in]ExistingTokenHandleAn existing token to duplicate.
[in]DesiredAccessThe desired access rights for the new duplicated token.
[in]ObjectAttributesObject attributes for the new duplicated token.
[in]EffectiveOnlyIf set to TRUE, the function removes all the disabled privileges and groups of the token to duplicate.
[in]TokenTypeType of token to assign to the duplicated token.
[out]NewTokenHandleThe returned duplicated token handle.
Returns
STATUS_SUCCESS is returned if token duplication has completed successfully. STATUS_BAD_IMPERSONATION_LEVEL is returned if the caller erroneously wants to raise the impersonation level even though the conditions do not permit it. A failure NTSTATUS code is returned otherwise.
Remarks
Some sources claim 4th param is ImpersonationLevel, but on W2K this is certainly NOT true, although I can't say for sure that EffectiveOnly is correct either. -Gunnar This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore wrong in that regard, while MSDN documentation is correct.

Definition at line 1865 of file tokenlif.c.

1872{
1874 HANDLE hToken;
1875 PTOKEN Token;
1876 PTOKEN NewToken;
1877 PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
1878 BOOLEAN QoSPresent;
1881
1882 PAGED_CODE();
1883
1886 {
1888 }
1889
1891
1892 if (PreviousMode != KernelMode)
1893 {
1894 _SEH2_TRY
1895 {
1897 }
1899 {
1900 /* Return the exception code */
1902 }
1903 _SEH2_END;
1904 }
1905
1908 PagedPool,
1909 FALSE,
1910 &CapturedSecurityQualityOfService,
1911 &QoSPresent);
1912 if (!NT_SUCCESS(Status))
1913 {
1914 DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
1915 return Status;
1916 }
1917
1918 Status = ObReferenceObjectByHandle(ExistingTokenHandle,
1922 (PVOID*)&Token,
1924 if (!NT_SUCCESS(Status))
1925 {
1926 DPRINT1("Failed to reference token (Status 0x%lx)\n", Status);
1927 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
1929 FALSE);
1930 return Status;
1931 }
1932
1933 /*
1934 * Fail, if the original token is an impersonation token and the caller
1935 * tries to raise the impersonation level of the new token above the
1936 * impersonation level of the original token.
1937 */
1938 if (Token->TokenType == TokenImpersonation)
1939 {
1940 if (QoSPresent &&
1941 CapturedSecurityQualityOfService->ImpersonationLevel >Token->ImpersonationLevel)
1942 {
1944 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
1946 FALSE);
1948 }
1949 }
1950
1951 /*
1952 * Fail, if a primary token is to be created from an impersonation token
1953 * and and the impersonation level of the impersonation token is below SecurityImpersonation.
1954 */
1955 if (Token->TokenType == TokenImpersonation &&
1957 Token->ImpersonationLevel < SecurityImpersonation)
1958 {
1960 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
1962 FALSE);
1964 }
1965
1969 TokenType,
1970 (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous),
1972 &NewToken);
1973
1975
1976 if (NT_SUCCESS(Status))
1977 {
1978 Status = ObInsertObject(NewToken,
1979 NULL,
1980 (DesiredAccess ? DesiredAccess : HandleInformation.GrantedAccess),
1981 0,
1982 NULL,
1983 &hToken);
1984 if (NT_SUCCESS(Status))
1985 {
1986 _SEH2_TRY
1987 {
1988 *NewTokenHandle = hToken;
1989 }
1991 {
1993 }
1994 _SEH2_END;
1995 }
1996 }
1997
1998 /* Free the captured structure */
1999 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
2001 FALSE);
2002
2003 return Status;
2004}
@ SecurityImpersonation
Definition: lsa.idl:57
@ SecurityAnonymous
Definition: lsa.idl:55
#define KeGetPreviousMode()
Definition: ketypes.h:1108
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:403
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE _Out_ PHANDLE NewTokenHandle
Definition: sefuncs.h:405
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.
Definition: sqos.c:52
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.
Definition: sqos.c:225
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
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
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44
#define TOKEN_DUPLICATE
Definition: setypes.h:922

◆ NtFilterToken()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtFilterToken ( _In_ HANDLE  ExistingTokenHandle,
_In_ ULONG  Flags,
_In_opt_ PTOKEN_GROUPS  SidsToDisable,
_In_opt_ PTOKEN_PRIVILEGES  PrivilegesToDelete,
_In_opt_ PTOKEN_GROUPS  RestrictedSids,
_Out_ PHANDLE  NewTokenHandle 
)

Creates an access token in a restricted form from the original existing token, that is, such action is called filtering.

Parameters
[in]ExistingTokenHandleA handle to an access token which is to be filtered.
[in]FlagsPrivilege flag options. This parameter argument influences how the token's privileges are filtered. For further details see remarks.
[in]SidsToDisableArray of SIDs to disable. The action of doing so assigns the SE_GROUP_USE_FOR_DENY_ONLY attribute to the respective group SID and takes away SE_GROUP_ENABLED and SE_GROUP_ENABLED_BY_DEFAULT. This parameter can be NULL. This can be a UM pointer.
[in]PrivilegesToDeleteArray of privileges to delete. The function will walk within this array to determine if the specified privileges do exist in the access token. Any missing privileges gets ignored. This parameter can be NULL. This can be a UM pointer.
[in]RestrictedSidsAn array list of restricted groups SID to be added in the access token. A token that is already restricted the newly added restricted SIDs are redundant information in addition to the existing restricted SIDs in the token. This parameter can be NULL. This can be a UM pointer.
[out]NewTokenHandleA new handle to the restricted (filtered) access token. This can be a UM pointer.
Returns
Returns STATUS_SUCCESS if the routine has successfully filtered the access token. STATUS_INVALID_PARAMETER is returned if one or more parameters are not valid (see SepPerformTokenFiltering routine call for more information). A failure NTSTATUS code is returned otherwise.
Remarks
The Flags parameter determines the final outcome of how the privileges in an access token are filtered. This parameter can take these supported values (these can be combined):

0 – Filter the token's privileges in the usual way. The function expects that the caller MUST PROVIDE a valid array list of privileges to be deleted (that is, PrivilegesToDelete MUSTN'T BE NULL).

DISABLE_MAX_PRIVILEGE – Disables (deletes) all the privileges except SeChangeNotifyPrivilege in the new access token. Bear in mind if this flag is specified the routine ignores PrivilegesToDelete.

SANDBOX_INERT – Stores the TOKEN_SANDBOX_INERT token flag within the access token.

LUA_TOKEN – The newly filtered access token is a LUA token. This flag is not supported in Windows Server 2003.

WRITE_RESTRICTED – The newly filtered token has the restricted SIDs that are considered only when evaluating write access onto the token. This value is not supported in Windows Server 2003.

Definition at line 2071 of file tokenlif.c.

2078{
2079 PTOKEN Token, FilteredToken;
2080 HANDLE FilteredTokenHandle;
2083 OBJECT_HANDLE_INFORMATION HandleInfo;
2085 ULONG CapturedSidsCount = 0;
2086 ULONG CapturedPrivilegesCount = 0;
2087 ULONG CapturedRestrictedSidsCount = 0;
2088 ULONG ProbeSize = 0;
2089 PSID_AND_ATTRIBUTES CapturedSids = NULL;
2090 PSID_AND_ATTRIBUTES CapturedRestrictedSids = NULL;
2091 PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL;
2092
2093 PAGED_CODE();
2094
2096
2097 _SEH2_TRY
2098 {
2099 /* Probe SidsToDisable */
2100 if (SidsToDisable != NULL)
2101 {
2102 /* Probe the header */
2103 ProbeForRead(SidsToDisable, sizeof(*SidsToDisable), sizeof(ULONG));
2104
2105 CapturedSidsCount = SidsToDisable->GroupCount;
2106 ProbeSize = FIELD_OFFSET(TOKEN_GROUPS, Groups[CapturedSidsCount]);
2107
2108 ProbeForRead(SidsToDisable, ProbeSize, sizeof(ULONG));
2109 }
2110
2111 /* Probe PrivilegesToDelete */
2112 if (PrivilegesToDelete != NULL)
2113 {
2114 /* Probe the header */
2115 ProbeForRead(PrivilegesToDelete, sizeof(*PrivilegesToDelete), sizeof(ULONG));
2116
2117 CapturedPrivilegesCount = PrivilegesToDelete->PrivilegeCount;
2118 ProbeSize = FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges[CapturedPrivilegesCount]);
2119
2120 ProbeForRead(PrivilegesToDelete, ProbeSize, sizeof(ULONG));
2121 }
2122
2123 /* Probe RestrictedSids */
2124 if (RestrictedSids != NULL)
2125 {
2126 /* Probe the header */
2127 ProbeForRead(RestrictedSids, sizeof(*RestrictedSids), sizeof(ULONG));
2128
2129 CapturedRestrictedSidsCount = RestrictedSids->GroupCount;
2130 ProbeSize = FIELD_OFFSET(TOKEN_GROUPS, Groups[CapturedRestrictedSidsCount]);
2131
2132 ProbeForRead(RestrictedSids, ProbeSize, sizeof(ULONG));
2133 }
2134
2135 /* Probe the handle */
2137 }
2139 {
2140 /* Return the exception code */
2142 }
2143 _SEH2_END;
2144
2145 /* Reference the token */
2146 Status = ObReferenceObjectByHandle(ExistingTokenHandle,
2150 (PVOID*)&Token,
2151 &HandleInfo);
2152 if (!NT_SUCCESS(Status))
2153 {
2154 DPRINT1("NtFilterToken(): Failed to reference the token (Status 0x%lx)\n", Status);
2155 return Status;
2156 }
2157
2158 /* Capture the group SIDs */
2159 if (SidsToDisable != NULL)
2160 {
2161 Status = SeCaptureSidAndAttributesArray(SidsToDisable->Groups,
2162 CapturedSidsCount,
2164 NULL,
2165 0,
2166 PagedPool,
2167 TRUE,
2168 &CapturedSids,
2169 &ResultLength);
2170 if (!NT_SUCCESS(Status))
2171 {
2172 DPRINT1("NtFilterToken(): Failed to capture the SIDs (Status 0x%lx)\n", Status);
2173 goto Quit;
2174 }
2175 }
2176
2177 /* Capture the privileges */
2178 if (PrivilegesToDelete != NULL)
2179 {
2180 Status = SeCaptureLuidAndAttributesArray(PrivilegesToDelete->Privileges,
2181 CapturedPrivilegesCount,
2183 NULL,
2184 0,
2185 PagedPool,
2186 TRUE,
2187 &CapturedPrivileges,
2188 &ResultLength);
2189 if (!NT_SUCCESS(Status))
2190 {
2191 DPRINT1("NtFilterToken(): Failed to capture the privileges (Status 0x%lx)\n", Status);
2192 goto Quit;
2193 }
2194 }
2195
2196 /* Capture the restricted SIDs */
2197 if (RestrictedSids != NULL)
2198 {
2199 Status = SeCaptureSidAndAttributesArray(RestrictedSids->Groups,
2200 CapturedRestrictedSidsCount,
2202 NULL,
2203 0,
2204 PagedPool,
2205 TRUE,
2206 &CapturedRestrictedSids,
2207 &ResultLength);
2208 if (!NT_SUCCESS(Status))
2209 {
2210 DPRINT1("NtFilterToken(): Failed to capture the restricted SIDs (Status 0x%lx)\n", Status);
2211 goto Quit;
2212 }
2213 }
2214
2215 /* Call the internal API */
2217 CapturedPrivileges,
2218 CapturedSids,
2219 CapturedRestrictedSids,
2220 CapturedPrivilegesCount,
2221 CapturedSidsCount,
2222 CapturedRestrictedSidsCount,
2223 Flags,
2225 &FilteredToken);
2226 if (!NT_SUCCESS(Status))
2227 {
2228 DPRINT1("NtFilterToken(): Failed to filter the token (Status 0x%lx)\n", Status);
2229 goto Quit;
2230 }
2231
2232 /* Insert the filtered token and retrieve a handle to it */
2233 Status = ObInsertObject(FilteredToken,
2234 NULL,
2235 HandleInfo.GrantedAccess,
2236 0,
2237 NULL,
2238 &FilteredTokenHandle);
2239 if (!NT_SUCCESS(Status))
2240 {
2241 DPRINT1("NtFilterToken(): Failed to insert the filtered token (Status 0x%lx)\n", Status);
2242 goto Quit;
2243 }
2244
2245 /* And return it to the caller once we're done */
2246 _SEH2_TRY
2247 {
2248 *NewTokenHandle = FilteredTokenHandle;
2249 }
2251 {
2253 _SEH2_YIELD(goto Quit);
2254 }
2255 _SEH2_END;
2256
2257Quit:
2258 /* Dereference the token */
2260
2261 /* Release all the captured data */
2262 if (CapturedSids != NULL)
2263 {
2264 SeReleaseSidAndAttributesArray(CapturedSids,
2266 TRUE);
2267 }
2268
2269 if (CapturedPrivileges != NULL)
2270 {
2271 SeReleaseLuidAndAttributesArray(CapturedPrivileges,
2273 TRUE);
2274 }
2275
2276 if (CapturedRestrictedSids != NULL)
2277 {
2278 SeReleaseSidAndAttributesArray(CapturedRestrictedSids,
2280 TRUE);
2281 }
2282
2283 return Status;
2284}
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
static NTSTATUS SepPerformTokenFiltering(_In_ PTOKEN Token, _In_opt_ PLUID_AND_ATTRIBUTES PrivilegesToBeDeleted, _In_opt_ PSID_AND_ATTRIBUTES SidsToBeDisabled, _In_opt_ PSID_AND_ATTRIBUTES RestrictedSidsIntoToken, _When_(PrivilegesToBeDeleted !=NULL, _In_) ULONG PrivilegesCount, _When_(SidsToBeDisabled !=NULL, _In_) ULONG RegularGroupsSidCount, _When_(RestrictedSidsIntoToken !=NULL, _In_) ULONG RestrictedSidsCount, _In_ ULONG PrivilegeFlags, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PTOKEN *FilteredToken)
Private helper function responsible for creating a restricted access token, that is,...
Definition: tokenlif.c:855
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17

◆ NtImpersonateAnonymousToken()

NTSYSCALLAPI NTSTATUS NTAPI NtImpersonateAnonymousToken ( _In_ HANDLE  ThreadHandle)

Allows the calling thread to impersonate the system's anonymous logon token.

Parameters
[in]ThreadHandleA handle to the thread to start the procedure of logon token impersonation. The thread must have the THREAD_IMPERSONATE access right.
Returns
Returns STATUS_SUCCESS if the thread has successfully impersonated the anonymous logon token, otherwise a failure NTSTATUS code is returned.
Remarks
By default the system gives the opportunity to the caller to impersonate the anonymous logon token without including the Everyone Group SID. In cases where the caller wants to impersonate the token including such group, the EveryoneIncludesAnonymous registry value setting has to be set to 1, from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa registry path. The calling thread must invoke PsRevertToSelf when impersonation is no longer needed or RevertToSelf if the calling execution is done in user mode.

Definition at line 2419 of file token.c.

2421{
2425 PAGED_CODE();
2426
2428
2429 /* Obtain the thread object from the handle */
2430 Status = ObReferenceObjectByHandle(ThreadHandle,
2434 (PVOID*)&Thread,
2435 NULL);
2436 if (!NT_SUCCESS(Status))
2437 {
2438 DPRINT1("NtImpersonateAnonymousToken(): Failed to reference the object (Status 0x%lx)\n", Status);
2439 return Status;
2440 }
2441
2442 /* Call the private routine to impersonate the token */
2444 if (!NT_SUCCESS(Status))
2445 {
2446 DPRINT1("NtImpersonateAnonymousToken(): Failed to impersonate the token (Status 0x%lx)\n", Status);
2447 }
2448
2450 return Status;
2451}
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define THREAD_IMPERSONATE
Definition: pstypes.h:151
POBJECT_TYPE PsThreadType
Definition: thread.c:20
static NTSTATUS SepImpersonateAnonymousToken(_In_ PETHREAD Thread, _In_ KPROCESSOR_MODE PreviousMode)
Private function that impersonates the system's anonymous logon token. The major bulk of the imperson...
Definition: token.c:334

◆ NtOpenObjectAuditAlarm()

__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtOpenObjectAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_opt_ PVOID  HandleId,
_In_ PUNICODE_STRING  ObjectTypeName,
_In_ PUNICODE_STRING  ObjectName,
_In_opt_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ HANDLE  ClientTokenHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ ACCESS_MASK  GrantedAccess,
_In_opt_ PPRIVILEGE_SET  PrivilegeSet,
_In_ BOOLEAN  ObjectCreation,
_In_ BOOLEAN  AccessGranted,
_Out_ PBOOLEAN  GenerateOnClose 
)

Raises an alarm audit message when an object is about to be opened.

Parameters
[in]SubsystemNameA Unicode string that points to a name of the subsystem.
[in]HandleIdA handle to an ID used for identification instance for auditing.
[in]ObjectTypeNameA Unicode string that points to an object type name.
[in]ObjectNameThe name of the object.
[in]SecurityDescriptorA security descriptor.
[in]ClientTokenHandleA handle to a client access token.
[in]DesiredAccessThe desired access rights masks requested by the caller.
[in]GrantedAccessThe granted access mask rights.
[in]PrivilegeSetIf specified, the function will use this set of privileges to audit.
[in]ObjectCreationSet this to TRUE if the object has just been created.
[in]AccessGrantedSet this to TRUE if the access attempt was deemed as granted.
[out]GenerateOnCloseA boolean flag returned to the caller once audit generation procedure finishes.
Returns
Returns STATUS_SUCCESS if all the operations have been completed successfully. STATUS_PRIVILEGE_NOT_HELD is returned if the given subject context does not hold the required audit privilege to actually begin auditing in the first place. STATUS_BAD_IMPERSONATION_LEVEL is returned if the security impersonation level of the client token is not on par with the impersonation level that alllows impersonation. STATUS_INVALID_PARAMETER is returned if the caller has submitted a bogus set of privileges as such array set exceeds the maximum count of privileges that the kernel can accept. A failure NTSTATUS code is returned otherwise.

Definition at line 1622 of file audit.c.

1635{
1636 PTOKEN ClientToken;
1637 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor;
1638 UNICODE_STRING CapturedSubsystemName, CapturedObjectTypeName, CapturedObjectName;
1639 ULONG PrivilegeCount, PrivilegeSetSize;
1640 volatile PPRIVILEGE_SET CapturedPrivilegeSet;
1641 BOOLEAN LocalGenerateOnClose;
1642 PVOID CapturedHandleId;
1645 PAGED_CODE();
1646
1647 /* Only user mode is supported! */
1649
1650 /* Start clean */
1651 ClientToken = NULL;
1652 CapturedSecurityDescriptor = NULL;
1653 CapturedPrivilegeSet = NULL;
1654 CapturedSubsystemName.Buffer = NULL;
1655 CapturedObjectTypeName.Buffer = NULL;
1656 CapturedObjectName.Buffer = NULL;
1657
1658 /* Reference the client token */
1659 Status = ObReferenceObjectByHandle(ClientTokenHandle,
1662 UserMode,
1663 (PVOID*)&ClientToken,
1664 NULL);
1665 if (!NT_SUCCESS(Status))
1666 {
1667 DPRINT1("Failed to reference token handle %p: %lx\n",
1668 ClientTokenHandle, Status);
1669 return Status;
1670 }
1671
1672 /* Capture the security subject context */
1674
1675 /* Validate the token's impersonation level */
1676 if ((ClientToken->TokenType == TokenImpersonation) &&
1678 {
1679 DPRINT1("Invalid impersonation level (%u)\n", ClientToken->ImpersonationLevel);
1681 goto Cleanup;
1682 }
1683
1684 /* Check for audit privilege */
1686 {
1687 DPRINT1("Caller does not have SeAuditPrivilege\n");
1689 goto Cleanup;
1690 }
1691
1692 /* Check for NULL SecurityDescriptor */
1693 if (SecurityDescriptor == NULL)
1694 {
1695 /* Nothing to do */
1697 goto Cleanup;
1698 }
1699
1700 /* Capture the security descriptor */
1702 UserMode,
1703 PagedPool,
1704 FALSE,
1705 &CapturedSecurityDescriptor);
1706 if (!NT_SUCCESS(Status))
1707 {
1708 DPRINT1("Failed to capture security descriptor!\n");
1709 goto Cleanup;
1710 }
1711
1712 _SEH2_TRY
1713 {
1714 /* Check if we have a privilege set */
1715 if (PrivilegeSet != NULL)
1716 {
1717 /* Probe the basic privilege set structure */
1718 ProbeForRead(PrivilegeSet, sizeof(PRIVILEGE_SET), sizeof(ULONG));
1719
1720 /* Validate privilege count */
1721 PrivilegeCount = PrivilegeSet->PrivilegeCount;
1722 if (PrivilegeCount > SEP_PRIVILEGE_SET_MAX_COUNT)
1723 {
1725 _SEH2_YIELD(goto Cleanup);
1726 }
1727
1728 /* Calculate the size of the PrivilegeSet structure */
1729 PrivilegeSetSize = FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]);
1730
1731 /* Probe the whole structure */
1732 ProbeForRead(PrivilegeSet, PrivilegeSetSize, sizeof(ULONG));
1733
1734 /* Allocate a temp buffer */
1735 CapturedPrivilegeSet = ExAllocatePoolWithTag(PagedPool,
1736 PrivilegeSetSize,
1738 if (CapturedPrivilegeSet == NULL)
1739 {
1740 DPRINT1("Failed to allocate %u bytes\n", PrivilegeSetSize);
1742 _SEH2_YIELD(goto Cleanup);
1743 }
1744
1745 /* Copy the privileges */
1746 RtlCopyMemory(CapturedPrivilegeSet, PrivilegeSet, PrivilegeSetSize);
1747 }
1748
1749 if (HandleId != NULL)
1750 {
1751 ProbeForRead(HandleId, sizeof(PVOID), sizeof(PVOID));
1752 CapturedHandleId = *(PVOID*)HandleId;
1753 }
1754
1755 ProbeForWrite(GenerateOnClose, sizeof(BOOLEAN), sizeof(BOOLEAN));
1756 }
1758 {
1760 DPRINT1("Exception while probing parameters: 0x%lx\n", Status);
1761 _SEH2_YIELD(goto Cleanup);
1762 }
1763 _SEH2_END;
1764
1765 /* Probe and capture the subsystem name */
1766 Status = ProbeAndCaptureUnicodeString(&CapturedSubsystemName,
1767 UserMode,
1768 SubsystemName);
1769 if (!NT_SUCCESS(Status))
1770 {
1771 DPRINT1("Failed to capture subsystem name!\n");
1772 goto Cleanup;
1773 }
1774
1775 /* Probe and capture the object type name */
1776 Status = ProbeAndCaptureUnicodeString(&CapturedObjectTypeName,
1777 UserMode,
1779 if (!NT_SUCCESS(Status))
1780 {
1781 DPRINT1("Failed to capture object type name!\n");
1782 goto Cleanup;
1783 }
1784
1785 /* Probe and capture the object name */
1786 Status = ProbeAndCaptureUnicodeString(&CapturedObjectName,
1787 UserMode,
1788 ObjectName);
1789 if (!NT_SUCCESS(Status))
1790 {
1791 DPRINT1("Failed to capture object name!\n");
1792 goto Cleanup;
1793 }
1794
1795 /* Call the internal function */
1797 &CapturedSubsystemName,
1798 CapturedHandleId,
1799 &CapturedObjectTypeName,
1800 &CapturedObjectName,
1801 CapturedSecurityDescriptor,
1802 ClientToken,
1805 CapturedPrivilegeSet,
1806 ObjectCreation,
1808 &LocalGenerateOnClose);
1809
1811
1812 /* Enter SEH to copy the data back to user mode */
1813 _SEH2_TRY
1814 {
1815 *GenerateOnClose = LocalGenerateOnClose;
1816 }
1818 {
1820 DPRINT1("Exception while copying back data: 0x%lx\n", Status);
1821 }
1822 _SEH2_END;
1823
1824Cleanup:
1825
1826 if (CapturedObjectName.Buffer != NULL)
1827 ReleaseCapturedUnicodeString(&CapturedObjectName, UserMode);
1828
1829 if (CapturedObjectTypeName.Buffer != NULL)
1830 ReleaseCapturedUnicodeString(&CapturedObjectTypeName, UserMode);
1831
1832 if (CapturedSubsystemName.Buffer != NULL)
1833 ReleaseCapturedUnicodeString(&CapturedSubsystemName, UserMode);
1834
1835 if (CapturedSecurityDescriptor != NULL)
1836 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, UserMode, FALSE);
1837
1838 if (CapturedPrivilegeSet != NULL)
1839 ExFreePoolWithTag(CapturedPrivilegeSet, TAG_PRIVILEGE_SET);
1840
1841 /* Release the security subject context */
1843
1844 ObDereferenceObject(ClientToken);
1845
1846 return Status;
1847}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_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
@ SecurityIdentification
Definition: lsa.idl:56
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define UserMode
Definition: asm.h:35
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 subj...
Definition: priv.c:360
#define SEP_PRIVILEGE_SET_MAX_COUNT
Definition: audit.c:15
VOID NTAPI SepOpenObjectAuditAlarm(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PUNICODE_STRING SubsystemName, _In_opt_ PVOID HandleId, _In_ PUNICODE_STRING ObjectTypeName, _In_ PUNICODE_STRING ObjectName, _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PTOKEN ClientToken, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK GrantedAccess, _In_opt_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN ObjectCreation, _In_ BOOLEAN AccessGranted, _Out_ PBOOLEAN GenerateOnClose)
Raises an alarm audit message when an object is about to be opened.
Definition: audit.c:1535
NTSTATUS NTAPI SeCaptureSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Captures a security descriptor.
Definition: sd.c:386
NTSTATUS NTAPI SeReleaseSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
Releases a captured security descriptor buffer.
Definition: sd.c:760
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define STATUS_SUCCESS
Definition: shellext.h:65
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:240
TOKEN_TYPE TokenType
Definition: setypes.h:239
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
#define TAG_PRIVILEGE_SET
Definition: tag.h:157
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE _In_ BOOLEAN _In_ BOOLEAN AccessGranted
Definition: sefuncs.h:419

◆ NtOpenProcessTokenEx()

NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcessTokenEx ( _In_ HANDLE  ProcessHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ ULONG  HandleAttributes,
_Out_ PHANDLE  TokenHandle 
)

◆ NtPrivilegeCheck()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegeCheck ( _In_ HANDLE  ClientToken,
_Inout_ PPRIVILEGE_SET  RequiredPrivileges,
_Out_ PBOOLEAN  Result 
)

◆ NtPrivilegedServiceAuditAlarm()

NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegedServiceAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_ PUNICODE_STRING  ServiceName,
_In_ HANDLE  ClientToken,
_In_ PPRIVILEGE_SET  Privileges,
_In_ BOOLEAN  AccessGranted 
)

◆ NtPrivilegeObjectAuditAlarm()

__kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtPrivilegeObjectAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_opt_ PVOID  HandleId,
_In_ HANDLE  ClientToken,
_In_ ACCESS_MASK  DesiredAccess,
_In_ PPRIVILEGE_SET  Privileges,
_In_ BOOLEAN  AccessGranted 
)

◆ NtSetInformationToken()

_Must_inspect_result_ __kernel_entry NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationToken ( _In_ HANDLE  TokenHandle,
_In_ TOKEN_INFORMATION_CLASS  TokenInformationClass,
_In_reads_bytes_(TokenInformationLength) PVOID  TokenInformation,
_In_ ULONG  TokenInformationLength 
)

Sets (modifies) some specific information in regard of an access token. The calling thread must have specific access rights in order to modify token's information data.

@unimplemented

Parameters
[in]TokenHandleA handle of a token where information is to be modified.
[in]TokenInformationClassToken information class.
[in]TokenInformationAn arbitrary pointer to a buffer with token information to set. Such arbitrary buffer depends on the information class chosen that the caller wants to modify such information data of a token.
[in]TokenInformationLengthLength of the token information buffer, in bytes.
Returns
Returns STATUS_SUCCESS if information setting has completed successfully. STATUS_INFO_LENGTH_MISMATCH is returned if the information length of the buffer is less than the required length. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation has failed. STATUS_PRIVILEGE_NOT_HELD is returned if the calling thread hasn't the required privileges to perform the operation in question. A failure NTSTATUS code is returned otherwise.
Remarks
The function is partly implemented, mainly TokenOrigin.

Definition at line 1125 of file tokencls.c.

1130{
1132 PTOKEN Token;
1134 ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
1135
1136 PAGED_CODE();
1137
1139
1143 TokenInformation,
1145 PreviousMode);
1146 if (!NT_SUCCESS(Status))
1147 {
1148 /* Invalid buffers */
1149 DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
1150 return Status;
1151 }
1152
1154 {
1155 NeededAccess |= TOKEN_ADJUST_SESSIONID;
1156 }
1157
1159 NeededAccess,
1162 (PVOID*)&Token,
1163 NULL);
1164 if (NT_SUCCESS(Status))
1165 {
1166 switch (TokenInformationClass)
1167 {
1168 case TokenOwner:
1169 {
1170 if (TokenInformationLength >= sizeof(TOKEN_OWNER))
1171 {
1172 PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
1173 PSID InputSid = NULL, CapturedSid;
1174 ULONG DefaultOwnerIndex;
1175
1176 _SEH2_TRY
1177 {
1178 InputSid = to->Owner;
1179 }
1181 {
1183 _SEH2_YIELD(goto Cleanup);
1184 }
1185 _SEH2_END;
1186
1187 Status = SepCaptureSid(InputSid,
1189 PagedPool,
1190 FALSE,
1191 &CapturedSid);
1192 if (NT_SUCCESS(Status))
1193 {
1194 /* Lock the token */
1196
1197 /* Find the owner amongst the existing token user and groups */
1199 NULL,
1200 CapturedSid,
1201 NULL,
1202 &DefaultOwnerIndex);
1203 if (NT_SUCCESS(Status))
1204 {
1205 /* Found it */
1206 Token->DefaultOwnerIndex = DefaultOwnerIndex;
1207 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1208 }
1209
1210 /* Unlock the token */
1212
1213 SepReleaseSid(CapturedSid,
1215 FALSE);
1216 }
1217 }
1218 else
1219 {
1221 }
1222 break;
1223 }
1224
1225 case TokenPrimaryGroup:
1226 {
1228 {
1229 PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
1230 ULONG AclSize;
1232 PSID InputSid = NULL, CapturedSid;
1233 ULONG PrimaryGroupIndex, NewDynamicLength;
1234
1235 _SEH2_TRY
1236 {
1237 InputSid = tpg->PrimaryGroup;
1238 }
1240 {
1242 _SEH2_YIELD(goto Cleanup);
1243 }
1244 _SEH2_END;
1245
1246 Status = SepCaptureSid(InputSid,
1248 PagedPool,
1249 FALSE,
1250 &CapturedSid);
1251 if (NT_SUCCESS(Status))
1252 {
1253 /* Lock the token */
1255
1256 /*
1257 * We can whack the token's primary group only if
1258 * the charged dynamic space boundary allows us
1259 * to do so. Exceeding this boundary and we're
1260 * busted out.
1261 */
1262 AclSize = Token->DefaultDacl ? Token->DefaultDacl->AclSize : 0;
1263 NewDynamicLength = RtlLengthSid(CapturedSid) + AclSize;
1264 if (NewDynamicLength > Token->DynamicCharged)
1265 {
1267 SepReleaseSid(CapturedSid, PreviousMode, FALSE);
1269 DPRINT1("NtSetInformationToken(): Couldn't assign new primary group, space exceeded (current length %u, new length %lu)\n",
1270 Token->DynamicCharged, NewDynamicLength);
1271 goto Cleanup;
1272 }
1273
1274 /*
1275 * The dynamic part of the token may require a rebuild
1276 * if the current dynamic area is too small. If not then
1277 * we're pretty much good as is.
1278 */
1279 Status = SepRebuildDynamicPartOfToken(Token, NewDynamicLength);
1280 if (NT_SUCCESS(Status))
1281 {
1282 /* Find the primary group amongst the existing token user and groups */
1284 CapturedSid,
1285 NULL,
1286 &PrimaryGroupIndex,
1287 NULL);
1288 if (NT_SUCCESS(Status))
1289 {
1290 /*
1291 * We have found it. Add the length of
1292 * the previous primary group SID to the
1293 * available dynamic area.
1294 */
1295 Token->DynamicAvailable += RtlLengthSid(Token->PrimaryGroup);
1296
1297 /*
1298 * Move the default DACL if it's not at the
1299 * head of the dynamic part.
1300 */
1301 if ((Token->DefaultDacl) &&
1302 ((PULONG)(Token->DefaultDacl) != Token->DynamicPart))
1303 {
1304 RtlMoveMemory(Token->DynamicPart,
1305 Token->DefaultDacl,
1306 RtlLengthSid(Token->PrimaryGroup));
1307 Token->DefaultDacl = (PACL)(Token->DynamicPart);
1308 }
1309
1310 /* Take away available space from the dynamic area */
1311 Token->DynamicAvailable -= RtlLengthSid(Token->UserAndGroups[PrimaryGroupIndex].Sid);
1312
1313 /*
1314 * And assign the new primary group. For that
1315 * we have to make sure where the primary group
1316 * is going to stay in memory, so if this token
1317 * has a default DACL then add up its size with
1318 * the address of the dynamic part.
1319 */
1320 PrimaryGroup = (ULONG_PTR)(Token->DynamicPart) + AclSize;
1321 RtlCopySid(RtlLengthSid(Token->UserAndGroups[PrimaryGroupIndex].Sid),
1323 Token->UserAndGroups[PrimaryGroupIndex].Sid);
1324 Token->PrimaryGroup = (PSID)PrimaryGroup;
1325
1326 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1327 }
1328 }
1329
1330 /* Unlock the token */
1332
1333 SepReleaseSid(CapturedSid,
1335 FALSE);
1336 }
1337 }
1338 else
1339 {
1341 }
1342 break;
1343 }
1344
1345 case TokenDefaultDacl:
1346 {
1348 {
1349 PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
1350 PACL InputAcl = NULL;
1351
1352 _SEH2_TRY
1353 {
1354 InputAcl = tdd->DefaultDacl;
1355 }
1357 {
1359 _SEH2_YIELD(goto Cleanup);
1360 }
1361 _SEH2_END;
1362
1363 if (InputAcl != NULL)
1364 {
1365 PACL CapturedAcl;
1366
1367 /* Capture, validate, and copy the DACL */
1368 Status = SepCaptureAcl(InputAcl,
1370 PagedPool,
1371 TRUE,
1372 &CapturedAcl);
1373 if (NT_SUCCESS(Status))
1374 {
1375 ULONG NewDynamicLength;
1376 ULONG_PTR Acl;
1377
1378 /* Lock the token */
1380
1381 /*
1382 * We can whack the token's default DACL only if
1383 * the charged dynamic space boundary allows us
1384 * to do so. Exceeding this boundary and we're
1385 * busted out.
1386 */
1387 NewDynamicLength = CapturedAcl->AclSize + RtlLengthSid(Token->PrimaryGroup);
1388 if (NewDynamicLength > Token->DynamicCharged)
1389 {
1391 SepReleaseAcl(CapturedAcl, PreviousMode, TRUE);
1393 DPRINT1("NtSetInformationToken(): Couldn't assign new default DACL, space exceeded (current length %u, new length %lu)\n",
1394 Token->DynamicCharged, NewDynamicLength);
1395 goto Cleanup;
1396 }
1397
1398 /*
1399 * The dynamic part of the token may require a rebuild
1400 * if the current dynamic area is too small. If not then
1401 * we're pretty much good as is.
1402 */
1403 Status = SepRebuildDynamicPartOfToken(Token, NewDynamicLength);
1404 if (NT_SUCCESS(Status))
1405 {
1406 /*
1407 * Before setting up a new DACL for the
1408 * token object we add up the size of
1409 * the old DACL to the available dynamic
1410 * area
1411 */
1412 if (Token->DefaultDacl)
1413 {
1414 Token->DynamicAvailable += Token->DefaultDacl->AclSize;
1415 }
1416
1417 /*
1418 * Move the primary group if it's not at the
1419 * head of the dynamic part.
1420 */
1421 if ((PULONG)(Token->PrimaryGroup) != Token->DynamicPart)
1422 {
1423 RtlMoveMemory(Token->DynamicPart,
1424 Token->PrimaryGroup,
1425 RtlLengthSid(Token->PrimaryGroup));
1426 Token->PrimaryGroup = (PSID)(Token->DynamicPart);
1427 }
1428
1429 /* Take away available space from the dynamic area */
1430 Token->DynamicAvailable -= CapturedAcl->AclSize;
1431
1432 /* Set the new dacl */
1433 Acl = (ULONG_PTR)(Token->DynamicPart) + RtlLengthSid(Token->PrimaryGroup);
1434 RtlCopyMemory((PVOID)Acl,
1435 CapturedAcl,
1436 CapturedAcl->AclSize);
1437 Token->DefaultDacl = (PACL)Acl;
1438
1439 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1440 }
1441
1442 /* Unlock the token and release the ACL */
1444 SepReleaseAcl(CapturedAcl, PreviousMode, TRUE);
1445 }
1446 }
1447 else
1448 {
1449 /* Lock the token */
1451
1452 /* Clear the default dacl if present */
1453 if (Token->DefaultDacl != NULL)
1454 {
1455 Token->DynamicAvailable += Token->DefaultDacl->AclSize;
1456 RtlZeroMemory(Token->DefaultDacl, Token->DefaultDacl->AclSize);
1457 Token->DefaultDacl = NULL;
1458
1459 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1460 }
1461
1462 /* Unlock the token */
1464 }
1465 }
1466 else
1467 {
1469 }
1470 break;
1471 }
1472
1473 case TokenSessionId:
1474 {
1475 ULONG SessionId = 0;
1476
1477 _SEH2_TRY
1478 {
1479 /* Buffer size was already verified, no need to check here again */
1480 SessionId = *(PULONG)TokenInformation;
1481 }
1483 {
1485 _SEH2_YIELD(goto Cleanup);
1486 }
1487 _SEH2_END;
1488
1489 /* Check for TCB privilege */
1491 {
1493 break;
1494 }
1495
1496 /* Lock the token */
1498
1499 Token->SessionId = SessionId;
1500 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1501
1502 /* Unlock the token */
1504
1505 break;
1506 }
1507
1509 {
1510 ULONG SessionReference;
1511
1512 _SEH2_TRY
1513 {
1514 /* Buffer size was already verified, no need to check here again */
1515 SessionReference = *(PULONG)TokenInformation;
1516 }
1518 {
1520 _SEH2_YIELD(goto Cleanup);
1521 }
1522 _SEH2_END;
1523
1524 /* Check for TCB privilege */
1526 {
1528 goto Cleanup;
1529 }
1530
1531 /* Check if it is 0 */
1532 if (SessionReference == 0)
1533 {
1534 ULONG OldTokenFlags;
1535
1536 /* Lock the token */
1538
1539 /* Atomically set the flag in the token */
1540 OldTokenFlags = RtlInterlockedSetBits(&Token->TokenFlags,
1542 /*
1543 * If the flag was already set, do not dereference again
1544 * the logon session. Use SessionReference as an indicator
1545 * to know whether to really dereference the session.
1546 */
1547 if (OldTokenFlags == Token->TokenFlags)
1548 SessionReference = ULONG_MAX;
1549
1550 /*
1551 * Otherwise if the flag was never set but just for this first time then
1552 * remove the referenced logon session data from the token and dereference
1553 * the logon session when needed.
1554 */
1555 if (SessionReference == 0)
1556 {
1558 SepRmDereferenceLogonSession(&Token->AuthenticationId);
1559 }
1560
1561 /* Unlock the token */
1563 }
1564 break;
1565 }
1566
1567 case TokenAuditPolicy:
1568 {
1569 PTOKEN_AUDIT_POLICY_INFORMATION PolicyInformation =
1570 (PTOKEN_AUDIT_POLICY_INFORMATION)TokenInformation;
1571 SEP_AUDIT_POLICY AuditPolicy;
1572 ULONG i;
1573
1574 _SEH2_TRY
1575 {
1576 ProbeForRead(PolicyInformation,
1578 Policies[PolicyInformation->PolicyCount]),
1579 sizeof(ULONG));
1580
1581 /* Loop all policies in the structure */
1582 for (i = 0; i < PolicyInformation->PolicyCount; i++)
1583 {
1584 /* Set the corresponding bits in the packed structure */
1585 switch (PolicyInformation->Policies[i].Category)
1586 {
1588 AuditPolicy.PolicyElements.System = PolicyInformation->Policies[i].Value;
1589 break;
1590
1591 case AuditCategoryLogon:
1592 AuditPolicy.PolicyElements.Logon = PolicyInformation->Policies[i].Value;
1593 break;
1594
1596 AuditPolicy.PolicyElements.ObjectAccess = PolicyInformation->Policies[i].Value;
1597 break;
1598
1600 AuditPolicy.PolicyElements.PrivilegeUse = PolicyInformation->Policies[i].Value;
1601 break;
1602
1604 AuditPolicy.PolicyElements.DetailedTracking = PolicyInformation->Policies[i].Value;
1605 break;
1606
1608 AuditPolicy.PolicyElements.PolicyChange = PolicyInformation->Policies[i].Value;
1609 break;
1610
1612 AuditPolicy.PolicyElements.AccountManagement = PolicyInformation->Policies[i].Value;
1613 break;
1614
1616 AuditPolicy.PolicyElements.DirectoryServiceAccess = PolicyInformation->Policies[i].Value;
1617 break;
1618
1620 AuditPolicy.PolicyElements.AccountLogon = PolicyInformation->Policies[i].Value;
1621 break;
1622 }
1623 }
1624 }
1626 {
1628 _SEH2_YIELD(goto Cleanup);
1629 }
1630 _SEH2_END;
1631
1632 /* Check for TCB privilege */
1634 {
1636 break;
1637 }
1638
1639 /* Lock the token */
1641
1642 /* Set the new audit policy */
1643 Token->AuditPolicy = AuditPolicy;
1644 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1645
1646 /* Unlock the token */
1648
1649 break;
1650 }
1651
1652 case TokenOrigin:
1653 {
1655
1656 _SEH2_TRY
1657 {
1658 /* Copy the token origin */
1659 TokenOrigin = *(PTOKEN_ORIGIN)TokenInformation;
1660 }
1662 {
1664 _SEH2_YIELD(goto Cleanup);
1665 }
1666 _SEH2_END;
1667
1668 /* Check for TCB privilege */
1670 {
1672 break;
1673 }
1674
1675 /* Lock the token */
1677
1678 /* Check if there is no token origin set yet */
1679 if (RtlIsZeroLuid(&Token->OriginatingLogonSession))
1680 {
1681 /* Set the token origin */
1682 Token->OriginatingLogonSession =
1683 TokenOrigin.OriginatingLogonSession;
1684
1685 ExAllocateLocallyUniqueId(&Token->ModifiedId);
1686 }
1687
1688 /* Unlock the token */
1690
1691 break;
1692 }
1693
1694 default:
1695 {
1696 DPRINT1("Invalid TokenInformationClass: 0x%lx\n",
1699 break;
1700 }
1701 }
1702Cleanup:
1704 }
1705
1706 if (!NT_SUCCESS(Status))
1707 {
1708 DPRINT1("NtSetInformationToken failed with Status 0x%lx\n", Status);
1709 }
1710
1711 return Status;
1712}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONG SessionId
Definition: dllmain.c:28
#define ULONG_PTR
Definition: config.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ULONG_MAX
Definition: limits.h:44
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
struct _SID * PSID
Definition: eventlog.c:35
struct _ACL * PACL
Definition: security.c:105
_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
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_In_ TOKEN_INFORMATION_CLASS TokenInformationClass
Definition: sefuncs.h:310
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG TokenInformationLength
Definition: sefuncs.h:312
VOID NTAPI ExAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
Definition: uuid.c:335
static __inline NTSTATUS DefaultSetInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ PVOID Buffer, _In_ ULONG BufferLength, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtSet*** system call is invoked from u...
Definition: probe.h:70
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
NTSTATUS SepRmDereferenceLogonSession(_Inout_ PLUID LogonLuid)
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
const LUID SeTcbPrivilege
Definition: priv.c:26
#define SepAcquireTokenLockExclusive(Token)
Definition: se.h:275
struct _TOKEN_AUDIT_POLICY_INFORMATION * PTOKEN_AUDIT_POLICY_INFORMATION
#define SepReleaseTokenLock(Token)
Definition: se.h:286
NTSTATUS SepRebuildDynamicPartOfToken(_In_ PTOKEN Token, _In_ ULONG NewDynamicPartSize)
@ AuditCategoryLogon
Definition: ntsecapi.h:261
@ AuditCategoryAccountManagement
Definition: ntsecapi.h:266
@ AuditCategoryAccountLogon
Definition: ntsecapi.h:268
@ AuditCategoryPolicyChange
Definition: ntsecapi.h:265
@ AuditCategorySystem
Definition: ntsecapi.h:260
@ AuditCategoryObjectAccess
Definition: ntsecapi.h:262
@ AuditCategoryDirectoryServiceAccess
Definition: ntsecapi.h:267
@ AuditCategoryDetailedTracking
Definition: ntsecapi.h:264
@ AuditCategoryPrivilegeUse
Definition: ntsecapi.h:263
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:389
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define DPRINT
Definition: sndvol32.h:71
USHORT AclSize
Definition: ms-dtyp.idl:296
SEP_AUDIT_POLICY_CATEGORIES PolicyElements
Definition: setypes.h:158
struct _TOKEN_AUDIT_POLICY_INFORMATION::@1783 Policies[1]
PSID Owner
Definition: setypes.h:1024
static const INFORMATION_CLASS_INFO SeTokenInformationClass[]
Definition: tokencls.c:19
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define RtlIsZeroLuid(_L1)
Definition: rtlfuncs.h:753
#define RtlInterlockedSetBits(Flags, Flag)
Definition: rtlfuncs.h:3434
struct _TOKEN_PRIMARY_GROUP * PTOKEN_PRIMARY_GROUP
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1180
struct _TOKEN_DEFAULT_DACL * PTOKEN_DEFAULT_DACL
struct _TOKEN_ORIGIN * PTOKEN_ORIGIN
#define TOKEN_ADJUST_SESSIONID
Definition: setypes.h:929
@ TokenAuditPolicy
Definition: setypes.h:977
@ TokenOrigin
Definition: setypes.h:978
@ TokenSessionId
Definition: setypes.h:973
@ TokenSessionReference
Definition: setypes.h:975
#define TOKEN_ADJUST_DEFAULT
Definition: setypes.h:928
struct _TOKEN_OWNER * PTOKEN_OWNER

◆ SeCaptureSecurityDescriptor()

NTKERNELAPI NTSTATUS NTAPI SeCaptureSecurityDescriptor ( _In_ PSECURITY_DESCRIPTOR  _OriginalSecurityDescriptor,
_In_ KPROCESSOR_MODE  CurrentMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor 
)

Captures a security descriptor.

Parameters
[in]_OriginalSecurityDescriptorAn already existing and valid security descriptor to be captured.
[in]CurrentModeProcessor level access mode.
[in]PoolTypePool type to be used when allocating the captured buffer.
[in]CaptureIfKernelSet this to TRUE if capturing is done within the kernel.
[out]CapturedSecurityDescriptorThe captured security descriptor.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the security descriptor has been captured. STATUS_UNKNOWN_REVISION is returned if the security descriptor has an unknown revision. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the captured buffer has failed. A failure NTSTATUS code is returned otherwise.

Definition at line 386 of file sd.c.

392{
393 PISECURITY_DESCRIPTOR OriginalDescriptor = _OriginalSecurityDescriptor;
394 SECURITY_DESCRIPTOR DescriptorCopy;
396 ULONG OwnerSAC = 0, GroupSAC = 0;
397 ULONG OwnerSize = 0, GroupSize = 0;
398 ULONG SaclSize = 0, DaclSize = 0;
401
402 if (!OriginalDescriptor)
403 {
404 /* Nothing to do... */
405 *CapturedSecurityDescriptor = NULL;
406 return STATUS_SUCCESS;
407 }
408
409 /* Quick path */
410 if (CurrentMode == KernelMode && !CaptureIfKernel)
411 {
412 /* Check descriptor version */
413 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
414 {
416 }
417
418 *CapturedSecurityDescriptor = _OriginalSecurityDescriptor;
419 return STATUS_SUCCESS;
420 }
421
423 {
424 if (CurrentMode != KernelMode)
425 {
426 ProbeForRead(OriginalDescriptor,
428 sizeof(ULONG));
429 }
430
431 /* Check the descriptor version */
432 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
433 {
435 }
436
437 if (CurrentMode != KernelMode)
438 {
439 /* Get the size of the descriptor */
440 DescriptorSize = (OriginalDescriptor->Control & SE_SELF_RELATIVE) ?
442
443 /* Probe the entire security descriptor structure. The SIDs
444 * and ACLs will be probed and copied later though */
445 ProbeForRead(OriginalDescriptor, DescriptorSize, sizeof(ULONG));
446 }
447
448 /* Now capture all fields and convert to an absolute descriptor */
449 DescriptorCopy.Revision = OriginalDescriptor->Revision;
450 DescriptorCopy.Sbz1 = OriginalDescriptor->Sbz1;
451 DescriptorCopy.Control = OriginalDescriptor->Control & ~SE_SELF_RELATIVE;
452 DescriptorCopy.Owner = SepGetOwnerFromDescriptor(OriginalDescriptor);
453 DescriptorCopy.Group = SepGetGroupFromDescriptor(OriginalDescriptor);
454 DescriptorCopy.Sacl = SepGetSaclFromDescriptor(OriginalDescriptor);
455 DescriptorCopy.Dacl = SepGetDaclFromDescriptor(OriginalDescriptor);
457
458 /* Determine owner and group sizes */
459 OwnerSize = DetermineSIDSize(DescriptorCopy.Owner, &OwnerSAC, CurrentMode);
461 GroupSize = DetermineSIDSize(DescriptorCopy.Group, &GroupSAC, CurrentMode);
462 DescriptorSize += ROUND_UP(GroupSize, sizeof(ULONG));
463
464 /* Determine the size of the ACLs */
465 if (DescriptorCopy.Control & SE_SACL_PRESENT)
466 {
467 /* Get the size and probe if user mode */
468 SaclSize = DetermineACLSize(DescriptorCopy.Sacl, CurrentMode);
470 }
471
472 if (DescriptorCopy.Control & SE_DACL_PRESENT)
473 {
474 /* Get the size and probe if user mode */
475 DaclSize = DetermineACLSize(DescriptorCopy.Dacl, CurrentMode);
477 }
478 }
480 {
482 }
483 _SEH2_END;
484
485 /*
486 * Allocate enough memory to store a complete copy of a self-relative
487 * security descriptor
488 */
491 TAG_SD);
493
495 NewDescriptor->Revision = DescriptorCopy.Revision;
496 NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
497 NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
498
500 {
501 /*
502 * Setup the offsets and copy the SIDs and ACLs to the new
503 * self-relative security descriptor. Probing the pointers is not
504 * neccessary anymore as we did that when collecting the sizes!
505 * Make sure to validate the SIDs and ACLs *again* as they could have
506 * been modified in the meanwhile!
507 */
509
510 if (DescriptorCopy.Owner)
511 {
512 if (!RtlValidSid(DescriptorCopy.Owner)) RtlRaiseStatus(STATUS_INVALID_SID);
515 DescriptorCopy.Owner,
516 OwnerSize);
517 Offset += ROUND_UP(OwnerSize, sizeof(ULONG));
518 }
519
520 if (DescriptorCopy.Group)
521 {
522 if (!RtlValidSid(DescriptorCopy.Group)) RtlRaiseStatus(STATUS_INVALID_SID);
525 DescriptorCopy.Group,
526 GroupSize);
527 Offset += ROUND_UP(GroupSize, sizeof(ULONG));
528 }
529
530 if (DescriptorCopy.Sacl)
531 {
532 if (!RtlValidAcl(DescriptorCopy.Sacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
535 DescriptorCopy.Sacl,
536 SaclSize);
537 Offset += ROUND_UP(SaclSize, sizeof(ULONG));
538 }
539
540 if (DescriptorCopy.Dacl)
541 {
542 if (!RtlValidAcl(DescriptorCopy.Dacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
545 DescriptorCopy.Dacl,
546 DaclSize);
547 Offset += ROUND_UP(DaclSize, sizeof(ULONG));
548 }
549
550 /* Make sure the size was correct */
552 }
554 {
555 /* We failed to copy the data to the new descriptor */
558 }
559 _SEH2_END;
560
561 /*
562 * We're finally done!
563 * Copy the pointer to the captured descriptor to to the caller.
564 */
565 *CapturedSecurityDescriptor = NewDescriptor;
566 return STATUS_SUCCESS;
567}
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
_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 OwnerSize
Definition: rtlfuncs.h:1598
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
_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 SaclSize
Definition: rtlfuncs.h:1596
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1594
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:99
FORCEINLINE PACL SepGetSaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:141
FORCEINLINE PSID SepGetGroupFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:79
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:119
static ULONG DetermineSIDSize(_In_ PISID Sid, _Inout_ PULONG OutSAC, _In_ KPROCESSOR_MODE ProcessorMode)
Determines the size of a SID.
Definition: sd.c:290
static ULONG DetermineACLSize(_In_ PACL Acl, _In_ KPROCESSOR_MODE ProcessorMode)
Determines the size of an ACL.
Definition: sd.c:336
#define STATUS_UNKNOWN_REVISION
Definition: ntstatus.h:324
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
#define STATUS_INVALID_SID
Definition: ntstatus.h:356
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
#define TAG_SD
Definition: tag.h:153
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:30
#define SE_SELF_RELATIVE
Definition: setypes.h:830
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
#define SE_SACL_PRESENT
Definition: setypes.h:819
#define SECURITY_DESCRIPTOR_REVISION1
Definition: setypes.h:59
#define SE_DACL_PRESENT
Definition: setypes.h:817

Referenced by NtAccessCheck(), NtOpenObjectAuditAlarm(), NtSetSecurityObject(), ObpCaptureObjectCreateInformation(), ProbeAndCaptureObjectAttributes(), and SepAccessCheckAndAuditAlarm().

◆ SeCreateAccessState()

NTKERNELAPI NTSTATUS NTAPI SeCreateAccessState ( _In_ PACCESS_STATE  AccessState,
_In_ PAUX_ACCESS_DATA  AuxData,
_In_ ACCESS_MASK  Access,
_In_ PGENERIC_MAPPING  GenericMapping 
)

◆ SeDeleteAccessState()

NTKERNELAPI VOID NTAPI SeDeleteAccessState ( _In_ PACCESS_STATE  AccessState)

Deletes an allocated access state from the memory.

Parameters
[in]AccessStateA valid access state.
Returns
Nothing.

Definition at line 150 of file access.c.

152{
153 PAUX_ACCESS_DATA AuxData;
154 PAGED_CODE();
155
156 /* Get the Auxiliary Data */
157 AuxData = AccessState->AuxData;
158
159 /* Deallocate Privileges */
160 if (AccessState->PrivilegesAllocated)
162
163 /* Deallocate Name and Type Name */
164 if (AccessState->ObjectName.Buffer)
165 {
166 ExFreePool(AccessState->ObjectName.Buffer);
167 }
168
169 if (AccessState->ObjectTypeName.Buffer)
170 {
171 ExFreePool(AccessState->ObjectTypeName.Buffer);
172 }
173
174 /* Release the Subject Context */
175 SeReleaseSubjectContext(&AccessState->SubjectSecurityContext);
176}
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
PPRIVILEGE_SET PrivilegeSet
Definition: setypes.h:258
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by NtOpenProcess(), NtOpenThread(), ObDuplicateObject(), ObInsertObject(), ObOpenObjectByName(), ObOpenObjectByPointer(), ObReferenceObjectByName(), PspCreateProcess(), PspCreateThread(), and START_TEST().

◆ SeReleaseSecurityDescriptor()

NTKERNELAPI NTSTATUS NTAPI SeReleaseSecurityDescriptor ( _In_ PSECURITY_DESCRIPTOR  CapturedSecurityDescriptor,
_In_ KPROCESSOR_MODE  CurrentMode,
_In_ BOOLEAN  CaptureIfKernelMode 
)

Releases a captured security descriptor buffer.

Parameters
[in]CapturedSecurityDescriptorThe captured security descriptor to be freed.
[in]CurrentModeProcessor level access mode.
[in]CaptureIfKernelModeSet this to TRUE if the releasing is to be done within the kernel.
Returns
Returns STATUS_SUCCESS.

Definition at line 760 of file sd.c.

764{
765 PAGED_CODE();
766
767 /*
768 * WARNING! You need to call this function with the same value for CurrentMode
769 * and CaptureIfKernelMode that you previously passed to
770 * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
771 */
772 if (CapturedSecurityDescriptor != NULL &&
773 (CurrentMode != KernelMode ||
774 (CurrentMode == KernelMode && CaptureIfKernelMode)))
775 {
776 /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
777 ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD);
778 }
779
780 return STATUS_SUCCESS;
781}

Referenced by NtAccessCheck(), NtOpenObjectAuditAlarm(), NtSetSecurityObject(), ObInsertObject(), ObpReleaseObjectCreateInformation(), ReleaseCapturedObjectAttributes(), and SepAccessCheckAndAuditAlarm().

◆ SeTokenImpersonationLevel()

NTKERNELAPI SECURITY_IMPERSONATION_LEVEL NTAPI SeTokenImpersonationLevel ( _In_ PACCESS_TOKEN  Token)

Gathers the security impersonation level of an access token.

Parameters
[in]TokenA valid access token where the impersonation level has to be gathered.
Returns
Returns the security impersonation level from a valid token.

Definition at line 1846 of file token.c.

1848{
1849 PAGED_CODE();
1850
1851 return ((PTOKEN)Token)->ImpersonationLevel;
1852}

Referenced by PsAssignImpersonationToken().

◆ ZwAccessCheck()

NTSYSAPI NTSTATUS NTAPI ZwAccessCheck ( _In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ HANDLE  ClientToken,
_In_ ACCESS_MASK  DesiredAccess,
_In_ PGENERIC_MAPPING  GenericMapping,
_Out_ PPRIVILEGE_SET  PrivilegeSet,
_Out_ PULONG  ReturnLength,
_Out_ PACCESS_MASK  GrantedAccess,
_Out_ PNTSTATUS  AccessStatus 
)

◆ ZwAdjustGroupsToken()

NTSYSAPI NTSTATUS NTAPI ZwAdjustGroupsToken ( _In_ HANDLE  TokenHandle,
_In_ BOOLEAN  ResetToDefault,
_In_ PTOKEN_GROUPS  NewState,
_In_ ULONG  BufferLength,
_Out_opt_ PTOKEN_GROUPS  PreviousState,
_Out_ PULONG  ReturnLength 
)

◆ ZwAdjustPrivilegesToken()

◆ ZwAllocateLocallyUniqueId()

NTSYSAPI NTSTATUS NTAPI ZwAllocateLocallyUniqueId ( _Out_ LUID LocallyUniqueId)

◆ ZwAllocateUuids()

NTSYSAPI NTSTATUS NTAPI ZwAllocateUuids ( _Out_ PULARGE_INTEGER  Time,
_Out_ PULONG  Range,
_Out_ PULONG  Sequence,
_Out_ PUCHAR  Seed 
)

◆ ZwCreateToken()

NTSYSAPI NTSTATUS NTAPI ZwCreateToken ( _Out_ PHANDLE  TokenHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ POBJECT_ATTRIBUTES  ObjectAttributes,
_In_ TOKEN_TYPE  TokenType,
_In_ PLUID  AuthenticationId,
_In_ PLARGE_INTEGER  ExpirationTime,
_In_ PTOKEN_USER  TokenUser,
_In_ PTOKEN_GROUPS  TokenGroups,
_In_ PTOKEN_PRIVILEGES  TokenPrivileges,
_In_ PTOKEN_OWNER  TokenOwner,
_In_ PTOKEN_PRIMARY_GROUP  TokenPrimaryGroup,
_In_ PTOKEN_DEFAULT_DACL  TokenDefaultDacl,
_In_ PTOKEN_SOURCE  TokenSource 
)

◆ ZwImpersonateAnonymousToken()

NTSYSAPI NTSTATUS NTAPI ZwImpersonateAnonymousToken ( _In_ HANDLE  Thread)

◆ ZwOpenObjectAuditAlarm()

NTSYSAPI NTSTATUS NTAPI ZwOpenObjectAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_ PVOID  HandleId,
_In_ PUNICODE_STRING  ObjectTypeName,
_In_ PUNICODE_STRING  ObjectName,
_In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ HANDLE  ClientToken,
_In_ ULONG  DesiredAccess,
_In_ ULONG  GrantedAccess,
_In_ PPRIVILEGE_SET  Privileges,
_In_ BOOLEAN  ObjectCreation,
_In_ BOOLEAN  AccessGranted,
_Out_ PBOOLEAN  GenerateOnClose 
)

◆ ZwOpenProcessTokenEx()

NTSYSAPI NTSTATUS NTAPI ZwOpenProcessTokenEx ( _In_ HANDLE  ProcessHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ ULONG  HandleAttributes,
_Out_ PHANDLE  TokenHandle 
)

◆ ZwPrivilegeCheck()

NTSYSAPI NTSTATUS NTAPI ZwPrivilegeCheck ( _In_ HANDLE  ClientToken,
_In_ PPRIVILEGE_SET  RequiredPrivileges,
_In_ PBOOLEAN  Result 
)

◆ ZwPrivilegedServiceAuditAlarm()

NTSYSAPI NTSTATUS NTAPI ZwPrivilegedServiceAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_ PUNICODE_STRING  ServiceName,
_In_ HANDLE  ClientToken,
_In_ PPRIVILEGE_SET  Privileges,
_In_ BOOLEAN  AccessGranted 
)

◆ ZwPrivilegeObjectAuditAlarm()

NTSYSAPI NTSTATUS NTAPI ZwPrivilegeObjectAuditAlarm ( _In_ PUNICODE_STRING  SubsystemName,
_In_ PVOID  HandleId,
_In_ HANDLE  ClientToken,
_In_ ULONG  DesiredAccess,
_In_ PPRIVILEGE_SET  Privileges,
_In_ BOOLEAN  AccessGranted 
)

◆ ZwSetInformationToken()

NTSYSAPI NTSTATUS NTAPI ZwSetInformationToken ( _In_ HANDLE  TokenHandle,
_In_ TOKEN_INFORMATION_CLASS  TokenInformationClass,
_Out_ PVOID  TokenInformation,
_In_ ULONG  TokenInformationLength 
)

Variable Documentation

◆ DesiredAccess

Definition at line 401 of file sefuncs.h.

◆ EffectiveOnly

◆ Length

Definition at line 485 of file sefuncs.h.

◆ NewTokenHandle

◆ ObjectAttributes

Definition at line 402 of file sefuncs.h.

◆ ResultLength

◆ ReturnLength

Definition at line 313 of file sefuncs.h.

◆ TokenHandle

Definition at line 437 of file sefuncs.h.

◆ TokenInformationClass

◆ TokenInformationLength

◆ TokenType