我有一个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。
答案 0 :(得分:1)
如果您在服务中创建作业 - 默认情况下,此对象将具有WinSystemLabelSid
标签SID: S-1-16-16384
- 系统强制级别。 (我只是检查一下)所以你不仅需要设置 Dacl ,还要设置 Sacl 。例如:
ULONG cb = MAX_SID_SIZE;
PSID LowLabelSid = (PSID)alloca(MAX_SID_SIZE);
if (CreateWellKnownSid(WinLowLabelSid, 0, LowLabelSid, &cb))
{
PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
InitializeAcl(Sacl, cb, ACL_REVISION);
if (AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, LowLabelSid))
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);
SECURITY_ATTRIBUTES sa= { sizeof(sa), &sd, FALSE };
if (HANDLE hJob = CreateJobObject(&sa, L"Global\\{58BFC6DB-BE93-4cdb-919C-4C713ACB5A32}"))
{
CloseHandle(hJob);
}
}
}