Click here to Skip to main content
15,879,474 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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:

C++
int LaunchAppWithElevatedPrivilege (
	LPTSTR lpszUsername,    // client to log on
	LPTSTR lpszDomain,      // domain of client's account
	LPTSTR lpszPassword,    // client's password
	LPTSTR lpCommandLine    // command line to execute e.g. L"C:\\windows\\regedit.exe"
	)
{
	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,            // client's access token
			NULL,              // file to execute
			lpCommandLine,     // command line
			NULL,              // pointer to process SECURITY_ATTRIBUTES
			NULL,              // pointer to thread SECURITY_ATTRIBUTES
			FALSE,             // handles are not inheritable
			dwCreationFlags,   // creation flags
			pEnv,              // pointer to new environment block 
			NULL,              // name of current directory 
			&si,               // pointer to STARTUPINFO structure
			&pi                // receives information about new process
			);

		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
Posted
Updated 9-Jun-14 21:24pm
v2

1 solution

If you had searched more instead of posting it 3 times at codeproject, stackoverflow or msdn. Than you had found the dangerous hack Stack overflow

The best solution is with interactive services
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900