ReactOS 0.4.15-dev-5893-g1bb4167
token.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for token.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS SepCreateTokenLock (_Inout_ PTOKEN Token)
 Creates a lock for the token.
 
VOID SepDeleteTokenLock (_Inout_ PTOKEN Token)
 Deletes a lock of a token.
 
static BOOLEAN SepCompareSidAndAttributesFromTokens (_In_ PSID_AND_ATTRIBUTES SidArrayToken1, _In_ ULONG CountSidArray1, _In_ PSID_AND_ATTRIBUTES SidArrayToken2, _In_ ULONG CountSidArray2)
 Compares the elements of SID arrays provided by tokens. The elements that are being compared for equality are the SIDs and their attributes.
 
static BOOLEAN SepComparePrivilegeAndAttributesFromTokens (_In_ PLUID_AND_ATTRIBUTES PrivArrayToken1, _In_ ULONG CountPrivArray1, _In_ PLUID_AND_ATTRIBUTES PrivArrayToken2, _In_ ULONG CountPrivArray2)
 Compares the elements of privilege arrays provided by tokens. The elements that are being compared for equality are the privileges and their attributes.
 
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 are met then the tokens are deemed as equal.
 
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 impersonation procedure is done here.
 
VOID SepUpdateSinglePrivilegeFlagToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Updates the token's flags based upon the privilege that the token has been granted. The flag can either be taken out or given to the token if the attributes of the specified privilege is enabled or not.
 
BOOLEAN NTAPI SepTokenIsOwner (_In_ PACCESS_TOKEN _Token, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ BOOLEAN TokenLocked)
 Checks if a token belongs to the main user, being the owner.
 
VOID SepUpdatePrivilegeFlagsToken (_Inout_ PTOKEN Token)
 Updates the token's flags based upon the privilege that the token has been granted. The function uses the private helper, SepUpdateSinglePrivilegeFlagToken, in order to update the flags of a token.
 
VOID SepRemovePrivilegeToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Removes a privilege from the token.
 
VOID SepRemoveUserGroupToken (_Inout_ PTOKEN Token, _In_ ULONG Index)
 Removes a group from the token.
 
ULONG SepComputeAvailableDynamicSpace (_In_ ULONG DynamicCharged, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl)
 Computes the exact available dynamic area of an access token whilst querying token statistics.
 
NTSTATUS SepRebuildDynamicPartOfToken (_Inout_ PTOKEN AccessToken, _In_ ULONG NewDynamicPartSize)
 Re-builds the dynamic part area of an access token during an a default DACL or primary group replacement within the said token if the said dynamic area can't hold the new security content.
 
VOID NTAPI SepFreeProxyData (_Inout_ PVOID ProxyData)
 Frees (de-allocates) the proxy data memory block of a token.
 
NTSTATUS NTAPI SepCopyProxyData (_Out_ PVOID *Dest, _In_ PVOID Src)
 Copies the proxy data from the source into the destination of a token.
 
NTSTATUS NTAPI SeExchangePrimaryToken (_In_ PEPROCESS Process, _In_ PACCESS_TOKEN NewAccessToken, _Out_ PACCESS_TOKEN *OldAccessToken)
 Replaces the old access token of a process (pointed by the EPROCESS kernel structure) with a new access token. The new access token must be a primary token for use.
 
VOID NTAPI SeDeassignPrimaryToken (_Inout_ PEPROCESS Process)
 Removes the primary token of a process.
 
