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 ");
}
OpenProcessToken
,AdjustTokenPrivileges
,DuplicateTokenEx
,ImpersonateLoggedOnUser
andCreateProcessAsUser
works without any errors. Still newly created process owner is not the impersonated user. I might be missing some minor config changes or order of these function executions. Any small pointers/suggestions would be grateful. TIA! – DimeterWinNT.SE_INCREASE_QUOTA_NAME
try assigningSE_ASSIGNPRIMARYTOKEN_NAME
. Also consider tryingTOKEN_ALL_ACCESS
to start with to see if it works, in case you've missed aTOKEN_*
. (docs) – GristTOKEN_ALL_ACCESS
to the token andSE_ASSIGNPRIMARYTOKEN_NAME
privilege. Since the current user doesn't have the the privilegeSE_ASSIGNPRIMARYTOKEN_NAME
, this can not be enabled/disabled usingAdjustTokenPrivileges
. But no luck, still facing the same issue. SpringBoot properties for Waffle,waffle.sso.enabled=true; waffle.sso.protocols=NTLM; waffle.sso.basic-enabled=false;
I am using negotiate security package. Do I need to specify Kerberos Delegation anywhere? – DimeterTOKEN_ASSIGN_PRIMARY
this is required. As for Kerberos Delegation, I saw that mentioned as a requirement at other SO posts on the topic. – Grist