Reputation: 805
I'm having some issues with some long-ago written classes that do thread-level impersonation and process spawning. The problem seems to be that my usage of these utility classes is above and beyond what anyone else has tried to do with them.
The first does thread-level impersonation by using OpenThreadToken and DuplicateToken along with ImpersonateLoggedOnUser.
The second attempts to create a process using CreateProcessAsUser with a token obtained with OpenThreadToken / DuplicateToken.
The issue I'm running into is that I have:
Thread 1 running in IIS with the correct user
Thread 2 that is created by Thread 1 - which is impersonated
Thread 3 that is created by Thread 2 - which is impersonated
Process 1 that is spawned by Thread 3 - which I attempt to impersonate
Spawning Process 1 fails with error code 5 from OpenThreadToken. If I spawn process 1 from Thread 1, OpenThreadToken doesn't give me any guff. I ask for TOKEN_ACCESS_ALL from OpenThreadToken & DuplicateToken and it doesn't fail until I actually do it from Thread 3. Anybody have any insight as to what permissions I may actually need here?
Here's the code for spawning the process:
(Impersonating the thread just involves taking the thread token handle and calling ImpersonateLoggedOnUser...)
//process spawn
if (!::OpenThreadToken(::GetCurrentThread(),
TOKEN_ALL_ACCESS,
false,
&hThreadUserToken))
{
Handle hNewProcessUserToken;
if (!DuplicateTokenEx(
hThreadUserToken,
TOKEN_ALL_ACCESS,
NULL,
SecurityDelegation,
TokenPrimary ,
&hNewProcessUserToken))
{
m_dwCreateError = ::GetLastError();
return false;
}
bReturnValue = ::CreateProcessAsUserA(
hNewProcessUserToken,
AppName,
cmdLine,
NULL,
NULL,
TRUE,
0,
m_lpEnvironment,
cwdStr
&m_StartupInfo,
&piProcInfo);
Anything obvious I'm doing wrong here? I can't really spawn the process from Thread 1 - it just doesn't have the right info it needs, and having a handle back to it from Thread 3 is...not a good solution and not good design.
Upvotes: 3
Views: 2345
Reputation: 5635
OpenThreadToken fails in the impersonated case because the impersonated user does not have permission to access the thread's token. You should pass OpenAsSelf = TRUE.
Upvotes: 3