设置服务访问规则

Set Service Access Rules

本文关键字:规则 访问 服务 设置      更新时间:2023-10-16

我希望能够执行sc sdset $serviceName $accessString以允许特定用户停止和启动服务,另请参阅此问题。但是我希望在没有命令行的情况下使用c ++来代替Windows API。

我已经得到了一个安全描述符和安全信息。我现在失败的地方是将此新规则添加到服务中。我找到了这个资源,但我不清楚如何将我的安全描述符转换为与 SetEntriesInAcl(( 一起使用的EXPLICIT_ACCESS结构。

这里的主要问题 - 如何决定 - 哪个帐户 (SID( 必须具有权限。 如果需要允许NetworkService启动/停止/暂停本身 - 它需要SERVICE_STARTSERVICE_STOPSERVICE_PAUSE_CONTINUE- 所以实际上GENERIC_EXECUTE如果查看服务安全性和访问权限

例如,我们可以设计下一个DACL

  • 面向本地系统和 管理员GENERIC_ALL
  • GENERIC_READ
  • 网络服务GENERIC_READ | GENERIC_EXECUTE

--

#include <sddl.h>
ULONG afe(PCWSTR lpServiceName)
{
ULONG err = 0;
if (SC_HANDLE hSCManager = OpenSCManagerW(0, 0, 0))
{
if (SC_HANDLE hService = OpenService(hSCManager, lpServiceName, WRITE_DAC))
{
PSECURITY_DESCRIPTOR SecurityDescriptor;
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
L"D:(A;;GA;;;SY)" // SDDL_LOCAL_SYSTEM -> SDDL_GENERIC_ALL
L"(A;;GA;;;BA)" // SDDL_BUILTIN_ADMINISTRATORS -> SDDL_GENERIC_ALL
L"(A;;GR;;;WD)" // SDDL_EVERYONE -> SDDL_GENERIC_READ
L"(A;;GRGX;;;NS)", // SDDL_NETWORK_SERVICE -> SDDL_GENERIC_READ|SDDL_GENERIC_EXECUTE
SDDL_REVISION_1, &SecurityDescriptor, 0))
{
if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, SecurityDescriptor))
{
err = GetLastError();
}
LocalFree(SecurityDescriptor);
}
else
{
err = GetLastError(); 
}
CloseServiceHandle(hService);
}
else
{
err = GetLastError();
}
CloseServiceHandle(hSCManager);
}
else
{
err = GetLastError();
}
return err;
}