When user tries to access the controller method from web application, the below code will be executed to create a process as impersonated/logged on user. Below code executed without any issues. New Notepad has been created but the process owner is server user not the logged on user. Please let me know what I am missing from the below code to create a process as impersonated user.
Note: Running eclipse/sts as Admin user and the primary token (processToken) has all the required privilege for impersonation.
public String createProcessAsUser(HttpServletRequest req) {
// Enabled Error handler to all the functions -- No Errors
HANDLEByReference processToken = new HANDLEByReference();
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
// Get Current process Handle -- Access Token of the active user
if (!Advapi32.INSTANCE.OpenProcessToken(
processHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ALL_ACCESS
| WinNT.TOKEN_ASSIGN_PRIMARY | WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_IMPERSONATE,
processToken)) {
int rc = Kernel32.INSTANCE.GetLastError();
if (rc != W32Errors.ERROR_NO_TOKEN) {
throw new Win32Exception(rc);
}
}
WinNT.LUID luid = null;
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(2);
/*
* Required privileges to assign token for Impersonation.
User doesn't have SE_ASSIGNPRIMARYTOKEN_NAME privilege, so couldn't be
enabled/disabled
*
*/
String[] privileges = { WinNT.SE_INCREASE_QUOTA_NAME, WinNT.SE_ASSIGNPRIMARYTOKEN_NAME };
for (int i = 0; i < privileges.length; i++) {
luid = new WinNT.LUID();
if (Advapi32.INSTANCE.LookupPrivilegeValue("", privileges[i], luid)) {
tp.Privileges[i] = new LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
} else {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
}
// Enable Privileges to the existing Process handle/Token
if (!Advapi32.INSTANCE.AdjustTokenPrivileges(processToken.getValue(), false, tp, tp.size(), null,
new IntByReference())) {
Win32Exception error = new Win32Exception(Kernel32.INSTANCE.GetLastError());
System.out.println(error.getMessage());
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
// Impersonate logged on user
if (!Advapi32.INSTANCE.ImpersonateLoggedOnUser(processToken.getValue())) { /* This returns true */
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
WinNT.HANDLEByReference primaryToken = new WinNT.HANDLEByReference();
// Duplicate impersonated token to create a primary token to invoke the
// CreateProcessAsUser
if (!Advapi32.INSTANCE.DuplicateTokenEx(processToken.getValue(),
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ASSIGN_PRIMARY | WinNT.TOKEN_ADJUST_DEFAULT
| WinNT.TOKEN_ALL_ACCESS,
null, WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, WinNT.TOKEN_TYPE.TokenPrimary,
primaryToken)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
WinBase.STARTUPINFO startupInfo = new WinBase.STARTUPINFO();
WinBase.PROCESS_INFORMATION processInfo = new WinBase.PROCESS_INFORMATION();
if (!Advapi32.INSTANCE.CreateProcessAsUser(primaryToken.getValue(), "C:\\Windows\\notepad.exe", null, null,
null, false, WinNT.CREATE_NEW_CONSOLE | WinNT.CREATE_UNICODE_ENVIRONMENT, null, null, startupInfo,
processInfo)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
return String.format("New Process created ");
}