trying to spawn a process (say an exe file) with different user crendentials than that of the curren

R

ranju

I am trying to spawn a process (say an exe file) with different user
crendentials than that of the current user.

1) Called LogonUserEx() to logon the user and recieve a handle to the
token that represents the logged-on user.

2) Called ImpersonateLoggedOnUSer() to let the calling thread
impersonate the security context of logged on user.

3) Used CreateEnvironmentBlock() to get lpEnv
GetUserProfileDirectory()
LoadUserProfile()

and then called CreateProcessAsUser() with appropriate arguments.
But this fails with the error 1314 : ERROR_NO_SUCH_PRIVILEGE when the
calling thread

has admin credentails.

Also tried another option of using CreateUserWithLogonW() but it
also gives Application failed to initialize error(0xc0000142)


The Code I used is as follows



#include "stdafx.h"
#include "Windows.h"
#include "winbase.h"
#include <stdio.h>
#include "Userenv.h"
#include <windows.h>
#include <strsafe.h>



//typedef basic_string<wchar_t> wstring;
void log(char*);

BOOL logonUser(HANDLE &h);
BOOL SetPrivilege(
HANDLE , // token handle
LPCTSTR , // Privilege to enable/disable
BOOL // TRUE to enable. FALSE to disable
);
BOOL createProcessAsUser(HANDLE&);
BOOL impersonateUser(HANDLE&);
BOOL createProcessWithLogon(HANDLE&);
void ReadToEnd(HANDLE& hRead);

int main()
{
HANDLE h;
logonUser(h);
impersonateUser(h);
createProcessAsUser(h);
return 0;
}


BOOL logonUser(HANDLE &h)
{
TCHAR* username = _T("SOMEUSER");
TCHAR* password = _T("SOMEPASSWORD");
TCHAR* domain = _T("SOMEDOMAIN");
DWORD logonType = LOGON32_LOGON_NEW_CREDENTIALS;
DWORD logonProvider =LOGON32_PROVIDER_WINNT50;
PSID ppLogonSid=NULL;
PVOID ppProfileBuffer=NULL;
DWORD pdwProfileLength=0;
QUOTA_LIMITS pQuotaLimits;
ZeroMemory(&pQuotaLimits, sizeof(pQuotaLimits));

BOOL ret = FALSE;
if ( (ret = LogonUserEx(username, domain, password, logonType,
logonProvider,
&h,&ppLogonSid,&ppProfileBuffer,&pdwProfileLength,&pQuotaLimits)) ==
FALSE

)
{
char buf[1000];
sprintf(buf, "LogonUser failed with error: %ld\n",
HRESULT_FROM_WIN32(GetLastError()));
log(buf);
}
else
{
log("LogonUser succeeded\n");
}
return ret;
}

BOOL impersonateUser(HANDLE& h)
{
BOOL ret = ImpersonateLoggedOnUser(h);
if (!ret )
{
char buf[1000];
sprintf(buf, "ImpersonateLoggedOnUser failed with error: %ld
\n", HRESULT_FROM_WIN32(GetLastError()));
log(buf);
}
else
{
log("ImpersonateLoggedOnUser succeeded\n");
}
return ret;
}

BOOL createProcessAsUser(HANDLE &h)
{
TCHAR *appName = _T("c:\\windows\\notepad.exe");
TCHAR *cmdline = _T("");
LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
BOOL bInheritHandles = FALSE;
DWORD dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
void * lpEnv = NULL;
TCHAR* curDir = NULL;
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION pi;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&pi, 0, sizeof(pi));
siStartupInfo.cb = sizeof(siStartupInfo);
TCHAR* lpDesktop = _T("winsta0\\default");
siStartupInfo.lpDesktop = lpDesktop;
DWORD cchPath = 1024;
TCHAR szUserProfile[1024] = _T("");
PROFILEINFO pfi;
WCHAR szUserName[20];
_tcscpy( szUserName, _T("SOMEUSER") );
ZeroMemory( &pfi, sizeof(pfi) );
pfi.dwSize = sizeof(pfi);
pfi.lpUserName = szUserName;
pfi.dwFlags = PI_NOUI;

if (!CreateEnvironmentBlock(&lpEnv, h, TRUE))
log("CreateEnvironmentBlock failed");

if (!GetUserProfileDirectory(h, szUserProfile, &cchPath))
log("GetUserProfileDirectory failed");

// Load the profile. Since it doesn't exist, it will be created
if ( !LoadUserProfile(
h,
&pfi ) ) {
char msg[256];
sprintf(msg,"LoadUserProfile() failed. Error %d\n",
GetLastError() );
log(msg);
return -1;
}


BOOL ret = CreateProcessAsUser(h, appName, cmdline,
lpProcessAttributes, lpThreadAttributes, bInheritHandles,
dwCreationFlags, lpEnv, szUserProfile,

&siStartupInfo, &pi);
if(!ret)
{
char msg[256];
sprintf(msg,"CreateProcessAsUser() failed. Error %d\n",
GetLastError() );
log(msg);
}
else
{
log("CreateProcessAsUser succeeded\n");
}

if (!DestroyEnvironmentBlock(lpEnv)) {
log("DestroyEnvironmentBlock failed");
return FALSE;
}

if ( !UnloadUserProfile(
h,
pfi.hProfile ) ) {
char msg[256];
sprintf(msg,"UnloadUserProfile() failed. Error %d\n",
GetLastError() );
log(msg);
return -1;
}

if (!RevertToSelf()) {
log("RevertToSelf Failed");
return FALSE;
}

if (!CloseHandle(h)) {
log("CloseHandle Failed");
return FALSE;
}


return ret;

}

