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

Discussion in 'C++' started by ranju, May 17, 2007.

  1. ranju

    ranju Guest

    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);
    }
    }
     
    ranju, May 17, 2007
    #1
    1. Advertising

  2. ranju

    Jack Klein Guest

    On 17 May 2007 05:32:55 -0700, ranju <>
    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
     
    Jack Klein, May 18, 2007
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Derek Basch
    Replies:
    2
    Views:
    1,316
    Donn Cave
    Jan 21, 2005
  2. sanket
    Replies:
    3
    Views:
    685
    Gabriel Genellina
    Jul 3, 2009
  3. Ed Hames
    Replies:
    0
    Views:
    389
    Ed Hames
    Apr 16, 2008
  4. Edgardo Hames
    Replies:
    1
    Views:
    368
    Ed Hames
    May 6, 2008
  5. Victor Hooi
    Replies:
    1
    Views:
    140
    Nobody
    Feb 10, 2013
Loading...

Share This Page