EDN Admin
Well-known member
I have a requirement to invoke a process(sample.bat) from service using CreateProcessAsUser in Windows 7 machine.
Here are the steps I have followed:
1. Used the LogononUser API to get the token. The credentials provided here is other than logged on user.<br/>
2. Get the Active SessionId.<br/>
3. Duplicate the token.<br/>
4. Set the token information by specifying the sessionid.<br/>
5. Set the previlage.<br/>
6. Call CreateProcessAsUser to invoke the batch from service.
Results:<br/>
--------
The batch file is invoked but the contents of file is not shown, I mean I can able to see the batch file invoked but with black screen with no contents seen. The GUI is not drawn properly.
Here is the code snippet:
STARTUPINFO StartupInfo = {0};<br/>
PROCESS_INFORMATION ProcessInfo;<br/>
HDESK hDesk;<br/>
HWINSTA hwinsta;<br/>
HWINSTA hwinstaold;<br/>
PSID psid;<br/>
PSID bpsid;<br/>
DWORD status;<br/>
int rc = 0;<br/>
DWORD dwRet = 0;<br/>
BOOL bRet = FALSE;<br/>
TOKEN_PRIVILEGES tp;<br/>
DWORD dwCreationFlags;<br/>
LUID luid;
HANDLE hTokenthis = NULL, hUserTokenDup = NULL;
<br/>
hToken = GetToken("testuser","tesa123");
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));<br/>
ProcessInfo.hProcess=NULL;<br/>
ProcessInfo.hThread=NULL;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));<br/>
<br/>
StartupInfo.cb = sizeof(STARTUPINFO);<br/>
StartupInfo.lpTitle = pszCmdTitle;<br/>
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;<br/>
StartupInfo.wShowWindow = SW_MINIMIZE;<br/>
//StartupInfo.lpDesktop=NULL;<br/>
StartupInfo.lpDesktop = "winsta0\default";
rc=0;
hwinsta = hwinstaold = NULL;<br/>
hDesk = NULL;<br/>
<br/>
DWORD dwSessionid = WTSGetActiveConsoleSessionId();<br/>
dwRet = GetLastError();
<br/>
if (!LookupPrivilegeValue(NULL,SE_TCB_NAME/*SE_DEBUG_NAME*/,&luid))<br/>
{<br/>
printf("Lookup Privilege value Error: %un",GetLastError());<br/>
}<br/>
tp.PrivilegeCount =1;<br/>
tp.Privileges[0].Luid =luid;<br/>
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
bRet = false;
bRet = DuplicateTokenEx(htoken, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenthis);<br/>
dwRet = GetLastError();<br/>
<br/>
bRet = false;<br/>
<br/>
bRet = SetTokenInformation(hTokenthis,TokenSessionId,&dwSessionid,sizeof(DWORD));
if (!AdjustTokenPrivileges(hTokenthis,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL))<br/>
{<br/>
int abc =GetLastError();<br/>
printf("Adjust Privilege value Error: %un",GetLastError());<br/>
<br/>
}
if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)<br/>
{<br/>
printf("Token does not have the provilegen");<br/>
}
LPVOID pEnv =NULL;
dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS;
if(CreateEnvironmentBlock(&pEnv,hTokenthis,TRUE))<br/>
{<br/>
dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;<br/>
}<br/>
else<br/>
pEnv=NULL;
if (hTokenthis)<br/>
{<br/>
<br/>
printf("calling CreateProcessAsUser; token: %lun", hTokenthis);<br/>
if (!CreateProcessAsUser(hTokenthis,<br/>
NULL,<br/>
pszCmdTitle,<br/>
NULL,<br/>
NULL,<br/>
FALSE,<br/>
dwCreationFlags,
<br/>
<br/>
NULL,<br/>
NULL,<br/>
&StartupInfo,<br/>
&ProcessInfo))<br/>
{<br/>
rc=GetLastError();<br/>
printf("CreateProcessAsUser failed rc=%lun", rc);<br/>
}<br/>
}
HANDLE GetToken(LPCTSTR pszUsername, LPCTSTR pszPassword /*= NULL*/)<br/>
{
HANDLE hToken;<br/>
HANDLE hTokenthis = NULL;<br/>
LPHANDLE hDupToken = NULL;<br/>
HDESK hdesk;<br/>
HWINSTA hwinsta;<br/>
PROCESS_INFORMATION pi;<br/>
PSID psid;<br/>
STARTUPINFO si = {0};<br/>
DWORD dwExitCode = RTN_ERROR, dwRes = 0;<br/>
CString strUsername = pszUsername;<br/>
CString strUser, strDomain;<br/>
DWORD dwErr = 0;<br/>
HWINSTA hwinstaold;<br/>
BOOL bRet = false;<br/>
BOOL bAdmin = true;
<br/>
const char* pszUser = NULL;<br/>
const char* pszDomain = NULL;
SECURITY_ATTRIBUTES sa;<br/>
sa.bInheritHandle = false;<br/>
sa.nLength = sizeof(SECURITY_ATTRIBUTES);<br/>
sa.lpSecurityDescriptor = 0;
DWORD dwCreationFlags = CREATE_NEW_CONSOLE;
if ( pszUsername )<br/>
{
// check to see if we have domainuser<br/>
if( -1 != strUsername.Find( \ ) )<br/>
{<br/>
strDomain = strUsername.Left( strUsername.Find( \ ) );<br/>
pszDomain = strDomain;
strUser = strUsername.Mid( strUsername.Find( \ ) + 1 );<br/>
pszUser = strUser;<br/>
}<br/>
else<br/>
pszUser = pszUsername;
//<br/>
// obtain an access token for the user fester<br/>
//<br/>
if ( !LogonUser(<br/>
( char * )pszUser,<br/>
( char * )pszDomain,<br/>
( char * )pszPassword,<br/>
LOGON32_LOGON_INTERACTIVE,<br/>
LOGON32_PROVIDER_DEFAULT,<br/>
&hToken<br/>
) )<br/>
{<br/>
DWORD dwLastError = GetLastError();<br/>
return NULL;<br/>
}<br/>
return hToken;<br/>
}
return NULL; <br/>
}
View the full article
Here are the steps I have followed:
1. Used the LogononUser API to get the token. The credentials provided here is other than logged on user.<br/>
2. Get the Active SessionId.<br/>
3. Duplicate the token.<br/>
4. Set the token information by specifying the sessionid.<br/>
5. Set the previlage.<br/>
6. Call CreateProcessAsUser to invoke the batch from service.
Results:<br/>
--------
The batch file is invoked but the contents of file is not shown, I mean I can able to see the batch file invoked but with black screen with no contents seen. The GUI is not drawn properly.
Here is the code snippet:
STARTUPINFO StartupInfo = {0};<br/>
PROCESS_INFORMATION ProcessInfo;<br/>
HDESK hDesk;<br/>
HWINSTA hwinsta;<br/>
HWINSTA hwinstaold;<br/>
PSID psid;<br/>
PSID bpsid;<br/>
DWORD status;<br/>
int rc = 0;<br/>
DWORD dwRet = 0;<br/>
BOOL bRet = FALSE;<br/>
TOKEN_PRIVILEGES tp;<br/>
DWORD dwCreationFlags;<br/>
LUID luid;
HANDLE hTokenthis = NULL, hUserTokenDup = NULL;
<br/>
hToken = GetToken("testuser","tesa123");
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));<br/>
ProcessInfo.hProcess=NULL;<br/>
ProcessInfo.hThread=NULL;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));<br/>
<br/>
StartupInfo.cb = sizeof(STARTUPINFO);<br/>
StartupInfo.lpTitle = pszCmdTitle;<br/>
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;<br/>
StartupInfo.wShowWindow = SW_MINIMIZE;<br/>
//StartupInfo.lpDesktop=NULL;<br/>
StartupInfo.lpDesktop = "winsta0\default";
rc=0;
hwinsta = hwinstaold = NULL;<br/>
hDesk = NULL;<br/>
<br/>
DWORD dwSessionid = WTSGetActiveConsoleSessionId();<br/>
dwRet = GetLastError();
<br/>
if (!LookupPrivilegeValue(NULL,SE_TCB_NAME/*SE_DEBUG_NAME*/,&luid))<br/>
{<br/>
printf("Lookup Privilege value Error: %un",GetLastError());<br/>
}<br/>
tp.PrivilegeCount =1;<br/>
tp.Privileges[0].Luid =luid;<br/>
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
bRet = false;
bRet = DuplicateTokenEx(htoken, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenthis);<br/>
dwRet = GetLastError();<br/>
<br/>
bRet = false;<br/>
<br/>
bRet = SetTokenInformation(hTokenthis,TokenSessionId,&dwSessionid,sizeof(DWORD));
if (!AdjustTokenPrivileges(hTokenthis,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL))<br/>
{<br/>
int abc =GetLastError();<br/>
printf("Adjust Privilege value Error: %un",GetLastError());<br/>
<br/>
}
if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)<br/>
{<br/>
printf("Token does not have the provilegen");<br/>
}
LPVOID pEnv =NULL;
dwCreationFlags = CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS;
if(CreateEnvironmentBlock(&pEnv,hTokenthis,TRUE))<br/>
{<br/>
dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;<br/>
}<br/>
else<br/>
pEnv=NULL;
if (hTokenthis)<br/>
{<br/>
<br/>
printf("calling CreateProcessAsUser; token: %lun", hTokenthis);<br/>
if (!CreateProcessAsUser(hTokenthis,<br/>
NULL,<br/>
pszCmdTitle,<br/>
NULL,<br/>
NULL,<br/>
FALSE,<br/>
dwCreationFlags,
<br/>
<br/>
NULL,<br/>
NULL,<br/>
&StartupInfo,<br/>
&ProcessInfo))<br/>
{<br/>
rc=GetLastError();<br/>
printf("CreateProcessAsUser failed rc=%lun", rc);<br/>
}<br/>
}
HANDLE GetToken(LPCTSTR pszUsername, LPCTSTR pszPassword /*= NULL*/)<br/>
{
HANDLE hToken;<br/>
HANDLE hTokenthis = NULL;<br/>
LPHANDLE hDupToken = NULL;<br/>
HDESK hdesk;<br/>
HWINSTA hwinsta;<br/>
PROCESS_INFORMATION pi;<br/>
PSID psid;<br/>
STARTUPINFO si = {0};<br/>
DWORD dwExitCode = RTN_ERROR, dwRes = 0;<br/>
CString strUsername = pszUsername;<br/>
CString strUser, strDomain;<br/>
DWORD dwErr = 0;<br/>
HWINSTA hwinstaold;<br/>
BOOL bRet = false;<br/>
BOOL bAdmin = true;
<br/>
const char* pszUser = NULL;<br/>
const char* pszDomain = NULL;
SECURITY_ATTRIBUTES sa;<br/>
sa.bInheritHandle = false;<br/>
sa.nLength = sizeof(SECURITY_ATTRIBUTES);<br/>
sa.lpSecurityDescriptor = 0;
DWORD dwCreationFlags = CREATE_NEW_CONSOLE;
if ( pszUsername )<br/>
{
// check to see if we have domainuser<br/>
if( -1 != strUsername.Find( \ ) )<br/>
{<br/>
strDomain = strUsername.Left( strUsername.Find( \ ) );<br/>
pszDomain = strDomain;
strUser = strUsername.Mid( strUsername.Find( \ ) + 1 );<br/>
pszUser = strUser;<br/>
}<br/>
else<br/>
pszUser = pszUsername;
//<br/>
// obtain an access token for the user fester<br/>
//<br/>
if ( !LogonUser(<br/>
( char * )pszUser,<br/>
( char * )pszDomain,<br/>
( char * )pszPassword,<br/>
LOGON32_LOGON_INTERACTIVE,<br/>
LOGON32_PROVIDER_DEFAULT,<br/>
&hToken<br/>
) )<br/>
{<br/>
DWORD dwLastError = GetLastError();<br/>
return NULL;<br/>
}<br/>
return hToken;<br/>
}
return NULL; <br/>
}
View the full article