Here is the case:
OS environment: Windows 7
There are two user accounts in my system, standard user "S" and administrator account "A", and there is a windows service running with "Local System" privilege.
Now i logged-in with account "S", and i want to launch an application with elevated administrator account "A" from that service program, so here is the code snippet:
int LaunchAppWithElevatedPrivilege (
LPTSTR lpszUsername, LPTSTR lpszDomain, LPTSTR lpszPassword, LPTSTR lpCommandLine )
{
DWORD dwExitCode = 0;
HANDLE hToken = NULL;
HANDLE hFullToken = NULL;
HANDLE hPrimaryFullToken = NULL;
HANDLE lsa = NULL;
BOOL bResult = FALSE;
LUID luid;
MSV1_0_INTERACTIVE_PROFILE* profile = NULL;
DWORD err;
PTOKEN_GROUPS LocalGroups = NULL;
DWORD dwLength = 0;
DWORD dwSessionId = 0;
LPVOID pEnv = NULL;
DWORD dwCreationFlags = 0;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
__try
{
if (!LogonUser( lpszUsername,
lpszDomain,
lpszPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken))
{
LOG_FAILED(L"GetTokenInformation failed!");
__leave;
}
if( !GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)19, (VOID*)&hFullToken,
sizeof(HANDLE), &dwLength))
{
LOG_FAILED(L"GetTokenInformation failed!");
__leave;
}
if(!DuplicateTokenEx(hFullToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hPrimaryFullToken))
{
LOG_FAILED(L"DuplicateTokenEx failed!");
__leave;
}
DWORD dwSessionId = 0;
WTS_SESSION_INFO* sessionInfo = NULL;
DWORD ndSessionInfoCount;
bResult = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &ndSessionInfoCount);
if (!bResult)
{
dwSessionId = WTSGetActiveConsoleSessionId();
}
else
{
for(unsigned int i=0; i<ndSessionInfoCount; i++)
{
if( sessionInfo[i].State == WTSActive )
{
dwSessionId = sessionInfo[i].SessionId;
}
}
}
if(0 == dwSessionId)
{
LOG_FAILED(L"Get active session id failed!");
__leave;
}
if(!SetTokenInformation(hPrimaryFullToken, TokenSessionId, &dwSessionId, sizeof(DWORD)))
{
LOG_FAILED(L"SetTokenInformation failed!");
__leave;
}
if(CreateEnvironmentBlock(&pEnv, hPrimaryFullToken, FALSE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
else
pEnv=NULL;
if (! ImpersonateLoggedOnUser(hPrimaryFullToken) )
{
LOG_FAILED(L"ImpersonateLoggedOnUser failed!");
__leave;
}
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";
bResult = CreateProcessAsUser(
hPrimaryFullToken, NULL, lpCommandLine, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi );
RevertToSelf();
if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &dwExitCode);
}
else
{
LOG_FAILED(L"CreateProcessAsUser failed!");
}
}
__finally
{
if (pi.hProcess != INVALID_HANDLE_VALUE)
CloseHandle(pi.hProcess);
if (pi.hThread != INVALID_HANDLE_VALUE)
CloseHandle(pi.hThread);
if(LocalGroups)
LocalFree(LocalGroups);
if(pEnv)
DestroyEnvironmentBlock(pEnv);
if(hToken)
CloseHandle(hToken);
if(hFullToken)
CloseHandle(hFullToken);
if(hPrimaryFullToken)
CloseHandle(hPrimaryFullToken);
}
return dwExitCode;
}
I passed in username and password of account "A" to method "LaunchAppWithElevatedPrivilege", and also the application i want to launch, e.g. "C:\windows\regedit.exe", but when i run the service program, i found it do launch "regedit.exe" with elevated account "A", but the content of regedit.exe is pure back. screenshot as below:
http://social.msdn.microsoft.com/Forums/getfile/463206
http://social.msdn.microsoft.com/Forums/getfile/463207