ULONG RtlLengthSidAndAttributes (_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
 Computes the length size of a SID.
 
NTSTATUS SepFindPrimaryGroupAndDefaultOwner (_In_ PTOKEN Token, _In_ PSID PrimaryGroup, _In_opt_ PSID DefaultOwner, _Out_opt_ PULONG PrimaryGroupIndex, _Out_opt_ PULONG DefaultOwnerIndex)
 Finds the primary group and default owner entity based on the submitted primary group instance and an access token.
 
NTSTATUS NTAPI SeSubProcessToken (_In_ PTOKEN ParentToken, _Out_ PTOKEN *Token, _In_ BOOLEAN InUse, _In_ ULONG SessionId)
 Subtracts a token in exchange of duplicating a new one.
 
NTSTATUS NTAPI SeIsTokenChild (_In_ PTOKEN Token, _Out_ PBOOLEAN IsChild)
 Checks if the token is a child of the other token of the current process that the calling thread is invoking this function.
 
NTSTATUS NTAPI SeIsTokenSibling (_In_ PTOKEN Token, _Out_ PBOOLEAN IsSibling)
 Checks if the token is a sibling of the other token of the current process that the calling thread is invoking this function.
 
NTSTATUS NTAPI SeCopyClientToken (_In_ PACCESS_TOKEN Token, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PACCESS_TOKEN *NewToken)
 Copies an existing access token (technically duplicating a new one).
 
BOOLEAN NTAPI SeTokenIsInert (_In_ PTOKEN Token)
 Determines if a token is a sandbox inert token or not, based upon the token flags.
 
VOID NTAPI SepDeleteToken (_In_ PVOID ObjectBody)
 Internal function that deals with access token object destruction and deletion. The function is used solely by the object manager mechanism that handles the life management of a token object.
 
VOID NTAPI SepInitializeTokenImplementation (VOID)
 Internal function that initializes critical kernel data for access token implementation in SRM.
 
VOID NTAPI SeAssignPrimaryToken (_In_ PEPROCESS Process, _In_ PTOKEN Token)
 Assigns a primary access token to a given process.
 
VOID NTAPI SeGetTokenControlInformation (_In_ PACCESS_TOKEN _Token, _Out_ PTOKEN_CONTROL TokenControl)
 Retrieves token control information.
 
PTOKEN NTAPI SepCreateSystemProcessToken (VOID)
 Creates the system process token.
 
PTOKEN SepCreateSystemAnonymousLogonToken (VOID)
 Creates the anonymous logon token for the system. The difference between this token and the other one is the inclusion of everyone SID group (being SeWorldSid). The other token lacks such group.
 
PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone (VOID)
 Creates the anonymous logon token for the system. This kind of token doesn't include the everyone SID group (being SeWorldSid).
 
NTSTATUS NTAPI SeQuerySessionIdToken (_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
 Queries the session ID of an access token.
 
NTSTATUS NTAPI SeQueryAuthenticationIdToken (_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
 Queries the authentication ID of an access token.
 
SECURITY_IMPERSONATION_LEVEL NTAPI SeTokenImpersonationLevel (_In_ PACCESS_TOKEN Token)
 Gathers the security impersonation level of an access token.
 
TOKEN_TYPE NTAPI SeTokenType (_In_ PACCESS_TOKEN Token)
 Gathers the token type of an access token. A token ca be either a primary token or impersonation token.
 
BOOLEAN NTAPI SeTokenIsAdmin (_In_ PACCESS_TOKEN Token)
 Determines if a token is either an admin token or not. Such condition is checked based upon TOKEN_HAS_ADMIN_GROUP flag, which means if the respective access token belongs to an administrator group or not.
 
BOOLEAN NTAPI SeTokenIsRestricted (_In_ PACCESS_TOKEN Token)
 Determines if a token is restricted or not, based upon the token flags.
 
BOOLEAN NTAPI SeTokenIsWriteRestricted (_In_ PACCESS_TOKEN Token)
 Determines if a token is write restricted, that is, nobody can write anything to it.
 
BOOLEAN NTAPI SeTokenCanImpersonate (_In_ PTOKEN ProcessToken, _In_ PTOKEN TokenToImpersonate, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 Ensures that client impersonation can occur by checking if the token we're going to assign as the impersonation token can be actually impersonated in the first place. The routine is used primarily by PsImpersonateClient.
 
NTSTATUS NTAPI NtOpenThreadTokenEx (_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
 Opens a token that is tied to a thread handle.
 
NTSTATUS NTAPI NtOpenThreadToken (_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _Out_ PHANDLE TokenHandle)
 Opens a token that is tied to a thread handle.
 
NTSTATUS NTAPI NtCompareTokens (_In_ HANDLE FirstTokenHandle, _In_ HANDLE SecondTokenHandle, _Out_ PBOOLEAN Equal)
 Compares tokens if they're equal or not.
 
NTSTATUS NTAPI NtImpersonateAnonymousToken (_In_ HANDLE ThreadHandle)
 Allows the calling thread to impersonate the system's anonymous logon token.
 

Variables

POBJECT_TYPE SeTokenObjectType = NULL
 
TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}}
 
LUID SeSystemAuthenticationId = SYSTEM_LUID
 
LUID SeAnonymousAuthenticationId = ANONYMOUS_LOGON_LUID
 
static GENERIC_MAPPING SepTokenMapping
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file token.c.

Function Documentation

◆ NtCompareTokens()

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
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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
Status
Definition: gdiplustypes.h:25
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define KernelMode
Definition: asm.h:34
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().

◆ NtImpersonateAnonymousToken()

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

Referenced by ImpersonateAnonymousToken(), and START_TEST().

◆ NtOpenThreadToken()

NTSTATUS NTAPI NtOpenThreadToken ( _In_ HANDLE  ThreadHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ BOOLEAN  OpenAsSelf,
_Out_ PHANDLE  TokenHandle 
)

Opens a token that is tied to a thread handle.

Parameters
[out]ThreadHandleThread handle where the token is about to be opened.
[in]DesiredAccessThe request access right for the token.
[in]OpenAsSelfIf set to TRUE, the access check will be made with the security context of the process of the calling thread (opening as self). Otherwise the access check will be made with the security context of the calling thread instead.
[out]TokenHandleThe opened token handle returned to the caller for use.
Returns
See NtOpenThreadTokenEx.

Definition at line 2281 of file token.c.

2286{
2287 return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
2288 TokenHandle);
2289}
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:718
NTSTATUS NTAPI NtOpenThreadTokenEx(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
Opens a token that is tied to a thread handle.
Definition: token.c:2079
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ ACCESS_MASK _In_ BOOLEAN OpenAsSelf
Definition: zwfuncs.h:700

Referenced by BaseGetNamedObjectDirectory(), CheckTokenMembership(), CreateProcessAsUserCommon(), CsrGetProcessLuid(), GetCallerLuid(), LsarSetSecurityObject(), NpGetUserNamep(), OpenThreadToken(), RSetServiceObjectSecurity(), RtlDefaultNpAcl(), RtlNewSecurityGrantedAccess(), RtlpGetImpersonationToken(), and START_TEST().

◆ NtOpenThreadTokenEx()

NTSTATUS NTAPI NtOpenThreadTokenEx ( _In_ HANDLE  ThreadHandle,
_In_ ACCESS_MASK  DesiredAccess,
_In_ BOOLEAN  OpenAsSelf,
_In_ ULONG  HandleAttributes,
_Out_ PHANDLE  TokenHandle 
)

Opens a token that is tied to a thread handle.

Parameters
[out]ThreadHandleThread handle where the token is about to be opened.
[in]DesiredAccessThe request access right for the token.
[in]OpenAsSelfIf set to TRUE, the access check will be made with the security context of the process of the calling thread (opening as self). Otherwise the access check will be made with the security context of the calling thread instead.
[in]HandleAttributesHandle attributes for the opened thread token handle.
[out]TokenHandleThe opened token handle returned to the caller for use.
Returns
Returns STATUS_SUCCESS if the function has successfully opened the thread token. STATUS_CANT_OPEN_ANONYMOUS is returned if a token has SecurityAnonymous as impersonation level and we cannot open it. A failure NTSTATUS code is returned otherwise.

Definition at line 2079 of file token.c.

2085{
2087 HANDLE hToken;
2088 PTOKEN Token, NewToken = NULL, PrimaryToken;
2094 PACL Dacl = NULL;
2097 BOOLEAN RestoreImpersonation = FALSE;
2098
2099 PAGED_CODE();
2100
2102
2103 if (PreviousMode != KernelMode)
2104 {
2105 _SEH2_TRY
2106 {
2108 }
2110 {
2111 /* Return the exception code */
2113 }
2114 _SEH2_END;
2115 }
2116
2117 /* Validate object attributes */
2119
2120 /*
2121 * At first open the thread token for information access and verify
2122 * that the token associated with thread is valid.
2123 */
2124
2127 NULL);
2128 if (!NT_SUCCESS(Status))
2129 {
2130 return Status;
2131 }
2132
2135 if (Token == NULL)
2136 {
2138 return STATUS_NO_TOKEN;
2139 }
2140
2142 {
2146 }
2147
2148 /*
2149 * Revert to self if OpenAsSelf is specified.
2150 */
2151
2152 if (OpenAsSelf)
2153 {
2154 RestoreImpersonation = PsDisableImpersonation(PsGetCurrentThread(),
2156 }
2157
2158 if (CopyOnOpen)
2159 {
2160 PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
2161
2163
2164 ObFastDereferenceObject(&Thread->ThreadsProcess->Token, PrimaryToken);
2165
2166 if (NT_SUCCESS(Status))
2167 {
2168 if (Dacl)
2169 {
2172 if (!NT_SUCCESS(Status))
2173 {
2174 DPRINT1("NtOpenThreadTokenEx(): Failed to create a security descriptor (Status 0x%lx)\n", Status);
2175 }
2176
2178 FALSE);
2179 if (!NT_SUCCESS(Status))
2180 {
2181 DPRINT1("NtOpenThreadTokenEx(): Failed to set a DACL to the security descriptor (Status 0x%lx)\n", Status);
2182 }
2183 }
2184
2187
2190 KernelMode, &NewToken);
2191 if (!NT_SUCCESS(Status))
2192 {
2193 DPRINT1("NtOpenThreadTokenEx(): Failed to duplicate the token (Status 0x%lx)\n", Status);
2194 }
2195
2196 ObReferenceObject(NewToken);
2197 Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
2198 &hToken);
2199 if (!NT_SUCCESS(Status))
2200 {
2201 DPRINT1("NtOpenThreadTokenEx(): Failed to insert the token object (Status 0x%lx)\n", Status);
2202 }
2203 }
2204 else
2205 {
2206 DPRINT1("NtOpenThreadTokenEx(): Failed to impersonate token from DACL (Status 0x%lx)\n", Status);
2207 }
2208 }
2209 else
2210 {
2213 PreviousMode, &hToken);
2214 if (!NT_SUCCESS(Status))
2215 {
2216 DPRINT1("NtOpenThreadTokenEx(): Failed to open the object (Status 0x%lx)\n", Status);
2217 }
2218 }
2219
2221
2222 if (RestoreImpersonation)
2223 {
2225 }
2226
2228
2230 {
2232 if (!NT_SUCCESS(Status))
2233 {
2234 DPRINT1("NtOpenThreadTokenEx(): Failed to impersonate the client (Status 0x%lx)\n", Status);
2235 }
2236 }
2237
2238 if (NewToken) ObDereferenceObject(NewToken);
2239
2241
2242 if (NT_SUCCESS(Status))
2243 {
2244 _SEH2_TRY
2245 {
2246 *TokenHandle = hToken;
2247 }
2249 {
2251 }
2252 _SEH2_END;
2253 }
2254
2255 return Status;
2256}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FALSE
Definition: types.h:117
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:149
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
@ SecurityAnonymous
Definition: lsa.idl:55
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
@ TokenImpersonation
Definition: imports.h:274
#define PsDereferenceImpersonationToken(T)
Definition: imports.h:298
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:433
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:403
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
NTSTATUS NTAPI SepCreateImpersonationTokenDacl(_In_ PTOKEN Token, _In_ PTOKEN PrimaryToken, _Out_ PACL *Dacl)
Allocates a discretionary access control list based on certain properties of a regular and primary ac...
Definition: acl.c:277
BOOLEAN NTAPI PsDisableImpersonation(IN PETHREAD Thread, OUT PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:915
VOID NTAPI PsRestoreImpersonation(IN PETHREAD Thread, IN PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:965
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
PACCESS_TOKEN NTAPI PsReferenceImpersonationToken(IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:849
NTSTATUS NTAPI PsImpersonateClient(IN PETHREAD Thread, IN PACCESS_TOKEN Token, IN BOOLEAN CopyOnOpen, IN BOOLEAN EffectiveOnly, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:610
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
#define STATUS_CANT_OPEN_ANONYMOUS
Definition: ntstatus.h:402
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
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 ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2742
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define TAG_ACL
Definition: tag.h:151
_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
#define ObReferenceObject
Definition: obfuncs.h:204
_Out_ PBOOLEAN CopyOnOpen
Definition: psfuncs.h:154
_Inout_ PSE_IMPERSONATION_STATE ImpersonationState
Definition: psfuncs.h:189
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58

Referenced by NtOpenThreadToken(), and START_TEST().

◆ RtlLengthSidAndAttributes()

ULONG RtlLengthSidAndAttributes ( _In_ ULONG  Count,
_In_ PSID_AND_ATTRIBUTES  Src 
)

Computes the length size of a SID.

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

Definition at line 965 of file token.c.

968{
969 ULONG i;
970 ULONG uLength;
971
972 PAGED_CODE();
973
974 uLength = Count * sizeof(SID_AND_ATTRIBUTES);
975 for (i = 0; i < Count; i++)
976 uLength += RtlLengthSid(Src[i].Sid);
977
978 return uLength;
979}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
int Count
Definition: noreturn.cpp:7
uint32_t ULONG
Definition: typedefs.h:59
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES

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

◆ SeAssignPrimaryToken()

VOID NTAPI SeAssignPrimaryToken ( _In_ PEPROCESS  Process,
_In_ PTOKEN  Token 
)

Assigns a primary access token to a given process.

Parameters
[in]ProcessProcess where the token is about to be assigned.
[in]TokenThe token to be assigned.
Returns
Nothing.

Definition at line 1440 of file token.c.

1443{
1444 PAGED_CODE();
1445
1446 /* Sanity checks */
1447 ASSERT(Token->TokenType == TokenPrimary);
1448 ASSERT(!Token->TokenInUse);
1449
1450 /* Clean any previous token */
1451 if (Process->Token.Object) SeDeassignPrimaryToken(Process);
1452
1453 /* Set the new token */
1455 Token->TokenInUse = TRUE;
1457}
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define ASSERT(a)
Definition: mode.c:44
@ TokenPrimary
Definition: imports.h:273
VOID NTAPI SeDeassignPrimaryToken(_Inout_ PEPROCESS Process)
Removes the primary token of a process.
Definition: token.c:936
VOID FASTCALL ObInitializeFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:107

◆ SeCopyClientToken()

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

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

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

Definition at line 1296 of file token.c.

1301{
1304
1305 PAGED_CODE();
1306
1308 NULL,
1309 0,
1310 NULL,
1311 NULL);
1312
1315 FALSE,
1317 Level,
1319 (PTOKEN*)NewToken);
1320
1321 return Status;
1322}
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

Referenced by PsImpersonateClient(), and SepCreateClientSecurity().

◆ SeDeassignPrimaryToken()

VOID NTAPI SeDeassignPrimaryToken ( _Inout_ PEPROCESS  Process)

Removes the primary token of a process.

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

Definition at line 936 of file token.c.

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

Referenced by PspDeleteProcessSecurity(), and SeAssignPrimaryToken().

◆ SeExchangePrimaryToken()

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

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

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

Definition at line 846 of file token.c.

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

Referenced by PspAssignPrimaryToken().

◆ SeGetTokenControlInformation()

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

Retrieves token control information.

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

Definition at line 1474 of file token.c.

1477{
1478 PTOKEN Token = _Token;
1479 PAGED_CODE();
1480
1481 /* Capture the main fields */
1482 TokenControl->AuthenticationId = Token->AuthenticationId;
1483 TokenControl->TokenId = Token->TokenId;
1484 TokenControl->TokenSource = Token->TokenSource;
1485
1486 /* Lock the token */
1488
1489 /* Capture the modified ID */
1490 TokenControl->ModifiedId = Token->ModifiedId;
1491
1492 /* Unlock it */
1494}
#define SepAcquireTokenLockShared(Token)
Definition: se.h:280

Referenced by SepCreateClientSecurity().

◆ SeIsTokenChild()

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

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

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

Definition at line 1187 of file token.c.

1190{
1191 PTOKEN ProcessToken;
1192 LUID ProcessTokenId, CallerParentId;
1193
1194 /* Assume failure */
1195 *IsChild = FALSE;
1196
1197 /* Reference the process token */
1199 if (!ProcessToken)
1200 return STATUS_UNSUCCESSFUL;
1201
1202 /* Get its token ID */
1203 ProcessTokenId = ProcessToken->TokenId;
1204
1205 /* Dereference the token */
1207
1208 /* Get our parent token ID */
1209 CallerParentId = Token->ParentTokenId;
1210
1211 /* Compare the token IDs */
1212 if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1213 *IsChild = TRUE;
1214
1215 /* Return success */
1216 return STATUS_SUCCESS;
1217}
LUID TokenId
Definition: setypes.h:218
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301

Referenced by PspSetPrimaryToken().

◆ SeIsTokenSibling()

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

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

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

Definition at line 1236 of file token.c.

1239{
1240 PTOKEN ProcessToken;
1241 LUID ProcessParentId, ProcessAuthId;
1242 LUID CallerParentId, CallerAuthId;
1243
1244 /* Assume failure */
1245 *IsSibling = FALSE;
1246
1247 /* Reference the process token */
1249 if (!ProcessToken)
1250 return STATUS_UNSUCCESSFUL;
1251
1252 /* Get its parent and authentication IDs */
1253 ProcessParentId = ProcessToken->ParentTokenId;
1254 ProcessAuthId = ProcessToken->AuthenticationId;
1255
1256 /* Dereference the token */
1258
1259 /* Get our parent and authentication IDs */
1260 CallerParentId = Token->ParentTokenId;
1261 CallerAuthId = Token->AuthenticationId;
1262
1263 /* Compare the token IDs */
1264 if (RtlEqualLuid(&CallerParentId, &ProcessParentId) &&
1265 RtlEqualLuid(&CallerAuthId, &ProcessAuthId))
1266 {
1267 *IsSibling = TRUE;
1268 }
1269
1270 /* Return success */
1271 return STATUS_SUCCESS;
1272}
LUID AuthenticationId
Definition: setypes.h:219
LUID ParentTokenId
Definition: setypes.h:220

Referenced by PspSetPrimaryToken().

◆ SepComparePrivilegeAndAttributesFromTokens()

static BOOLEAN SepComparePrivilegeAndAttributesFromTokens ( _In_ PLUID_AND_ATTRIBUTES  PrivArrayToken1,
_In_ ULONG  CountPrivArray1,
_In_ PLUID_AND_ATTRIBUTES  PrivArrayToken2,
_In_ ULONG  CountPrivArray2 
)
static

Compares the elements of privilege arrays provided by tokens. The elements that are being compared for equality are the privileges and their attributes.

Parameters
[in]PrivArrayToken1Privilege array from the first token.
[in]CountPrivArray1Privilege count array from the first token.
[in]PrivArrayToken2Privilege array from the second token.
[in]CountPrivArray2Privilege count array from the second token.
Returns
Returns TRUE if the elements match from either arrays, FALSE otherwise.

Definition at line 174 of file token.c.

179{
180 ULONG FirstCount, SecondCount;
181 PLUID_AND_ATTRIBUTES FirstPrivArray, SecondPrivArray;
182 PAGED_CODE();
183
184 /* Bail out if index counters provided are not equal */
185 if (CountPrivArray1 != CountPrivArray2)
186 {
187 DPRINT("SepComparePrivilegeAndAttributesFromTokens(): Index counters are not the same!\n");
188 return FALSE;
189 }
190
191 /* Loop over the privilege arrays and compare them */
192 for (FirstCount = 0; FirstCount < CountPrivArray1; FirstCount++)
193 {
194 for (SecondCount = 0; SecondCount < CountPrivArray2; SecondCount++)
195 {
196 FirstPrivArray = &PrivArrayToken1[FirstCount];
197 SecondPrivArray = &PrivArrayToken2[SecondCount];
198
199 if (RtlEqualLuid(&FirstPrivArray->Luid, &SecondPrivArray->Luid) &&
200 FirstPrivArray->Attributes == SecondPrivArray->Attributes)
201 {
202 break;
203 }
204 }
205
206 /* We've exhausted the array of the second token without finding this one */
207 if (SecondCount == CountPrivArray2)
208 {
209 DPRINT("SepComparePrivilegeAndAttributesFromTokens(): No matching elements could be found in either token!\n");
210 return FALSE;
211 }
212 }
213
214 return TRUE;
215}
#define DPRINT
Definition: sndvol32.h:71

Referenced by SepCompareTokens().

◆ SepCompareSidAndAttributesFromTokens()

static BOOLEAN SepCompareSidAndAttributesFromTokens ( _In_ PSID_AND_ATTRIBUTES  SidArrayToken1,
_In_ ULONG  CountSidArray1,
_In_ PSID_AND_ATTRIBUTES  SidArrayToken2,
_In_ ULONG  CountSidArray2 
)
static

Compares the elements of SID arrays provided by tokens. The elements that are being compared for equality are the SIDs and their attributes.

Parameters
[in]SidArrayToken1SID array from the first token.
[in]CountSidArray1SID count array from the first token.
[in]SidArrayToken2SID array from the second token.
[in]CountSidArray2SID count array from the second token.
Returns
Returns TRUE if the elements match from either arrays, FALSE otherwise.

Definition at line 107 of file token.c.

112{
113 ULONG FirstCount, SecondCount;
114 PSID_AND_ATTRIBUTES FirstSidArray, SecondSidArray;
115 PAGED_CODE();
116
117 /* Bail out if index counters provided are not equal */
118 if (CountSidArray1 != CountSidArray2)
119 {
120 DPRINT("SepCompareSidAndAttributesFromTokens(): Index counters are not the same!\n");
121 return FALSE;
122 }
123
124 /* Loop over the SID arrays and compare them */
125 for (FirstCount = 0; FirstCount < CountSidArray1; FirstCount++)
126 {
127 for (SecondCount = 0; SecondCount < CountSidArray2; SecondCount++)
128 {
129 FirstSidArray = &SidArrayToken1[FirstCount];
130 SecondSidArray = &SidArrayToken2[SecondCount];
131
132 if (RtlEqualSid(FirstSidArray->Sid, SecondSidArray->Sid) &&
133 FirstSidArray->Attributes == SecondSidArray->Attributes)
134 {
135 break;
136 }
137 }
138
139 /* We've exhausted the array of the second token without finding this one */
140 if (SecondCount == CountSidArray2)
141 {
142 DPRINT("SepCompareSidAndAttributesFromTokens(): No matching elements could be found in either token!\n");
143 return FALSE;
144 }
145 }
146
147 return TRUE;
148}
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)

Referenced by SepCompareTokens().

◆ SepCompareTokens()

static NTSTATUS SepCompareTokens ( _In_ PTOKEN  FirstToken,
_In_ PTOKEN  SecondToken,
_Out_ PBOOLEAN  Equal 
)
static

Compares tokens if they're equal based on all the following properties. If all of the said conditions are met then the tokens are deemed as equal.

  • Every SID that is present in either token is also present in the other one.
  • Both or none of the tokens are restricted.
  • If both tokens are restricted, every SID that is restricted in either token is also restricted in the other one.
  • Every privilege present in either token is also present in the other one.
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.

Definition at line 243 of file token.c.

247{
249 PAGED_CODE();
250
251 ASSERT(FirstToken != SecondToken);
252
253 /* Lock the tokens */
254 SepAcquireTokenLockShared(FirstToken);
255 SepAcquireTokenLockShared(SecondToken);
256
257 /* Check if every SID that is present in either token is also present in the other one */
258 if (!SepCompareSidAndAttributesFromTokens(FirstToken->UserAndGroups,
259 FirstToken->UserAndGroupCount,
260 SecondToken->UserAndGroups,
261 SecondToken->UserAndGroupCount))
262 {
263 goto Quit;
264 }
265
266 /* Is one token restricted but the other isn't? */
267 Restricted = SeTokenIsRestricted(FirstToken);
268 if (Restricted != SeTokenIsRestricted(SecondToken))
269 {
270 /* If that's the case then bail out */
271 goto Quit;
272 }
273
274 /*
275 * If both tokens are restricted check if every SID
276 * that is restricted in either token is also restricted
277 * in the other one.
278 */
279 if (Restricted)
280 {
281 if (!SepCompareSidAndAttributesFromTokens(FirstToken->RestrictedSids,
282 FirstToken->RestrictedSidCount,
283 SecondToken->RestrictedSids,
284 SecondToken->RestrictedSidCount))
285 {
286 goto Quit;
287 }
288 }
289
290 /* Check if every privilege present in either token is also present in the other one */
291 if (!SepComparePrivilegeAndAttributesFromTokens(FirstToken->Privileges,
292 FirstToken->PrivilegeCount,
293 SecondToken->Privileges,
294 SecondToken->PrivilegeCount))
295 {
296 goto Quit;
297 }
298
299 /* If we're here then the tokens are equal */
300 IsEqual = TRUE;
301 DPRINT("SepCompareTokens(): Tokens are equal!\n");
302
303Quit:
304 /* Unlock the tokens */
305 SepReleaseTokenLock(SecondToken);
306 SepReleaseTokenLock(FirstToken);
307
308 *Equal = IsEqual;
309 return STATUS_SUCCESS;
310}
UNICODE_STRING Restricted
Definition: utils.c:24
static BOOLEAN SepComparePrivilegeAndAttributesFromTokens(_In_ PLUID_AND_ATTRIBUTES PrivArrayToken1, _In_ ULONG CountPrivArray1, _In_ PLUID_AND_ATTRIBUTES PrivArrayToken2, _In_ ULONG CountPrivArray2)
Compares the elements of privilege arrays provided by tokens. The elements that are being compared fo...
Definition: token.c:174
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:1913
static BOOLEAN SepCompareSidAndAttributesFromTokens(_In_ PSID_AND_ATTRIBUTES SidArrayToken1, _In_ ULONG CountSidArray1, _In_ PSID_AND_ATTRIBUTES SidArrayToken2, _In_ ULONG CountSidArray2)
Compares the elements of SID arrays provided by tokens. The elements that are being compared for equa...
Definition: token.c:107

Referenced by NtCompareTokens(), and SeExchangePrimaryToken().

◆ SepComputeAvailableDynamicSpace()

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

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

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

Definition at line 659 of file token.c.

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

Referenced by NtQueryInformationToken(), and SeQueryInformationToken().

◆ SepCopyProxyData()

NTSTATUS NTAPI SepCopyProxyData ( _Out_ PVOID Dest,
_In_ PVOID  Src 
)

Copies the proxy data from the source into the destination of a token.

@unimplemented

Parameters
[out]DestThe destination path where the proxy data is to be copied to.
[in]SrcThe source path where the proxy data is be copied from.
Returns
To be added...

Definition at line 815 of file token.c.

818{
821}
#define UNIMPLEMENTED
Definition: debug.h:115
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ SepCreateSystemAnonymousLogonToken()

PTOKEN SepCreateSystemAnonymousLogonToken ( VOID  )

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

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

Definition at line 1657 of file token.c.

1658{
1659 SID_AND_ATTRIBUTES Groups[32], UserSid;
1661 PTOKEN Token;
1662 ULONG GroupsLength;
1663 LARGE_INTEGER Expiration;
1666
1667 /* The token never expires */
1668 Expiration.QuadPart = -1;
1669
1670 /* The user is the anonymous logon */
1671 UserSid.Sid = SeAnonymousLogonSid;
1672 UserSid.Attributes = 0;
1673
1674 /* The primary group is also the anonymous logon */
1676
1677 /* The only group for the token is the World */
1678 Groups[0].Sid = SeWorldSid;
1680 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1681 SeLengthSid(Groups[0].Sid);
1682 ASSERT(GroupsLength <= sizeof(Groups));
1683
1684 /* Initialise the object attributes for the token */
1687
1688 /* Create token */
1690 KernelMode,
1691 0,
1696 &Expiration,
1697 &UserSid,
1698 1,
1699 Groups,
1700 GroupsLength,
1701 0,
1702 NULL,
1703 NULL,
1707 TRUE);
1709
1710 /* Return the anonymous logon token */
1711 return Token;
1712}
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
#define SE_GROUP_ENABLED
Definition: setypes.h:92
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
PSID SeAnonymousLogonSid
Definition: se.h:203
PSID SeWorldSid
Definition: sid.c:25
NTSTATUS NTAPI SepCreateToken(_Out_ PHANDLE TokenHandle, _In_ KPROCESSOR_MODE PreviousMode, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PSID_AND_ATTRIBUTES User, _In_ ULONG GroupCount, _In_ PSID_AND_ATTRIBUTES Groups, _In_ ULONG GroupsLength, _In_ ULONG PrivilegeCount, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_opt_ PSID Owner, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl, _In_ PTOKEN_SOURCE TokenSource, _In_ BOOLEAN SystemToken)
Internal function responsible for access token object creation in the kernel. A fully created token o...
Definition: tokenlif.c:97
TOKEN_SOURCE SeSystemTokenSource
Definition: token.c:19
LUID SeAnonymousAuthenticationId
Definition: token.c:21
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
LONGLONG QuadPart
Definition: typedefs.h:114
#define SeLengthSid(Sid)
Definition: sefuncs.h:570

