I have a service running as SYSTEM
that has to run some applications on users’ sessions. I can run non-elevated processes but I can’t run elevated processes.
I get the user’s token via WTSQueryUserToken
(I have user’s SessionId), set SeDebugPrivilege
, create environment with CreateEnvironmentBlock
and then call CreateProcessAsUser
. Setting SeDebugPrivilege
via AdjustTokenPrivileges
fails with ERROR_NOT_ALL_ASSIGNED
error code.
What am I missing? Any help is appreciated. Thanks
bool runPrivilegedProcess(ULONG sessionId)
{
HANDLE userToken;
// get user token with sessionId
if (WTSQueryUserToken(sessionId, &userToken) == FALSE)
{
debugFile << "WTSQueryUserToken failed: " << GetLastError() << std::endl;
return false;
}
if (SetPrivilege(userToken, "SeDebugPrivilege") == false)
{
debugFile << "SetPrivilege failedn";
//CloseHandle(userToken);
//return false;
}
STARTUPINFOW si;
memset(&si, 0, sizeof(STARTUPINFOW));
si.cb = sizeof(STARTUPINFOW);
PROCESS_INFORMATION processInfo;
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
DWORD dwFlags = DETACHED_PROCESS;
LPVOID pEnv = NULL;
if (CreateEnvironmentBlock(&pEnv, userToken, FALSE))
{
dwFlags |= CREATE_UNICODE_ENVIRONMENT;
}
else
debugFile << "CreateEnvironmentBlock failedn";
wchar_t processName[100] = L"C:\windows\system32\taskmgr.exe";
if (CreateProcessAsUserW(userToken, NULL, processName, NULL, NULL, false, dwFlags, pEnv, NULL, &si, &processInfo) == FALSE)
{
debugFile << "CreateProcessAsUserA failed: " << GetLastError() << std::endl;
CloseHandle(userToken);
return false;
}
debugFile << "Execution done. Child process ID is " << processInfo.dwProcessId << std::endl;
CloseHandle(userToken);
return true;
}
bool SetPrivilege(HANDLE hToken, const char* privilegeName)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if(LookupPrivilegeValueA(NULL, privilegeName, &luid) == FALSE)
{
debugFile << "LookupPrivilegeValueA failed: " << privilegeName << " " << GetLastError() << "n";
return false;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid.HighPart = luid.HighPart;
tp.Privileges[0].Luid.LowPart = luid.LowPart;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
{
debugFile << "AdjustTokenPrivileges error: " << privilegeName << " " << GetLastError() << "n";
return false;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return false; // always ends up here
else
return true;
}