我需要为用户提供哪些最低权限才能检查 SQL Server 代理服务的状态?

Ash*_*ish 6 sql-server permissions sql-server-agent

我创建了一个用户并为其授予了许多权限和角色,包括SQLAgentUserRoleSQLAgentReaderRole

我的应用程序检查 SQL Server 代理的状态以查看它是否正在运行,并且每当我尝试使用我创建的用户运行我的应用程序时,它都无法识别正在运行的 SQL Server 代理

当我使用sysadmin角色中的用户做同样的事情时,它工作正常。

我们正在使用master..xp_servicecontrol检查 SQL 代理服务的状态,我已经为用户提供了

GRANT EXECUTE ON SYS.XP_PROP_OLEDB_PROVIDER TO User;
Run Code Online (Sandbox Code Playgroud)

它仍然不起作用。有什么帮助吗?

Sol*_*zky 7

我需要为用户提供哪些最低权限才能检查 SQL Server 代理服务的状态?

没有任何 :-)

从 SQL Server 2005 开始,Microsoft 提供了一种通过“代理”推断权限的机制。权限的代理是登录(对于服务器级别权限)或用户(对于数据库级别权限)。在任何一种情况下,主体(服务器或数据库)都是从非对称密钥或证书创建的,被授予适当的权限,然后通过使用ADD SIGNATURE签署一个或多个代码片段来推断权限。通过这样做,您将给予代码您授予该服务器或数据库主体的权限。因此,现在您可以创建一个存储过程或函数来执行非常具体的操作,并有效地仅授予该代码正确运行的适当权限。然后,您只需自然地处理权限,只将 EXECUTE / SELECT 权限授予那些应该被允许执行该操作的用户或角色。

在执行方面xp_servicecontrol,如果您将其授予EXECUTE用户,则该用户可以运行它以获取有关任何服务的信息,这几乎不像只允许运行它来获取有关一项特定服务的信息那样进行微调。

考虑到推断权限方法,我们可以创建一个登录并将其放置在sysadmin角色中,但我们甚至不需要走那么远。从 SQL Server 2008 R2 的 SP1 开始,引入了一个新的 DMV,用于显示 SQL Server 相关的 Windows/NT 服务的状态信息:sys.dm_server_services。此 DMV 需要的唯一许可是VIEW SERVER STATE. 但同样,您甚至不需要向相关用户授予此权限。你可以:

  • 创建一个函数(UDF 或多语句 TVF)或存储过程来封装此 DMV 的非常具体的用法
  • 创建证书
  • 基于该证书创建登录
  • 授予VIEW SERVER STATE该登录名
  • 在有问题的用户所在的数据库中创建相同的证书
  • 使用该证书签署函数和/或存储过程
  • 授予EXECUTE有关该函数和/或存储过程的用户

在此设置中,除了运行存储过程或函数之外,没有授予用户任何权限。虽然该VIEW SERVER STATE权限允许查看大量信息,但该权限仅用于运行存储过程或函数中的任何代码。并且只要该代码不是动态 SQL,那么就不能在狭义定义的用途之外(或在由同一证书签名的任何其他代码之外)应用该权限。

担心您可能会误操作并意外授予ALTER PROCEDURE该用户,然后他们可以放入任何需要该权限的代码?错误的!任何完全更改为已签名的对象将删除该对象的签名。因此,即使有人设法更改了该函数或存储过程,它也将不再由证书签名,因此将不再能够从基于证书的登录推断权限。即使该用户以某种方式有权向对象添加签名,如果没有用于创建证书的密码,那也无济于事。如果用户可以访问您的密码(或可能拥有密码的部署脚本),那么您的流程和标准存在严重缺陷,在这种情况下,不值得花时间和精力来完成所有这些工作,只是把那个人放在sysadmin角色中;-)。


请尝试以下操作:

最初设定:

USE [Test];
GO -------------------------------------------------------------
-- DROP PROCEDURE dbo.CheckSqlAgent
CREATE PROCEDURE dbo.CheckSqlAgent
AS
SET NOCOUNT ON;

SELECT dss.[status], dss.[status_desc]
FROM   sys.dm_server_services dss
WHERE  dss.[servicename] LIKE N'SQL Server Agent (%';

GO -------------------------------------------------------------
-- DROP FUNCTION dbo.IsSqlAgentRunning
CREATE FUNCTION dbo.IsSqlAgentRunning()
RETURNS BIT
AS
BEGIN
  DECLARE @IsRunning BIT = 0;

  IF (EXISTS(SELECT dss.*
             FROM   sys.dm_server_services dss
             WHERE  dss.[servicename] LIKE N'SQL Server Agent (%'
             AND    dss.[status] = 4 -- Running
            )
     )
  BEGIN
    SET @IsRunning = 1;
  END;

  RETURN @IsRunning;
END;

GO -------------------------------------------------------------

CREATE USER [MrNoLogin] WITHOUT LOGIN;
GRANT EXECUTE ON dbo.CheckSqlAgent TO [MrNoLogin];
GRANT EXECUTE ON dbo.IsSqlAgentRunning TO [MrNoLogin];
Run Code Online (Sandbox Code Playgroud)

测试#1:

SELECT SESSION_USER AS [SessionUser];

EXEC dbo.CheckSqlAgent;
SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning];
Run Code Online (Sandbox Code Playgroud)

返回:

SessionUser
-----------
dbo


