hol*_*olt 8 opengl windows-services createprocessasuser session-0-isolation windows-server-2008
我有一个传统的Windows服务器服务和(衍生)应用程序在XP-64和W2K3中工作正常,但在W2K8上失败.我相信这是因为新的" Session 0隔离 "功能.
因此,我正在寻找代码示例/安全设置mojo,它允许您从Windows 2008 Server的Windows服务创建一个新进程,以便我可以恢复(并可能超过)以前的行为.我需要一个解决方案:
由于会话0不再是用户会话,因此在会话0中运行的服务无法访问视频驱动程序.这意味着服务渲染图形的任何尝试都会失败.查询会话0中的显示分辨率和颜色深度报告系统的正确结果,最高为1920x1200,每像素32位.
新进程获得一个可用于创建Windows DC的Windows工作站/桌面(例如winsta0/default).我在这里找到了一个解决方案(在交互式会话中启动OK):在C++中启动交互式客户端进程
当用作OpenGL DescribePixelFormat枚举的基础时,Windows DC 能够找到并使用硬件加速格式(在适当配备OpenGL硬件的系统上).请注意,我们当前的解决方案在XP-64和W2K3上运行正常,除非终端服务会话正在运行(VNC工作正常.)一个允许进程工作的解决方案(即使在终端服务会话打开时使用OpenGL硬件加速运行)也会很奇妙,尽管不是必需的.
我目前只停留在第1项,虽然有一些类似的帖子讨论这个(像这样,这个 - 它们不是合适的解决方案,因为无法保证用户会话已经登录"拿"了来自的会话ID,我也没有从LocalSystem帐户运行(我从服务的域帐户运行,我可以在合理范围内调整权限,尽管我更愿意不必将优先级升级到包括SeTcbPrivileges.)
例如 - 这是我认为应该工作的存根,但总是在SetTokenInformation调用上返回错误1314(即使AdjustTokenPrivileges没有返回任何错误)我也使用了一些涉及"LogonUser"的替代策略(而不是打开现有的进程令牌),但我似乎无法换出会话ID.
我也怀疑在所有情况下都使用WTSActiveConsoleSessionId(例如,如果没有交互式用户登录) - 尽管在没有登录会话的情况下运行的服务的快速测试似乎返回了合理的会话值(1).
我已经删除了错误处理以便于阅读(仍然有点凌乱 - 道歉)
//Also tried using LogonUser(..) here
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_SESSIONID
| TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE, &hToken)
GetTokenInformation( hToken, TokenSessionId, &logonSessionId, sizeof(DWORD), &dwTokenLength )
DWORD consoleSessionId = WTSGetActiveConsoleSessionId();
/* Can't use this - requires very elevated privileges (LOCAL only, SeTcbPrivileges as well)
if( !WTSQueryUserToken(consoleSessionId, &hToken))
...
*/
DuplicateTokenEx(hToken, (TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE), NULL, SecurityIdentification, TokenPrimary, &hDupToken))
// Look up the LUID for the TCB Name privilege.
LookupPrivilegeValue(NULL, SE_TCB_NAME, &tp.Privileges[0].Luid))
// Enable the TCB Name privilege in the token.
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hDupToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, 0))
{
DisplayError("AdjustTokenPrivileges");
...
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
DEBUG( "Token does not have the necessary privilege.\n");
} else {
DEBUG( "No error reported from AdjustTokenPrivileges!\n");
} // Never errors here
DEBUG(LM_INFO, "Attempting setting of sessionId to: %d\n", consoleSessionId );
if (!SetTokenInformation(hDupToken, TokenSessionId, &consoleSessionId, sizeof(DWORD)))
*** ALWAYS FAILS WITH 1314 HERE ***
Run Code Online (Sandbox Code Playgroud)
在SetTokenInformation调用之前,所有调试输出看起来都很好 - 我看到会话0是我当前的进程会话,在我的情况下,它正在尝试设置会话1(WTSGetActiveConsoleSessionId的结果).(注意我是通过VNC而不是RDC登录到W2K8盒子)
所以 - 一个问题:
任何帮助非常感谢 - 谢谢!
对于有兴趣解决此问题的任何人:
我在LogonSDK团队的MS支持中讨论了这个问题.似乎不可能以编程方式完全模仿交互式用户,这样你就可以获得一个物理控制台和相关的GDI结构,而且我们基本上"幸运"它直到现在才有效.他们确实确认会话0隔离是回归的根本原因.
他们的建议是启用自动登录到交互式会话,并重构服务以与交互式会话中的新客户端组件通信.为了解决这方面的安全缺点,他们建议实施shell替换以在登录时将服务器置于"Kiosk"模式(例如,没有适当凭据的资源管理器访问等)
从好的方面来说,这应该解决我们遇到的终端服务会话遇到的问题,这些问题会导致硬件加速.
我将向MS提交一个请求,考虑在未来的版本中使用"代理用户会话"支持的这种"渲染农场"用例,这样服务器就可以产生硬件加速的进程而不需要现有客户端用户进程的安全性损害在控制台登录.