While the main thread impersonates a client, my code creates a thread and assigns it the impersonation token using SetThreadToken
. Then the main thread closes the token.
Specifically, the main thread does this:
LogonUser
.DuplicateToken
from the primary token.ImpersonateLoggedOnUser
.SetThreadToken
on the thread with the impersonation token.RevertToSelf
.CloseHandle
on both the impersonation and the primary token.At this point, the secondary thread is still running. Does the impersonation token remain usable for the secondary thread even though the token handle has been closed in the main thread?
windows kernel use reference counting on objects. the TOKEN
is object too. when you assign token to thread (via SetThreadToken
) the pointer to TOKEN
object is stored in ETHREAD
object and additional reference added to TOKEN
object. of course kernel cannot rely on close you or not original handle (reference) to TOKEN
object. this is general pointer counting rule - if A
stored pointer to B
in self - it add reference to B
, for it will be valid until A
use B
. the token will be valid until your thread not impersonate another token, or end impersonation or exit. anyway after you assign token to thread you can close handle to it - token remain valid
if exist interest, how internal SetThreadToken
work:
SetThreadToken
call NtSetInformationThread
with ThreadImpersonationToken
information class. from kernel side implementation called PsAssignImpersonationToken
- this api declared in ntifs.h. it implementation call PsImpersonateClient
which and reference the passed token. as result it become valid util assigned to thread
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.
but anyway - we not need for this internal knowledge - need general think understand - object reference counting. if pointer to token saved in thread - this token of course must be valid until used by thread. as result it referenced. when thread stop using this token (change pointer or exit) - token dereferenced