here goes the problem , Get a username , password and executable file name.
Run in the context of the specified user. The program should work on windows 2000 , 2003 and xp ...
I first thought .. easyyy .. then i said not that easyyy .. and then i realised i underestimated the problem ..
This is my thought process flow ...
Impersonate and Create Process:
Use LogonUser , get the user's token.
ImersonateLoggedOnUser
Then call CreateProcess...
Thoroughly mistaken dear ,....
CreateProcess runs the process in the security context of the primary token of the thread...
ImpersonateLoggedOnUser creates an impersonation thread.
This method will not work...
CreateProcessAsUser:
Use LogonUser , get the users token
Call CreateProcessAsUser with the token obtained from the above step.
I found the method good mainly because i need not store the password once i get the token.
I ran the program , Boooom CreateProcessAsUser failed with "The Client Does Not Hold A required Privilege"
Here is the catch ... The process that calls CreateProcessAsUser should have
"Act as part of the operating system" (SeTcbPrivilege)
"Bypass traverse checking" (SeChangeNotifyPrivilege)
"Increase quotas" (SeIncreaseQuotaPrivilege)
"Replace a process level token" (SeAssignPrimaryTokenPrivilege)
Huh ... Even the administrator does not have these privileges !!!!
I thought whats the use ?? Forget it ....
CreateProcessWithLogonW:
This does not require any special privilege.. Thanks ..
It takes username and password and does the logging internally.
The user should have log on locally permission ..
Not bad..
Now this creates a new console and there is no way ( i know of ) to prevent it ...
So i sought to hiding the new window.
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
DWORD ret = 0;
memset(&sInfo, 0, sizeof(sInfo));
memset(&pInfo, 0, sizeof(pInfo));
sInfo.cb = sizeof(sInfo);
// do not display the new window
sInfo.dwFlags = STARTF_USESHOWWINDOW ;
sInfo.wShowWindow = SW_HIDE;
Great , no window appears now :-) .. But hey how am i suposed to know what the process has done ... I need to log it somewhere ...
I was thinking about logging the output to a file..
Here is how to go about it
// create the redirection handle
// this handle is used for output
SECURITY_ATTRIBUTES secAttr;
secAttr.nLength = sizeof ( secAttr);
secAttr.lpSecurityDescriptor = NULL;
secAttr.bInheritHandle = TRUE;
HANDLE rOutput = CreateFile (
_T("LogFile.log"),
FILE_ALL_ACCESS,
FILE_SHARE_READ,
&secAttr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL // template file
);
// open always return ERROR_ALREADY_EXISTS even though function succeeds
if ( (0!= (retVal = GetLastError())) && ERROR_ALREADY_EXISTS != retVal )
{
printError ( retVal , _T("Unable To create log file") );
goto cleanup;
}
// to append to specified file
if ( INVALID_SET_FILE_POINTER == SetFilePointer ( rOutput , 0 , NULL , FILE_END ) )
{
printError ( retVal , _T("Unable To Set Log Append") );
goto cleanup;
}
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
DWORD ret = 0;
memset(&sInfo, 0, sizeof(sInfo));
memset(&pInfo, 0, sizeof(pInfo));
sInfo.cb = sizeof(sInfo);
// set the handles in startup info
// do not display the new window
sInfo.dwFlags = STARTF_USESHOWWINDOW STARTF_USESTDHANDLES ;
sInfo.wShowWindow = SW_HIDE;
sInfo.hStdOutput = rOutput;
sInfo.hStdError = rOutput;
sInfo.hStdInput = GetStdHandle( STD_INPUT_HANDLE ) ;
LPTSTR wrkDir = _wgetcwd ( NULL , 0 );
ret = CreateProcessWithLogonW(
c_usrName, // user name
c_fDom?c_DomName:NULL, // domain name
c_pswd, // user pswd
LOGON_WITH_PROFILE, // login with profile , otherwise keeps asking permission for psexec
NULL, // name of program
(LPTSTR)commandString, // command line
0, // flags
NULL,
wrkDir, // new wrking dir for child process
&sInfo, // startup info
&pInfo); // process info
Problem solved
Tuesday, April 3, 2007
Subscribe to:
Posts (Atom)