My service is running under local system permissions, and needs to start an application with administrator permissions in the user session.
What I got is:
WTSGetActiveConsoleSessionID()
WTSQueryUserToken
for session IDCreateProcessAsUser
The problem is I need to run the process (Step 3) as an administrator, without asking the user for the administrator's password.
On Linux systems I would simply do a "su ", but to achieve this on a Windows system?
I've finally found the solution to manage this:
public void launchProcessInUserSession(String process) throws WindowsAPIException {
final DWORD interactiveSessionId = kernel32.WTSGetActiveConsoleSessionId();
final DWORD serviceSessionId = getCurrentSessionId();
final HANDLEByReference pExecutionToken = new HANDLEByReference();
final HANDLE currentProcessToken = getCurrentProcessToken();
try {
final HANDLE interactiveUserToken = getUserToken(interactiveSessionId);
checkAPIError(advapi32.DuplicateTokenEx(currentProcessToken, WinNT.TOKEN_ALL_ACCESS, null, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
WinNT.TOKEN_TYPE.TokenPrimary, pExecutionToken));
} finally {
kernel32.CloseHandle(currentProcessToken);
}
final HANDLE executionToken = pExecutionToken.getValue();
try {
checkAPIError(advapi32.SetTokenInformation(executionToken, TOKEN_INFORMATION_CLASS.TokenSessionId, new IntByReference(interactiveSessionId.intValue()), DWORD.SIZE));
final WinBase.STARTUPINFO si = new WinBase.STARTUPINFO();
final PROCESS_INFORMATION processInfo = new WinBase.PROCESS_INFORMATION();
final int dwFlags = WinBase.DETACHED_PROCESS;
checkAPIError(advapi32.CreateProcessAsUser(executionToken, null, process, null, null, false, dwFlags, null, null, si, processInfo));
LOGGER.debug("Execution done. Process ID is {}", processInfo.dwProcessId);
} finally {
kernel32.CloseHandle(executionToken);
}
}