我正在使用WinHTTP Server API 2.0,我正在尝试执行以下步骤(https://msdn.microsoft.com/en-us/library/windows/desktop/aa364672(v=vs.85).aspx):
HttpSetRequestQueueProperty
功能配置请求队列。HttpQueryRequestQueueProperty
函数查询请求队列配置参数。HttpWaitForDemandStart
以延迟工作进程的实例化,直到第一个请求到达请求队列。任何人都可以为步骤提供帮助:
设置ACL,指定允许在请求队列上接收I / O的工作进程
我不确定这是什么意思(我从未使用过ACL API),但我想我需要在某个时间点调用::GetNamedSecurityInfo()
来修改它:
if (NO_ERROR == ::HttpCreateRequestQueue(HTTPAPI_VERSION_2,
requestQueueName,
0,
HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER,
&m_requestQueue))
// setup queue
if (NO_ERROR == ::HttpCreateUrlGroup(m_sessionId, &m_groupId, 0))
{
HTTP_BINDING_INFO bindingInfo{ 1, m_requestQueue };
if (NO_ERROR == ::HttpSetUrlGroupProperty(m_groupId,
HttpServerBindingProperty,
&bindingInfo,
sizeof(bindingInfo)))
{
m_localUrl = (NO_ERROR == (::HttpAddUrlToUrlGroup(m_groupId, localUrl.c_str(), 0, 0)));
m_globalUrl = (NO_ERROR == (::HttpAddUrlToUrlGroup(m_groupId, globalUrl.c_str(), 0, 0)));
PACL pacl = NULL;
PSECURITY_DESCRIPTOR securityDescriptor = NULL;
DWORD result = ::GetNamedSecurityInfo(requestQueueName,
SE_KERNEL_OBJECT,
SACL_SECURITY_INFORMATION,
NULL,
NULL,
NULL,
&pacl,
&securityDescriptor);
// it (result != 0) fails when passing various SE_OBJECT_TYPEs
}
}
答案 0 :(得分:1)
设置ACL,指定允许的工作进程 在请求队列上接收I / O
寻找其他一个注释:
使用 HttpCreateRequestQueue 创建命名请求队列 功能。创建请求队列时,应用程序指定 pSecurityAttribute 参数中的ACL。 ACL,只能 在创建请求队列时设置,允许工作进程 打开请求队列,接收请求并发送响应。通过 默认情况下,不允许进程打开请求队列 已获得ACL的许可。应用程序不需要 用于创建请求队列的管理权限。
所以你可以(但不是必须,这是可选的)创建并初始化一些安全描述符并通过In_opt_ PSECURITY_ATTRIBUTES pSecurityAttributes
将其传递给HttpCreateRequestQueue函数 - 这里绝对没什么特别的,任何内核中使用的SECURITY_ATTRIBUTES
对象创建api。比如说CreateEvent
(这里是第一个参数)。
如何初始化它,为谁授予访问权限 - 这已经是开放式问题 - 边界案例 - 允许所有人:
ULONG cb = MAX_SID_SIZE;
PSID UntrustedLabelSid = (PSID)alloca(MAX_SID_SIZE);
if (CreateWellKnownSid(WinUntrustedLabelSid, 0, UntrustedLabelSid, &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, UntrustedLabelSid))
{
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 (NO_ERROR == HttpCreateRequestQueue(HTTPAPI_VERSION_2,
requestQueueName,
&sa,
HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER,
&m_requestQueue))
{
}
}
}
作为替代方案,我们可以使用string-format security descriptor,然后将其转换为ConvertStringSecurityDescriptorToSecurityDescriptor
,例如:
SECURITY_ATTRIBUTES sa = { sizeof(sa), 0, FALSE };
ULONG dwError;
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
L"D:NO_ACCESS_CONTROLS:(ML;;;;;LW)",
SDDL_REVISION_1, &sa.lpSecurityDescriptor, 0))
{
dwError = HttpCreateRequestQueue(HTTPAPI_VERSION_2,
requestQueueName,
&sa,
HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER,
&m_requestQueue);
LocalFree(sa.lpSecurityDescriptor);
}
else
{
dwError = GetLastError();
}
此处"D:NO_ACCESS_CONTROLS:(ML;;;;;LW)"
允许对所有人进行访问 - NO_ACCESS_CONTROLS
和LW
- LowLabel。 (不像第一个例子那样不受信任)
另一个变体(仅举例)使用say next string:
"D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGX;;;BU)(A;;GRGX;;;AC)S:(ML;;;;;LW)"
此处我们允许GENERIC_ALL
(GA
)系统(SY
)和管理员(BA
)和用户(GENERIC_READ|GENERIC_EXECUTE
)和所有应用程序包<{1>} BU