=================================================================

The Code for the other Option using CreateProcessWithLogonW is as
follows

Calls

LogonUser()
ImpersonateLoggedOnUser() as in the above code and then called the
following function:

BOOL createProcessWithLogon(HANDLE &hToken)
{
LPVOID lpvEnv;
DWORD cchPath = 1024;
TCHAR szUserProfile[1024] = _T("");
//TCHAR *appName = _T("D:\\Tutorial\\JoinTwoFile\\JoinTwoFile\
\ContinuousLogger\\bin\\Debug\\ContinuousLogger.exe");
TCHAR *appName = _T("d:\\pubcomps\\lmpub.exe");
TCHAR *cmdline = _T("\"c:\\windows\\notepad.exe\"");
TCHAR* username = _T("SOMEUSER");
TCHAR* password = _T("SOMEPASSWORD");
TCHAR* domain = _T("SOMEDOMAIN");
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

PROFILEINFO pfi;
WCHAR szUserName[20];
_tcscpy( szUserName, username );
ZeroMemory( &pfi, sizeof(pfi) );
pfi.dwSize = sizeof(pfi);
pfi.lpUserName = szUserName;
pfi.dwFlags = PI_NOUI;



SECURITY_ATTRIBUTES secAttr = {0};
secAttr.nLength = sizeof(secAttr);
secAttr.bInheritHandle = TRUE;
secAttr.lpSecurityDescriptor = NULL;

HANDLE fileHandle = CreateFile(_T("d:\\redirFile.txt"),
GENERIC_WRITE| GENERIC_READ, FILE_SHARE_READ| FILE_SHARE_WRITE,
&secAttr, OPEN_ALWAYS,

FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == fileHandle) {
log("CreateFile failed");
return FALSE;
}

HANDLE hPipeWr;
HANDLE hPipeRd;
if ( !CreatePipe(&hPipeRd, &hPipeWr, &secAttr, 0) ) {
log("CreatePipe failed");
return FALSE;
}

si.hStdOutput = hPipeWr;
SetHandleInformation( hPipeRd, HANDLE_FLAG_INHERIT, 0);


if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
log("CreateEnvironmentBlock failed");

DWORD dwSize = sizeof(szUserProfile)/sizeof(TCHAR);

// Load the profile. Since it doesn't exist, it will be created
if ( !LoadUserProfile(
hToken,
&pfi ) ) {
char msg[256];
sprintf(msg,"LoadUserProfile() failed. Error %d\n",
GetLastError() );
log(msg);
return -1;
}


if (!GetUserProfileDirectory(hToken, szUserProfile, &cchPath))
log("GetUserProfileDirectory failed");

//
// TO DO: change NULL to '.' to use local account database
//



if (!CreateProcessWithLogonW(username, domain, password,
LOGON_WITH_PROFILE, NULL, cmdline,
NORMAL_PRIORITY_CLASS |CREATE_UNICODE_ENVIRONMENT, lpvEnv,
szUserProfile,
&si, &pi)) {
log("CreateProcessWithLogonW failed");
return FALSE;
}
else
{
log("createProcessWithLogonW suceeded");
}


if (!DestroyEnvironmentBlock(lpvEnv)) {
log("DestroyEnvironmentBlock failed");
return FALSE;
}

CloseHandle(hPipeWr);
// WaitForSingleObject(pi.hProcess, 0xffffffff);
//DWORD exitCode = 0;
//BOOL ret = GetExitCodeProcess(pi.hProcess, &exitCode);
//if(!ret)
//{
// char buf[1000];
// sprintf(buf, "GetExitCodeProcess failed with error: %ld\n",
HRESULT_FROM_WIN32(GetLastError()));
// log(buf);
//}
//else
//{
// log("GetExitCodeProcess succeeded\n");
//}
ReadToEnd(hPipeRd);

return TRUE;

}

void ReadToEnd(HANDLE& hRead)
{
DWORD dwRead, dwWritten;
CHAR chBuf[40];

// Read output from the child process, and write to parent's STDOUT.

for (;;)
{
if( !ReadFile( hRead, chBuf, 40, &dwRead,
NULL) || dwRead == 0) break;
fwrite(chBuf, sizeof(CHAR), dwRead, stdout);
}
}
 
J

Jack Klein

I am trying to spawn a process (say an exe file) with different user
crendentials than that of the current user.

Then I'm pretty sure you're asking in the wrong place. We discuss
standard, platform independent C++ here. It knows nothing about
processes, exe files, or user credentials.

[snip]
The Code I used is as follows

#include "stdafx.h"
#include "Windows.h"

[snip]

Now I am sure, your question is about the Windows API, not about the
C++ language.

is an excellent group for
this sort of question.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top