【发布时间】:2017-02-01 16:42:20
【问题描述】:
我有一个 Windows 服务,它创建一个 JobObject,只要机器打开,我就需要保持活动状态 - 目标是管理一些可以随时使用此 JobObject 终止/启动的用户会话进程。我在服务中创建它以确保进程在启动时运行,并且它不能被普通用户杀死。
但是,我似乎无法从用户会话中打开此 JobObject 的句柄,我总是收到拒绝访问 (5) 错误,尽管使用 NULL DACL 创建它。
我在这里找到了一个有点相关的问题:Open an Event object created by my service from my application,但对我来说,即使使用 NULL DACL,在请求 JOB_OBJECT_ASSIGN_PROCESS 权限时,我也会被拒绝访问(例如请求 SYNCHRONIZE 工作)。
服务代码:
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(psd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES secAttr= {0};
secAttr.nLength = sizeof(secAttr);
secAttr.bInheritHandle = false;
secAttr.lpSecurityDescriptor = psd;
hJobObject = CreateJobObject(&secAttr, SCL_JOBOBJECTNAME);
LocalFree(psd);
用户会话代码:
hJobObject = OpenJobObject(JOB_OBJECT_ASSIGN_PROCESS, FALSE, SCL_JOBOBJECTNAME);
if (hJobObject == NULL)
{
DWORD wError = GetLastError();
printf("Error: %d\n", wError); // this always pops 5
return 1;
}
有什么想法吗?作为测试,我尝试从服务中生成用户会话进程,并通过服务代码分配 JobObject,并且有效,.. 所以我相当确定它与我缺少的安全设置有关,尽管 NULL DACL .
【问题讨论】:
-
您为什么希望能够从不同的会话中打开作业对象?为什么你还需要这样做?
-
其他内核对象也可以像这样使用,我没有找到任何文档建议 JobObjects。也许有更好的方法来做到这一点,但我需要在同一个 JobObject 中保持在整个用户会话中独立启动的进程数天/数周,以确保它们永远不会超过一定的 RAM 使用量。如果我在用户会话本身中创建 JobObject,我无法确保它在第一个“托管”进程启动之前启动。服务似乎是实现此目的的工具。您对如何以不同的方式处理它有什么建议吗?
-
你是在全局命名空间中创建的吗?您不需要运行提升来访问全局命名空间中的对象吗?
-
我想你忘了在你的工作对象中设置标签,当你需要设置为
SECURITY_MANDATORY_MEDIUM_RID或低时它默认有SECURITY_MANDATORY_SYSTEM_RID -
@DavidHeffernan 是的,
#define SCL_JOBOBJECTNAME L"Global\\MyJobObject",否则我会得到预期的“未找到”(2) 错误。所以它似乎找到了它,但由于某种原因拒绝使用任何可能需要修改某些内容的访问权限进行访问。所以 JOB_OBJECT_SET_ATTRIBUTES 会失败(拒绝访问),但 JOB_OBJECT_QUERY 会给我一个句柄。