2013-06-18 63 views
0

使用ANCI C,和Windows API:使用CreateProcessAsUser以恢復用戶會話1之後,用戶的路徑的不再訪問

我打電話的功能CreateProcessAsUser(,,,)從Windows 7服務應用程序(運行在會話0中)在用戶登錄到會話1時啓動應用程序。

這很好。以這種方式通過該服務在啓動後由應用程序展示的所有行爲都是正常的EXCEPT的網絡位置通常給用戶(即作爲,如果應用程序是從會話1日開始)將不再可用

訪問

所以我的問題是:

  1. 如果我有重複的登錄會話1正確,爲什麼當應用程序使用此令牌啓動,它無法訪問t時的用戶令牌o該用戶通常可以訪問的網絡位置中的數據?

  2. 除了使用CreateProcessAsUser函數之外,還有一個步驟是否缺少恢復網絡可訪問性?

注:我特別選擇CreateProcessAsUser(相對於其它選擇,如CreateProcessWithLogonW),以避免必須保持與源代碼中傳遞用戶憑據。

有什麼建議?

這裏是我使用啓動從Windows服務的應用作爲會話1用戶的源代碼:

BOOL LaunchAppIntoDifferentSession(char *AtsAppPathName) 
{ 
    PROCESS_INFORMATION pi; 
    STARTUPINFO si; 
    BOOL bResult = FALSE; 
    DWORD dwSessionId; 
    DWORD winlogonPid = 0; 
    HANDLE hUserToken,hUserTokenDup,hPToken,hProcess; 
    DWORD dwCreationFlags; 

    // Log the client on to the local computer. 
    dwSessionId = WTSGetActiveConsoleSessionId(); 

    // Find the winlogon process 
    PROCESSENTRY32 procEntry; 

    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    if (hSnap == INVALID_HANDLE_VALUE) 
    { 
    return 1 ; 
    } 

    procEntry.dwSize = sizeof(PROCESSENTRY32); 

    if (!Process32First(hSnap, &procEntry)) 
    { 
    CloseHandle(hSnap); 
    return 1 ; 
    } 

    do 
    { 
     if (stricmp(procEntry.szExeFile, "winlogon.exe") == 0) 
     { 
     // found a winlogon process...make sure it's running in the console session 
     DWORD winlogonSessId = 0; 
      if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId) 
      { 
      winlogonPid = procEntry.th32ProcessID; 
      break; 
      } 
     } 

    } while (Process32Next(hSnap, &procEntry)); 

    WTSQueryUserToken(dwSessionId,&hUserToken); 
    dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE; 
    ZeroMemory(&si, sizeof(STARTUPINFO)); 
    si.cb= sizeof(STARTUPINFO); 
    si.lpDesktop = "winsta0\\default"; 
    ZeroMemory(&pi, sizeof(pi)); 
    TOKEN_PRIVILEGES tp; 
    LUID luid; 
    hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid); 

    if(!OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY 
           |TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID 
           |TOKEN_READ|TOKEN_WRITE,&hPToken)) 
    { 
    sprintf(gTempBuf, "Process token open Error: %u",GetLastError()); 
    if(LOG_ERR==1) WriteToLog("gTempBuf"); 

    } 

    if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid)) 
    { 
    sprintf(gTempBuf, "Lookup Privilege value Error: %u",GetLastError()); 
    if(LOG_ERR==1) WriteToLog("gTempBuf"); 
    } 
    tp.PrivilegeCount =1; 
    tp.Privileges[0].Luid =luid; 
    tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED; 
    if(!DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityImpersonation,TokenPrimary,&hUserTokenDup)) 
    { 
    sprintf(gTempBuf, "DuplicateTokenEx return Error: %u",GetLastError()); 
    if(LOG_ERR==1) WriteToLog("gTempBuf"); 
    } 

    //Adjust Token privilege 
    SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD)); 

    if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL)) 
    { 
    sprintf(gTempBuf, "Adjust Privilege value Error: %u",GetLastError()); 
    if(LOG_ERR==1) WriteToLog("gTempBuf"); 
    } 

    if (GetLastError()== ERROR_NOT_ALL_ASSIGNED) 
    { 
    sprintf(gTempBuf, "Token does not have the privilege"); 
    if(LOG_ERR==1) WriteToLog("gTempBuf"); 
    } 

    LPVOID pEnv =NULL; 

    if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE)) 
    { 
    dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT; 
    } 
    else 
    pEnv=NULL; 

    // Launch the process in the client's logon session. 
    bResult = CreateProcessAsUser(
     hUserTokenDup, // client's access token 
     AtsAppPathName, // file to execute 
     NULL,    // command line 
     NULL,    // pointer to process SECURITY_ATTRIBUTES 
     NULL,    // pointer to thread SECURITY_ATTRIBUTES 
     FALSE,   // handles are not inheritable 
     dwCreationFlags, // creation flags 
     pEnv,    // pointer to new environment block 
     NULL,    // name of current directory 
     &si,    // pointer to STARTUPINFO structure 
     &pi    // receives information about new process 
    ); 
    // End impersonation of client. 

    //Perform All the Close Handles task 
    CloseHandle(hProcess); 
    CloseHandle(hUserToken); 
    CloseHandle(hUserTokenDup); 
    CloseHandle(hPToken); 
    CloseHandle(hSnap); 

    //return iResultOfCreateProcessAsUser; 
    return 0; 
} 

回答

0

是不是訪問使用映射驅動器,這些網絡位置?

Mapped drives are stored with a login session。由於用戶的配置文件未加載,因此他們無法訪問其「」映射驅動器「」。

您可以改用完整的UNC路徑。

0

問題是您正在獲取管理(提升)令牌的副本。這可能是故意的,因爲您啓用了調試權限。不幸的是,用戶提升的令牌與被過濾的令牌不在同一個登錄會話中,因此沒有任何用戶的映射驅動器。

更多信息,包括各種解決方法,可以在MSDN文章"Copying files from a mapped drive to a local directory fails with error 「Location is not available」 if UAC is enabled"中找到。通常最簡單的解決方案是使用UNC路徑或根據需要重新映射驅動器。

相關問題