Referenced by SepInitializationPhase0().

◆ SepCreateSystemAnonymousLogonTokenNoEveryone()

PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone ( VOID  )

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

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

Definition at line 1725 of file token.c.

1726{
1727 SID_AND_ATTRIBUTES UserSid;
1729 PTOKEN Token;
1730 LARGE_INTEGER Expiration;
1733
1734 /* The token never expires */
1735 Expiration.QuadPart = -1;
1736
1737 /* The user is the anonymous logon */
1738 UserSid.Sid = SeAnonymousLogonSid;
1739 UserSid.Attributes = 0;
1740
1741 /* The primary group is also the anonymous logon */
1743
1744 /* Initialise the object attributes for the token */
1747
1748 /* Create token */
1750 KernelMode,
1751 0,
1756 &Expiration,
1757 &UserSid,
1758 0,
1759 NULL,
1760 0,
1761 0,
1762 NULL,
1763 NULL,
1767 TRUE);
1769
1770 /* Return the anonymous (not including everyone) logon token */
1771 return Token;
1772}

Referenced by SepInitializationPhase0().

◆ SepCreateSystemProcessToken()

PTOKEN NTAPI SepCreateSystemProcessToken ( VOID  )

Creates the system process token.

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

Definition at line 1507 of file token.c.

