设置服务访问规则

时间:2018-05-30 08:44:03

标签: c++ windows winapi windows-services

我希望能够sc sdset $serviceName $accessString允许特定用户停止和启动服务,另请参阅this question。但我希望不使用命令行和使用Windows API的c ++来实现。

我已经有了SecurityDescriptorSecurityInfo。我现在失败的地方是将这条新规则添加到服务中。我找到了this resource,但我不清楚如何将SecurityDescriptor转换为与SetEntriesInAcl()一起使用的EXPLICIT_ACCESS结构。

1 个答案:

答案 0 :(得分:0)

这里的主要问题 - 如何决定 - 哪个帐户(SID)必须拥有权利。如果想要允许NetworkService开始/停止/暂停 - 它需要SERVICE_STARTSERVICE_STOPSERVICE_PAUSE_CONTINUE - 事实上GENERIC_EXECUTE如果查看Service Security and Access Rights

我们可以设计下一个 DACL

  • GENERIC_ALL LocalSystem 管理员
  • GENERIC_READ Everyone
  • GENERIC_READ | GENERIC_EXECUTE NetworkService

-

#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;
}