By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,660 Members | 1,953 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,660 IT Pros & Developers. It's quick & easy.

trying to spawn a process (say an exe file) with different user crendentials than that of the current user but getting 1314 error

P: n/a
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_twstring;
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.ex e");
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);
}
}

May 17 '07 #1
Share this Question
Share on Google+
1 Reply


P: n/a
On 17 May 2007 05:32:55 -0700, ranju <ra**************@gmail.com>
wrote in comp.lang.c++:
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.

news:comp.os.ms-windows.programmer.win32 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
May 18 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.