1508{
1510 ULONG GroupAttributes, OwnerAttributes;
1511 SID_AND_ATTRIBUTES Groups[32];
1512 LARGE_INTEGER Expiration;
1513 SID_AND_ATTRIBUTES UserSid;
1514 ULONG GroupsLength;
1517 PSID Owner;
1518 ULONG i;
1519 PTOKEN Token;
1521
1522 /* Don't ever expire */
1523 Expiration.QuadPart = -1;
1524
1525 /* All groups mandatory and enabled */
1528
1529 /* User is Local System */
1530 UserSid.Sid = SeLocalSystemSid;
1531 UserSid.Attributes = 0;
1532
1533 /* Primary group is Local System */
1535
1536 /* Owner is Administrators */
1538
1539 /* Groups are Administrators, World, and Authenticated Users */
1540 Groups[0].Sid = SeAliasAdminsSid;
1541 Groups[0].Attributes = OwnerAttributes;
1542 Groups[1].Sid = SeWorldSid;
1543 Groups[1].Attributes = GroupAttributes;
1544 Groups[2].Sid = SeAuthenticatedUsersSid;
1545 Groups[2].Attributes = GroupAttributes;
1546 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1547 SeLengthSid(Groups[0].Sid) +
1548 SeLengthSid(Groups[1].Sid) +
1549 SeLengthSid(Groups[2].Sid);
1550 ASSERT(GroupsLength <= sizeof(Groups));
1551
1552 /* Setup the privileges */
1553 i = 0;
1555 Privileges[i++].Luid = SeTcbPrivilege;
1556
1557 Privileges[i].Attributes = 0;
1559
1560 Privileges[i].Attributes = 0;
1562
1565
1568
1569 Privileges[i].Attributes = 0;
1571
1572 Privileges[i].Attributes = 0;
1574
1577
1580
1582 Privileges[i++].Luid = SeDebugPrivilege;
1583
1585 Privileges[i++].Luid = SeAuditPrivilege;
1586
1587 Privileges[i].Attributes = 0;
1589
1590 Privileges[i].Attributes = 0;
1592
1595
1596 Privileges[i].Attributes = 0;
1597 Privileges[i++].Luid = SeBackupPrivilege;
1598
1599 Privileges[i].Attributes = 0;
1601
1602 Privileges[i].Attributes = 0;
1604
1605 Privileges[i].Attributes = 0;
1607
1610
1611 Privileges[i].Attributes = 0;
1613 ASSERT(i == 20);
1614
1615 /* Setup the object attributes */
1618
1619 /* Create the token */
1621 KernelMode,
1622 0,
1627 &Expiration,
1628 &UserSid,
1629 3,
1630 Groups,
1631 GroupsLength,
1632 20,
1633 Privileges,
1634 Owner,
1638 TRUE);
1640
1641 /* Return the token */
1642 return Token;
1643}
static const LUID SeChangeNotifyPrivilege
Definition: authpackage.c:167
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597
#define SE_GROUP_OWNER
Definition: setypes.h:93
PSID SeLocalSystemSid
Definition: sid.c:38
const LUID SeDebugPrivilege
Definition: priv.c:39
const LUID SeCreateTokenPrivilege
Definition: priv.c:21
const LUID SeBackupPrivilege
Definition: priv.c:36
const LUID SeAssignPrimaryTokenPrivilege
Definition: priv.c:22
const LUID SeSystemtimePrivilege
Definition: priv.c:31
PSID SeAliasAdminsSid
Definition: sid.c:41
const LUID SeTcbPrivilege
Definition: priv.c:26
const LUID SeRestorePrivilege
Definition: priv.c:37
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:33
const LUID SeLockMemoryPrivilege
Definition: priv.c:23
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
const LUID SeCreatePagefilePrivilege
Definition: priv.c:34
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
const LUID SeProfileSingleProcessPrivilege
Definition: priv.c:32
const LUID SeShutdownPrivilege
Definition: priv.c:38
const LUID SeSystemEnvironmentPrivilege
Definition: priv.c:41
const LUID SeSecurityPrivilege
Definition: priv.c:27
PSID SeAuthenticatedUsersSid
Definition: sid.c:49
const LUID SeAuditPrivilege
Definition: priv.c:40
const LUID SeIncreaseQuotaPrivilege
Definition: priv.c:24
PACL SeSystemDefaultDacl
Definition: acl.c:17
LUID SeSystemAuthenticationId
Definition: token.c:20
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT
Definition: setypes.h:62