status  status_desc
------  -----------
4       Running


IsSqlAgentRunning
-----------------
1
Run Code Online (Sandbox Code Playgroud)

测试#2:

EXECUTE AS USER='MrNoLogin';
SELECT SESSION_USER AS [SessionUser];

EXEC dbo.CheckSqlAgent;
SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning];
Run Code Online (Sandbox Code Playgroud)

返回:

SessionUser
-----------
MrNoLogin


Msg 297, Level 16, State 1, Procedure CheckSqlAgent, Line 7
The user does not have permission to perform this action.

Msg 297, Level 16, State 1, Line 6
The user does not have permission to perform this action.
Run Code Online (Sandbox Code Playgroud)

修复:

REVERT;
SELECT SESSION_USER AS [SessionUser];
-------------------------------------------------------------
USE [master];

-- DROP CERTIFICATE [DoStuffCert];
CREATE CERTIFICATE [DoStuffCert]
    ENCRYPTION BY PASSWORD = N'W0rdUp,Yo!'
    WITH SUBJECT = N'Certificate for Managing Special Permissions';

CREATE LOGIN [MrDoStuff] FROM CERTIFICATE [DoStuffCert];
GRANT VIEW SERVER STATE TO [MrDoStuff];

BACKUP CERTIFICATE [DoStuffCert]
    TO FILE = 'C:\TEMP\ViewSqlAgentStatus.CER'
    WITH PRIVATE KEY
    (
        FILE = 'C:\TEMP\ViewSqlAgentStatus.PVK',
        DECRYPTION BY PASSWORD = 'W0rdUp,Yo!',
        ENCRYPTION BY PASSWORD = 'DontStartNoneWontBeNone'
    );
-------------------------------------------------------------
USE [Test];

CREATE CERTIFICATE [DoStuffCert]
    FROM FILE = 'C:\temp\ViewSqlAgentStatus.CER'
    WITH PRIVATE KEY (
        FILE = 'C:\temp\ViewSqlAgentStatus.PVK',
        DECRYPTION BY PASSWORD = 'DontStartNoneWontBeNone',
        ENCRYPTION BY PASSWORD = 'W0rdUp,Yo!'
    );

ADD SIGNATURE TO dbo.CheckSqlAgent
    BY CERTIFICATE [DoStuffCert] WITH PASSWORD = 'W0rdUp,Yo!';

ADD SIGNATURE TO dbo.IsSqlAgentRunning
    BY CERTIFICATE [DoStuffCert] WITH PASSWORD = 'W0rdUp,Yo!';
Run Code Online (Sandbox Code Playgroud)

测试#3:

EXECUTE AS USER='MrNoLogin';
SELECT SESSION_USER AS [SessionUser];

EXEC dbo.CheckSqlAgent;
SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning];

REVERT;
Run Code Online (Sandbox Code Playgroud)

现在两者都适用于MrNoLogin:-)。


Up_*_*One -1

若要设置 SQL Server 代理的服务启动帐户
\n在注册的服务器中,单击加号以展开数据库引擎。

\n\n
    \n
  • 单击加号以展开本地服务器组文件夹
  • \n
\n\n


\n\n
    \n
  • 右键单击要设置服务\n启动帐户的服务器实例,然后选择 SQL Server Configuration Manager\xe2\x80\xa6。
  • \n
\n\n


\n\n
    \n
  • 在“用户帐户控制”对话框中,单击“是”。
  • \n
\n\n


\n\n
    \n
  • 在 SQL Server 配置管理器的控制台窗格中,选择 SQL\nServer 服务。
    在详细信息窗格中,右键单击 SQL Server\n代理(服务器名称),其中服务器名称是要更改其服务启动\n帐户的 SQL Server\n代理实例的名称,然后选择“属性”。\n
  • \n
  • 在 SQL Server 代理(服务器名称)属性对话框的\n登录选项卡中,选择登录身份下的以下选项之一:
  • \n
\n\n


\n\n
    \n
  • 内置帐户:如果您的作业仅需要来自本地服务器的资源,请选择此选项。有关如何选择\nWindows 内置帐户类型的信息,请参阅为 SQL\nServer 代理服务选择帐户。
  • \n
\n\n


\n\n
    \n
  • 重要提示 重要
  • \n
\n\n


\n\n
    \n
  • SQL Server 代理服务不支持 SQL Server Management Studio\n中的本地服务帐户
  • \n
\n\n


\n\n
    \n
  • 此帐户:如果您的作业需要跨网络的资源(包括应用程序资源),请选择此选项;如果您想要\n将事件转发到其他 Windows 应用程序日志;或者如果您想\n通过电子邮件或寻呼机通知操作员。如果您选择此选项:
  • \n
\n\n


\n\n
    \n
  • 在“帐户名称”框中,输入将用于运行\nSQL Server 代理的帐户。或者,单击“浏览”打开“选择用户\或组”对话框,然后选择要使用的帐户。
  • \n
\n\n


\n\n
    \n
  • 在“密码”框中,输入帐户的密码。在确认密码框中重新输入\n密码。
  • \n
\n\n


\n单击“确定”。
\n在 SQL Server 配置管理器中,单击“关闭”按钮。

\n

  • 我认为 @Ashish 并不是在寻找如何配置 SQL Server 代理,而是想知道它是否 (1) 正在运行或 (2) 正在运行特定作业。 (3认同)