PsImpersonateClient function (ntifs.h)
The PsImpersonateClient routine causes a server thread to impersonate a client.
NTSTATUS PsImpersonateClient( [in, out] PETHREAD Thread, [in] PACCESS_TOKEN Token, [in] BOOLEAN CopyOnOpen, [in] BOOLEAN EffectiveOnly, [in] SECURITY_IMPERSONATION_LEVEL ImpersonationLevel );
[in, out] Thread
Pointer to the server thread that is to impersonate the client.
Pointer to the token to be assigned as the impersonation token. This token can be a primary token or an impersonation token. Set to NULL to end the impersonation.
Specifies whether the token can be opened directly. Set to TRUE to specify that the token cannot be opened directly. In this case, the token must be duplicated, and the duplicate token used instead. Set to FALSE to allow the token to be opened directly.
Set to FALSE to allow the server to enable groups and privileges that are currently disabled in the client security context, TRUE otherwise.
A SECURITY_IMPERSONATION_LEVEL value that specifies the impersonation level at which the server is to access the token.
PsImpersonateClient returns STATUS_SUCCESS or an appropriate NTSTATUS value, such as the following:
||It was not possible to impersonate a client because of job restrictions.|
||There was insufficient memory to complete the operation.|
PsImpersonateClient causes the specified server thread to impersonate the specified client.
The server thread could already be impersonating a client when PsImpersonateClient is called. If this is the case, the reference count on the token representing that client is decremented. To preserve this token for later use, drivers should call PsReferenceImpersonationToken before calling PsImpersonateClient and save the pointer that is returned by PsReferenceImpersonationToken.
To end the new impersonation and return the server thread to the previous impersonation, call PsImpersonateClient again, passing the saved pointer for the Token parameter. To end all impersonations, call the PsRevertToSelf routine.
Otherwise, to end the impersonation and return the server thread to its original security context (that is, the one represented by its primary token), call PsImpersonateClient again, passing a NULL pointer for the Token parameter.
The PsImpersonateClient routine can fail to successfully return the server thread to the previous impersonation if the thread is already impersonating or there are job restrictions.
The routine ensures whether client impersonation can actually occur by checking various conditions, including the following:
- The token passed by the caller doesn't have an anonymous authentication ID
- The process's token referenced from the server thread and the given token have equal security identifiers (SIDs)
- Neither of the tokens are restricted
If none of the conditions are met, the routine makes a copy of the existing token passed to the call and assigns the newly copied token as impersonation token albeit with limited security impersonation level; that is, the server thread can only obtain information about the client. If token copying is not possible, the routine fails with a NTSTATUS code.
It is extremely unsafe to raise the privilege state of an untrusted user thread (take a user's thread and impersonate LocalSystem, for example). If an untrusted user thread had its privilege raised, the user could grab the thread token after it has been elevated and subvert the security of the entire system.
In cases where a higher privilege state is required, the task should be dispatched to a work queue where the task can be safely handled by system worker thread . This way no impersonation is necessary.
The SeImpersonateClientEx routine can be used to cause a thread to impersonate a user.
For more information about security and access control, see the documentation on these topics in the Microsoft Windows SDK.
|Minimum supported client||Windows XP|
|Header||ntifs.h (include Ntifs.h)|
|DDI compliance rules||HwStorPortProhibitedDDIs(storport), PowerIrpDDis(wdm)|