Referenced by SepInitializationPhase0().

◆ SepCreateTokenLock()

NTSTATUS SepCreateTokenLock ( _Inout_ PTOKEN  Token)

Creates a lock for the token.

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

Definition at line 45 of file token.c.

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

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

◆ SepDeleteToken()

VOID NTAPI SepDeleteToken ( _In_ PVOID  ObjectBody)

Internal function that deals with access token object destruction and deletion. The function is used solely by the object manager mechanism that handles the life management of a token object.

Parameters
[in]ObjectBodyThe object body that represents an access token object.
Returns
Nothing.

Definition at line 1359 of file token.c.

1361{
1363 PTOKEN AccessToken = (PTOKEN)ObjectBody;
1364
1365 DPRINT("SepDeleteToken()\n");
1366
1367 /* Remove the referenced logon session from token */
1368 if (AccessToken->LogonSession)
1369 {
1371 if (!NT_SUCCESS(Status))
1372 {
1373 /* Something seriously went wrong */
1374 DPRINT1("SepDeleteToken(): Failed to remove the logon session from token (Status: 0x%lx)\n", Status);
1375 return;
1376 }
1377 }
1378
1379 /* Dereference the logon session */
1380 if ((AccessToken->TokenFlags & TOKEN_SESSION_NOT_REFERENCED) == 0)
1382
1383 /* Delete the token lock */
1384 if (AccessToken->TokenLock)
1385 SepDeleteTokenLock(AccessToken);
1386
1387 /* Delete the dynamic information area */
1388 if (AccessToken->DynamicPart)
1390}
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
NTSTATUS SepRmDereferenceLogonSession(_Inout_ PLUID LogonLuid)
VOID SepDeleteTokenLock(_Inout_ PTOKEN Token)
Deletes a lock of a token.
Definition: token.c:74
ULONG TokenFlags
Definition: setypes.h:241
PERESOURCE TokenLock
Definition: setypes.h:222
PULONG DynamicPart
Definition: setypes.h:237
PSEP_LOGON_SESSION_REFERENCES LogonSession
Definition: setypes.h:245
#define TAG_TOKEN_DYNAMIC
Definition: tag.h:158
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1180

