CreateProcess API的安全问题

时间:2014-02-13 09:21:39

标签: c++ winapi rsync createprocess

目标:我正在尝试将一些文件从我的客户端发送到服务器。我正在使用" rsync"用于传输数据。我正在使用CreateProcess APi并传递rsync路径和参数。

肯定案例:当我从本地驱动器发送数据时,例如" C:"是我安装Windows的地方,上面的方法正常工作并传输数据。

问题:当我尝试发送映射驱动器(共享网络驱动器)的数据时。 CreateProcess完成但我得到的错误是rsync无法找到该文件。 相同的rsync命令,当我在命令提示符下运行时,所有文件都成功传输,没有任何错误,但在使用CreateProcess传输文件时失败。

代码

    int CreateRsyncProcess(const wchar_t * ptrCommand)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        SECURITY_ATTRIBUTES sap,sat,sao;
        HANDLE out;
        DWORD pwExit;

        //init the STARTUPINFO struct
        memset(&si,0,sizeof(si));
        si.cb=sizeof(si);

        wstring cmd = L"";
        cmd.append(ptrCommand);


        //proc sec attributes
        sap.nLength=sizeof(SECURITY_ATTRIBUTES);
        sap.lpSecurityDescriptor= NULL;
        sap.bInheritHandle=1;

        //thread sec attributes
        sat.nLength=sizeof(SECURITY_ATTRIBUTES);
        sat.lpSecurityDescriptor= NULL;
        sat.bInheritHandle=1;


        //create the proc
        if(!CreateProcess(NULL,(LPWSTR)cmd.c_str(),&sap,&sat,1,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
        {
            DWORD err = GetLastError();
            if(out != INVALID_HANDLE_VALUE)
                CloseHandle(out);

            return 1;
        }

        //wait till the proc ends

        WaitForSingleObject(pi.hProcess,INFINITE);

        GetExitCodeProcess(pi.hProcess,&pwExit);

        //close all
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        if(out != INVALID_HANDLE_VALUE)
            CloseHandle(out);
        TerminateProcess(pi.hProcess,0);


        return pwExit;

}

Rsync Cmd :         " C:\ Program Files \ cwRsync \ bin \ rsync.exe" -cvriHPDkREL --no-implied-dirs --stats -e'" C:\ Program Files \ cwRsync \ bin \ ssh" -o StrictHostKeyChecking = no -i" C:\ Program Files \ cwRsync \ bin \ rsync-key"' " / cygdrive / Z / 64位" user@server.com:~ / 6a90c592-2b3b-4088-8942-2106776c863a /

是否因为某些与安全相关的问题或权限问题而发生了CreateProcess或其他一些事情? 请帮忙,因为我被困在这上面。

由于

编辑::这在正常流程中运行良好,但是当我在服务中运行它时会失败。所以基本上现在的问题是服务没有访问网络共享。有没有解决方法呢?

3 个答案:

答案 0 :(得分:4)

映射驱动器是每个会话 - 隔离会话中的服务无法访问用户会话中的映射驱动器。您需要在服务会话中映射驱动器,或使用UNC路径(而不是映射的驱动器号),并让服务用户访问共享。

答案 1 :(得分:1)

由于您显然正在运行服务,因此您可能需要加载环境才能访问映射文件夹。

像这样。

    DWORD dwIdCurrentSession = 0xFFFFFFFF;

    WTS_SESSION_INFO* pSessionInfo = NULL;          
    DWORD dwSessionsCount = 0;
    if(WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwSessionsCount))
    {   
        for(int i=0; i<(int)dwSessionsCount; i++)
        {
            WTS_SESSION_INFO &si = pSessionInfo[i];
            if(si.State == WTSActive)
            {                                                       
                dwIdCurrentSession = si.SessionId;
                break;
            }
        }

        WTSFreeMemory(pSessionInfo);    
    }

    if(dwIdCurrentSession != 0xFFFFFFFF)
    {
        HANDLE hLoggedOnUserToken = NULL;           
        // Get Session User Token   
        if(WTSQueryUserToken(dwIdCurrentSession, &hLoggedOnUserToken))                          
        {                   
            LPVOID lpEnviroment = NULL;
            if(CreateEnvironmentBlock(&lpEnviroment, hLoggedOnUserToken, false))
            {               
                STARTUPINFO si;
                PROCESS_INFORMATION pi;

                ZeroMemory( &si, sizeof(si) );
                si.cb = sizeof(si);
                ZeroMemory( &pi, sizeof(pi) );

                // Create Process
                if(CreateProcessAsUser(hLoggedOnUserToken,
                    NULL,
                    (LPWSTR)cmd.c_str(),
                    NULL,
                    NULL,
                    FALSE,
                    CREATE_UNICODE_ENVIRONMENT,
                    lpEnviroment,
                    NULL,
                    &si,
                    &pi )
                ) 
                {   
                    // Wait for finish......

                    // Clean up
                    CloseHandle( pi.hProcess );
                    CloseHandle( pi.hThread );                                  
                }

                DestroyEnvironmentBlock(lpEnviroment);
            }

            CloseHandle(hLoggedOnUserToken);    
        }
    }

答案 2 :(得分:0)

您使用的是哪种特定操作系统,例如Windows 7 32位,Windows 7 64位等?此外,您是否启用了UAC?如果您确实启用了UAC,则以管理员身份运行应用程序时问题是否会消失。

根据您对这些问题的回答,我可能会提供进一步的帮助。我不得不做一些研究。

目前,如果UAC确实是您的问题,我唯一的建议是您调查使用ShellExecuteEx的可能性。在Riding the Vista UAC elevator, up and down找到的RunElevated函数可能对您有用。为方便起见,我将在此处包含该功能。

BOOL RunElevated(
  HWND hwnd, LPCTSTR pszPath,
  LPCTSTR pszParameters = NULL, LPCTSTR pszDirectory = NULL)
{
  SHELLEXECUTEINFO shex;
  memset( &shex, 0, sizeof( shex) );

  shex.cbSize = sizeof(SHELLEXECUTEINFO);
  shex.fMask = 0;
  shex.hwnd = hwnd;
  shex.lpVerb = _T("runas");
  shex.lpFile = pszPath;
  shex.lpParameters = pszParameters;
  shex.lpDirectory = pszDirectory;
  shex.nShow = SW_NORMAL;
  return ::ShellExecuteEx(&shex);
}

如果不能使用ShellExecuteEx,您还可以尝试Vista UAC: The Definitive Guide处的CreateProcessElevated函数。

相关问题