Referenced by SepInitializeTokenImplementation().

◆ SepDeleteTokenLock()

VOID SepDeleteTokenLock ( _Inout_ PTOKEN  Token)

Deletes a lock of a token.

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

Definition at line 74 of file token.c.

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

Referenced by SepDeleteToken().

◆ SepFindPrimaryGroupAndDefaultOwner()

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

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

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

Definition at line 1011 of file token.c.

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

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

◆ SepFreeProxyData()

VOID NTAPI SepFreeProxyData ( _Inout_ PVOID  ProxyData)

Frees (de-allocates) the proxy data memory block of a token.

@unimplemented

Parameters
[in,out]ProxyDataThe proxy data to be freed.
Returns
Nothing.

Definition at line 793 of file token.c.

795{
797}

◆ SepImpersonateAnonymousToken()

static NTSTATUS SepImpersonateAnonymousToken ( _In_ PETHREAD  Thread,
_In_ KPROCESSOR_MODE  PreviousMode 
)
static

Private function that impersonates the system's anonymous logon token. The major bulk of the impersonation procedure is done here.

Parameters
[in]ThreadThe executive thread object that is to impersonate the client.
[in]PreviousModeThe access processor mode, indicating if the call is executed in kernel or user mode.
Returns
Returns STATUS_SUCCESS if the impersonation has succeeded. STATUS_UNSUCCESSFUL is returned if the primary token couldn't be obtained from the current process to perform additional tasks. STATUS_ACCESS_DENIED is returned if the process' primary token is restricted, which for this matter we cannot impersonate onto a restricted process. Otherwise a failure NTSTATUS code is returned.

Definition at line 334 of file token.c.

337{
339 PTOKEN TokenToImpersonate, ProcessToken;
340 ULONG IncludeEveryoneValueData;
341 PAGED_CODE();
342
343 /*
344 * We must check first which kind of token
345 * shall we assign for the thread to impersonate,
346 * the one with Everyone Group SID or the other
347 * without. Invoke the registry helper to
348 * return the data value for us.
349 */
350 Status = SepRegQueryHelper(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Lsa",
351 L"EveryoneIncludesAnonymous",
352 REG_DWORD,
353 sizeof(IncludeEveryoneValueData),
354 &IncludeEveryoneValueData);
355 if (!NT_SUCCESS(Status))
356 {
357 DPRINT1("SepRegQueryHelper(): Failed to query the registry value (Status 0x%lx)\n", Status);
358 return Status;
359 }
360
361 if (IncludeEveryoneValueData == 0)
362 {
363 DPRINT("SepImpersonateAnonymousToken(): Assigning the token not including the Everyone Group SID...\n");
364 TokenToImpersonate = SeAnonymousLogonTokenNoEveryone;
365 }
366 else
367 {
368 DPRINT("SepImpersonateAnonymousToken(): Assigning the token including the Everyone Group SID...\n");
369 TokenToImpersonate = SeAnonymousLogonToken;
370 }
371
372 /*
373 * Tell the object manager that we're going to use this token
374 * object now by incrementing the reference count.
375 */
376 Status = ObReferenceObjectByPointer(TokenToImpersonate,
380 if (!NT_SUCCESS(Status))
381 {
382 DPRINT1("SepImpersonateAnonymousToken(): Couldn't be able to use the token, bail out...\n");
383 return Status;
384 }
385
386 /*
387 * Reference the primary token of the current process that the anonymous
388 * logon token impersonation procedure is being performed. We'll be going
389 * to use the process' token to figure out if the process is actually
390 * restricted or not.
391 */
393 if (!ProcessToken)
394 {
395 DPRINT1("SepImpersonateAnonymousToken(): Couldn't be able to get the process' primary token, bail out...\n");
396 ObDereferenceObject(TokenToImpersonate);
397 return STATUS_UNSUCCESSFUL;
398 }
399
400 /* Now, is the token from the current process restricted? */
401 if (SeTokenIsRestricted(ProcessToken))
402 {
403 DPRINT1("SepImpersonateAnonymousToken(): The process is restricted, can't do anything. Bail out...\n");
404 PsDereferencePrimaryToken(ProcessToken);
405 ObDereferenceObject(TokenToImpersonate);
407 }
408
409 /*
410 * Finally it's time to impersonate! But first, fast dereference the
411 * process' primary token as we no longer need it.
412 */
415 if (!NT_SUCCESS(Status))
416 {
417 DPRINT1("SepImpersonateAnonymousToken(): Failed to impersonate, bail out...\n");
418 ObDereferenceObject(TokenToImpersonate);
419 return Status;
420 }
421
422 return Status;
423}
@ SecurityImpersonation
Definition: lsa.idl:57
PTOKEN SeAnonymousLogonToken
Definition: semgr.c:19
NTSTATUS NTAPI SepRegQueryHelper(_In_ PCWSTR KeyName, _In_ PCWSTR ValueName, _In_ ULONG ValueType, _In_ ULONG DataLength, _Out_ PVOID ValueData)
A private registry helper that returns the desired value data based on the specifics requested by the...
Definition: srm.c:93
PTOKEN SeAnonymousLogonTokenNoEveryone
Definition: semgr.c:20
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
#define REG_DWORD
Definition: sdbapi.c:596
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define TOKEN_IMPERSONATE
Definition: setypes.h:923

Referenced by NtImpersonateAnonymousToken().

◆ SepInitializeTokenImplementation()

VOID NTAPI SepInitializeTokenImplementation ( VOID  )

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

Returns
Nothing.

Definition at line 1403 of file token.c.

1404{
1406 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1407
1408 DPRINT("Creating Token Object Type\n");
1409
1410 /* Initialize the Token type */
1411 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
1412 RtlInitUnicodeString(&Name, L"Token");
1413 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
1414 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
1415 ObjectTypeInitializer.SecurityRequired = TRUE;
1416 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(TOKEN);
1417 ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1418 ObjectTypeInitializer.PoolType = PagedPool;
1419 ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1420 ObjectTypeInitializer.UseDefaultObject = TRUE;
1421 ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1422 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1423}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define PagedPool
Definition: env_spec_w32.h:308
#define OBJ_OPENLINK
Definition: winternl.h:230
struct _TOKEN TOKEN
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
VOID NTAPI SepDeleteToken(_In_ PVOID ObjectBody)
Internal function that deals with access token object destruction and deletion. The function is used ...
Definition: token.c:1359
static GENERIC_MAPPING SepTokenMapping
Definition: token.c:23
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1121
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define TOKEN_ALL_ACCESS
Definition: setypes.h:942

Referenced by SepInitializationPhase0().

◆ SepRebuildDynamicPartOfToken()

NTSTATUS SepRebuildDynamicPartOfToken ( _Inout_ PTOKEN  AccessToken,
_In_ ULONG  NewDynamicPartSize 
)

Re-builds the dynamic part area of an access token during an a default DACL or primary group replacement within the said token if the said dynamic area can't hold the new security content.

Parameters
[in]AccessTokenA pointer to an access token where its dynamic part is to be re-built and expanded based upon the new dynamic part size provided by the caller. Dynamic part expansion is not always guaranteed. See Remarks for further information.
[in]NewDynamicPartSizeThe new dynamic part size.
Returns
Returns STATUS_SUCCESS if the function has completed its operations successfully. STATUS_INSUFFICIENT_RESOURCES is returned if the new dynamic part could not be allocated.
Remarks
STATUS_SUCCESS does not indicate if the function has re-built the dynamic part of a token. If the current dynamic area size suffices the new dynamic area length provided by the caller then the dynamic area can hold the new security content buffer so dynamic part expansion is not necessary.

Definition at line 715 of file token.c.

718{
719 PVOID NewDynamicPart;
720 PVOID PreviousDynamicPart;
721 ULONG CurrentDynamicLength;
722
723 PAGED_CODE();
724
725 /* Sanity checks */
726 ASSERT(AccessToken);
727 ASSERT(NewDynamicPartSize != 0);
728
729 /*
730 * Compute the exact length of the available
731 * dynamic part of the access token.
732 */
733 CurrentDynamicLength = AccessToken->DynamicAvailable + RtlLengthSid(AccessToken->PrimaryGroup);
734 if (AccessToken->DefaultDacl)
735 {
736 CurrentDynamicLength += AccessToken->DefaultDacl->AclSize;
737 }
738
739 /*
740 * Figure out if the current dynamic part is too small
741 * to fit new contents inside the said dynamic part.
742 * Rebuild the dynamic area and expand it if necessary.
743 */
744 if (CurrentDynamicLength < NewDynamicPartSize)
745 {
746 NewDynamicPart = ExAllocatePoolWithTag(PagedPool,
747 NewDynamicPartSize,
749 if (NewDynamicPart == NULL)
750 {
751 DPRINT1("SepRebuildDynamicPartOfToken(): Insufficient resources to allocate new dynamic part!\n");
753 }
754
755 /* Copy the existing dynamic part */
756 PreviousDynamicPart = AccessToken->DynamicPart;
757 RtlCopyMemory(NewDynamicPart, PreviousDynamicPart, CurrentDynamicLength);
758
759 /* Update the available dynamic area and assign new dynamic */
760 AccessToken->DynamicAvailable += NewDynamicPartSize - CurrentDynamicLength;
761 AccessToken->DynamicPart = NewDynamicPart;
762
763 /* Move the contents (primary group and default DACL) addresses as well */
764 AccessToken->PrimaryGroup = (PSID)((ULONG_PTR)AccessToken->DynamicPart +
765 ((ULONG_PTR)AccessToken->PrimaryGroup - (ULONG_PTR)PreviousDynamicPart));
766 if (AccessToken->DefaultDacl != NULL)
767 {
768 AccessToken->DefaultDacl = (PACL)((ULONG_PTR)AccessToken->DynamicPart +
769 ((ULONG_PTR)AccessToken->DefaultDacl - (ULONG_PTR)PreviousDynamicPart));
770 }
771
772 /* And discard the previous dynamic part */
773 DPRINT("SepRebuildDynamicPartOfToken(): The dynamic part has been re-built with success!\n");
774 ExFreePoolWithTag(PreviousDynamicPart, TAG_TOKEN_DYNAMIC);
775 }
776
777 return STATUS_SUCCESS;
778}
#define ULONG_PTR
Definition: config.h:101
struct _SID * PSID
Definition: eventlog.c:35
struct _ACL * PACL
Definition: security.c:105
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ SepRemovePrivilegeToken()

VOID SepRemovePrivilegeToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

Removes a privilege from the token.

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

Definition at line 582 of file token.c.

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

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

◆ SepRemoveUserGroupToken()

VOID SepRemoveUserGroupToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

Removes a group from the token.

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

Definition at line 618 of file token.c.

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

Referenced by SepDuplicateToken().

◆ SepTokenIsOwner()

BOOLEAN NTAPI SepTokenIsOwner ( _In_ PACCESS_TOKEN  _Token,
_In_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ BOOLEAN  TokenLocked 
)

Checks if a token belongs to the main user, being the owner.

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

Definition at line 511 of file token.c.

515{
516 PSID Sid;
518 PTOKEN Token = _Token;
519
520 /* Get the owner SID */
522 ASSERT(Sid != NULL);
523
524 /* Lock the token if needed */
525 if (!TokenLocked) SepAcquireTokenLockShared(Token);
526
527 /* Check if the owner SID is found, handling restricted case as well */
529 if ((Result) && (Token->TokenFlags & TOKEN_IS_RESTRICTED))
530 {
532 }
533
534 /* Release the lock if we had acquired it */
535 if (!TokenLocked) SepReleaseTokenLock(Token);
536
537 /* Return the result */
538 return Result;
539}
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:99
BOOLEAN NTAPI SepSidInToken(_In_ PACCESS_TOKEN _Token, _In_ PSID Sid)
Checks if a SID is present in a token.
Definition: sid.c:547
BOOLEAN NTAPI SepSidInTokenEx(_In_ PACCESS_TOKEN _Token, _In_ PSID PrincipalSelfSid, _In_ PSID _Sid, _In_ BOOLEAN Deny, _In_ BOOLEAN Restricted)
Checks if a SID is present in a token.
Definition: sid.c:443
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1179

Referenced by NtAccessCheck(), and SeAccessCheck().

◆ SepUpdatePrivilegeFlagsToken()

VOID SepUpdatePrivilegeFlagsToken ( _Inout_ PTOKEN  Token)

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

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

Definition at line 554 of file token.c.

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

Referenced by SepCreateToken().

◆ SepUpdateSinglePrivilegeFlagToken()

VOID SepUpdateSinglePrivilegeFlagToken ( _Inout_ PTOKEN  Token,
_In_ ULONG  Index 
)

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

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

Definition at line 442 of file token.c.

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

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

◆ SeQueryAuthenticationIdToken()

NTSTATUS NTAPI SeQueryAuthenticationIdToken ( _In_ PACCESS_TOKEN  Token,
_Out_ PLUID  LogonId 
)

Queries the authentication ID of an access token.

Parameters
[in]TokenA valid access token where the authentication ID has to be gathered.
[out]pSessionIdThe returned pointer to an authentication ID to the caller.
Returns
Returns STATUS_SUCCESS.

Definition at line 1823 of file token.c.

1826{
1827 PAGED_CODE();
1828
1829 *LogonId = ((PTOKEN)Token)->AuthenticationId;
1830
1831 return STATUS_SUCCESS;
1832}
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId

Referenced by GetProcessLuid(), KsecGetKeyData(), nfs41_GetLUID(), NtSetUuidSeed(), ObpReferenceDeviceMap(), ObpSetCurrentProcessDeviceMap(), RxGetUid(), and RxInitializeVNetRootParameters().

◆ SeQuerySessionIdToken()

NTSTATUS NTAPI SeQuerySessionIdToken ( _In_ PACCESS_TOKEN  Token,
_Out_ PULONG  pSessionId 
)

Queries the session ID of an access token.

Parameters
[in]TokenA valid access token where the session ID has to be gathered.
[out]pSessionIdThe returned pointer to a session ID to the caller.
Returns
Returns STATUS_SUCCESS.

Definition at line 1791 of file token.c.

1794{
1795 PAGED_CODE();
1796
1797 /* Lock the token */
1799
1800 *pSessionId = ((PTOKEN)Token)->SessionId;
1801
1802 /* Unlock the token */
1804
1805 return STATUS_SUCCESS;
1806}

Referenced by NtQueryInformationToken(), RxGetSessionId(), RxInitializeVNetRootParameters(), and SeQueryInformationToken().

◆ SeSubProcessToken()

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

Subtracts a token in exchange of duplicating a new one.

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

Definition at line 1127 of file token.c.

1132{
1133 PTOKEN NewToken;
1136
1137 /* Initialize the attributes and duplicate it */
1139 Status = SepDuplicateToken(ParentToken,
1141 FALSE,
1143 ParentToken->ImpersonationLevel,
1144 KernelMode,
1145 &NewToken);
1146 if (NT_SUCCESS(Status))
1147 {
1148 /* Insert it */
1149 Status = ObInsertObject(NewToken,
1150 NULL,
1151 0,
1152 0,
1153 NULL,
1154 NULL);
1155 if (NT_SUCCESS(Status))
1156 {
1157 /* Set the session ID */
1158 NewToken->SessionId = SessionId;
1159 NewToken->TokenInUse = InUse;
1160
1161 /* Return the token */
1162 *Token = NewToken;
1163 }
1164 }
1165
1166 /* Return status */
1167 return Status;
1168}
ULONG SessionId
Definition: dllmain.c:28

Referenced by PspInitializeProcessSecurity().

◆ SeTokenCanImpersonate()

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

Ensures that client impersonation can occur by checking if the token we're going to assign as the impersonation token can be actually impersonated in the first place. The routine is used primarily by PsImpersonateClient.

Parameters
[in]ProcessTokenToken from a process.
[in]TokenToImpersonateToken that we are going to impersonate.
[in]ImpersonationLevelSecurity impersonation level grade.
Returns
Returns TRUE if the conditions checked are met for token impersonation, FALSE otherwise.

Definition at line 1969 of file token.c.

1973{
1974 BOOLEAN CanImpersonate;
1975 PAGED_CODE();
1976
1977 /*
1978 * SecurityAnonymous and SecurityIdentification levels do not
1979 * allow impersonation.
1980 */
1983 {
1984 return FALSE;
1985 }
1986
1987 /* Time to lock our tokens */
1988 SepAcquireTokenLockShared(ProcessToken);
1989 SepAcquireTokenLockShared(TokenToImpersonate);
1990
1991 /* What kind of authentication ID does the token have? */
1992 if (RtlEqualLuid(&TokenToImpersonate->AuthenticationId,
1994 {
1995 /*
1996 * OK, it looks like the token has an anonymous
1997 * authentication. Is that token created by the system?
1998 */
1999 if (TokenToImpersonate->TokenSource.SourceName != SeSystemTokenSource.SourceName &&
2000 !RtlEqualLuid(&TokenToImpersonate->TokenSource.SourceIdentifier, &SeSystemTokenSource.SourceIdentifier))
2001 {
2002 /* It isn't, we can't impersonate regular tokens */
2003 DPRINT("SeTokenCanImpersonate(): Token has an anonymous authentication ID, can't impersonate!\n");
2004 CanImpersonate = FALSE;
2005 goto Quit;
2006 }
2007 }
2008
2009 /* Are the SID values from both tokens equal? */
2010 if (!RtlEqualSid(ProcessToken->UserAndGroups->Sid,
2011 TokenToImpersonate->UserAndGroups->Sid))
2012 {
2013 /* They aren't, bail out */
2014 DPRINT("SeTokenCanImpersonate(): Tokens SIDs are not equal!\n");
2015 CanImpersonate = FALSE;
2016 goto Quit;
2017 }
2018
2019 /*
2020 * Make sure the tokens aren't diverged in terms of
2021 * restrictions, that is, one token is restricted
2022 * but the other one isn't.
2023 */
2024 if (SeTokenIsRestricted(ProcessToken) !=
2025 SeTokenIsRestricted(TokenToImpersonate))
2026 {
2027 /*
2028 * One token is restricted so we cannot
2029 * continue further at this point, bail out.
2030 */
2031 DPRINT("SeTokenCanImpersonate(): One token is restricted, can't continue!\n");
2032 CanImpersonate = FALSE;
2033 goto Quit;
2034 }
2035
2036 /* If we've reached that far then we can impersonate! */
2037 DPRINT("SeTokenCanImpersonate(): We can impersonate.\n");
2038 CanImpersonate = TRUE;
2039
2040Quit:
2041 /* We're done, unlock the tokens now */
2042 SepReleaseTokenLock(ProcessToken);
2043 SepReleaseTokenLock(TokenToImpersonate);
2044
2045 return CanImpersonate;
2046}
@ SecurityIdentification
Definition: lsa.idl:56
CCHAR SourceName[TOKEN_SOURCE_LENGTH]
Definition: imports.h:278
LUID SourceIdentifier
Definition: imports.h:279

Referenced by PsImpersonateClient().

◆ SeTokenImpersonationLevel()

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

◆ SeTokenIsAdmin()

BOOLEAN NTAPI SeTokenIsAdmin ( _In_ PACCESS_TOKEN  Token)

Determines if a token is either an admin token or not. Such condition is checked based upon TOKEN_HAS_ADMIN_GROUP flag, which means if the respective access token belongs to an administrator group or not.

Parameters
[in]TokenA valid access token to determine if such token is admin or not.
Returns
Returns TRUE if the token is an admin one, FALSE otherwise.

Definition at line 1890 of file token.c.

1892{
1893 PAGED_CODE();
1894
1895 // NOTE: Win7+ instead really checks the list of groups in the token
1896 // (since TOKEN_HAS_ADMIN_GROUP == TOKEN_WRITE_RESTRICTED ...)
1897 return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
1898}
#define TOKEN_HAS_ADMIN_GROUP
Definition: setypes.h:1178

Referenced by PsImpersonateClient().

◆ SeTokenIsInert()

BOOLEAN NTAPI SeTokenIsInert ( _In_ PTOKEN  Token)

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

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

Definition at line 1337 of file token.c.

1339{
1340 PAGED_CODE();
1341
1342 return (((PTOKEN)Token)->TokenFlags & TOKEN_SANDBOX_INERT) != 0;
1343}
#define TOKEN_SANDBOX_INERT
Definition: setypes.h:1181

Referenced by NtQueryInformationToken().

◆ SeTokenIsRestricted()

BOOLEAN NTAPI SeTokenIsRestricted ( _In_ PACCESS_TOKEN  Token)

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

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

Definition at line 1913 of file token.c.

1915{
1916 PAGED_CODE();
1917
1918 return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
1919}

Referenced by NtQueryInformationToken(), PsImpersonateClient(), RxInitializeVNetRootParameters(), SepAccessCheck(), SepCompareTokens(), SepDumpTokenDebugInfo(), SepImpersonateAnonymousToken(), and SeTokenCanImpersonate().

◆ SeTokenIsWriteRestricted()

BOOLEAN NTAPI SeTokenIsWriteRestricted ( _In_ PACCESS_TOKEN  Token)

Determines if a token is write restricted, that is, nobody can write anything to it.

Parameters
[in]TokenA valid access token to determine if such token is write restricted.
Returns
Returns TRUE if the token is write restricted, FALSE otherwise.
Remarks
First introduced in NT 5.1 SP2 x86 (5.1.2600.2622), absent in NT 5.2, then finally re-introduced in Vista+.

Definition at line 1938 of file token.c.

1940{
1941 PAGED_CODE();
1942
1943 // NOTE: NT 5.1 SP2 x86 checks the SE_BACKUP_PRIVILEGES_CHECKED flag
1944 // while Vista+ checks the TOKEN_WRITE_RESTRICTED flag as one expects.
1945 return (((PTOKEN)Token)->TokenFlags & SE_BACKUP_PRIVILEGES_CHECKED) != 0;
1946}
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1183

◆ SeTokenType()

TOKEN_TYPE NTAPI SeTokenType ( _In_ PACCESS_TOKEN  Token)

Gathers the token type of an access token. A token ca be either a primary token or impersonation token.

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

Definition at line 1867 of file token.c.

1869{
1870 PAGED_CODE();
1871
1872 return ((PTOKEN)Token)->TokenType;
1873}

Variable Documentation

◆ SeAnonymousAuthenticationId

◆ SepTokenMapping

GENERIC_MAPPING SepTokenMapping
static
Initial value:
= {
}
#define TOKEN_WRITE
Definition: setypes.h:949
#define TOKEN_READ
Definition: setypes.h:947
#define TOKEN_EXECUTE
Definition: setypes.h:954

Definition at line 23 of file token.c.

Referenced by SepInitializeTokenImplementation().

◆ SeSystemAuthenticationId

LUID SeSystemAuthenticationId = SYSTEM_LUID

Definition at line 20 of file token.c.

Referenced by SepCreateSystemProcessToken(), SepRmDeleteLogonSession(), and SeRmInitPhase0().

◆ SeSystemTokenSource

◆ SeTokenObjectType