允许非系统管理员、非 SQL Server 代理作业的所有者执行它

Cru*_*her 10 sql-server permissions ssis jobs

我有一份运行 SSIS 包的工作。

目前所有者是代理帐户。我可以从系统管理员帐户手动运行该作业。

我们的网络服务使用受限帐户登录。它需要执行作业。目前它根本看不到作业(当我尝试按名称执行时,它说它不存在)。

我尝试将工作所有者更改为受限帐户。现在它可以看到作业,但作业执行失败,因为它无法再运行 SSIS 包。

必须有一种方法可以让受限帐户运行另一个帐户拥有的作业,对吗?

RLF*_*RLF 18

可以设置一种方法来授予运行用户没有足够权限自行运行的作业的权限。

编辑:为了通过明确提及 SQLAgentOperatorRole 作为选项并添加对第三个解决方案的一些解释来清楚地说明三个选项。

(1)如果允许用户管理所有作业的执行,则使该用户成为 SQLAgentOperatorRole 的成员。用户将能够启动(以及停止、启用和禁用)该服务器上的任何 SQL 代理作业。 (结果证明这个解决方案满足了最初的提问者。)

(2) Erland Sommarskog 写了很多关于如何使用反签名通过存储过程授予权限的文章。他有一个解决方案:

http://www.sommarskog.se/grantperm.html#countersignatures

关键的一点是:“为了能够开始别人拥有一份工作,你需要固定角色的成员SQLAgentOperatorRolemsdb一开始是写一个存储过程调用。sp_start_job对于这个特定的工作,签署过程与证书,然后从证书创建一个用户并使该用户成为 的成员SQLAgentOperatorRole。”

(3)我的一般解决方案是StartAgentJobmsdb数据库中创建一个存储过程,允许用户启动其他人拥有的作业。

这需要一个表来维护谁可以运行哪个作业的配置。由于下dbo.msdbJobMap表是特定于 SQL Server 代理作业的表,因此我将在msdb. 但如果需要,它可以在其他一些服务数据库中创建。

USE msdb;

/* Create a table to hold configuration of who can start jobs. */
CREATE TABLE dbo.msdbJobMap  
 (job_name NVARCHAR(128),
  group_name NVARCHAR(256));

/* Populate the table of allowed groups for a job 
   A group may be a single user or a Windows group. */
INSERT INTO dbo.msdbJobMap Values (N'Test it out',N'Domain\Group');
INSERT INTO dbo.msdbJobMap Values (N'Another job',N'Domain\OtherGroup');
INSERT INTO dbo.msdbJobMap Values (N'Special job',N'Domain\Joe');
INSERT INTO dbo.msdbJobMap Values (N'Special job',N'Domain\Andre');    
Run Code Online (Sandbox Code Playgroud)

存储过程还允许指定组的任何成员启动作业,因为它用于IS_MEMBER检查组成员身份。

CREATE PROCEDURE dbo.StartAgentJob
@Job_Name NVARCHAR(128)
WITH EXECUTE AS OWNER
AS
SET NOCOUNT ON;

DECLARE @Allowed INT;
SET @Allowed = 0;

/* Since this runs as sysadmin need to check group membership of original login*/
EXECUTE AS LOGIN = ORIGINAL_LOGIN();
IF EXISTS (SELECT * FROM dbo.msdbJobMap
           WHERE job_name = @Job_Name
           AND IS_MEMBER(group_name) = 1 )
   SET @Allowed = 1;
REVERT;

/* Back to sysadmin so that we can start the job. */

IF @Allowed = 1 
    EXEC sp_start_job @job_name = @Job_Name;
ELSE
    PRINT 'Invalid attempt to start ''' + QUOTENAME(@Job_Name)+'''';
RETURN;
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,过程取决于作为运行sysadminmsdb。通过切换到 的上下文,ORIGINAL_LOGIN它可以IS_MEMBER用来检查ORIGINAL_LOGIN确实已通过dbo.msdbJobMap表授予权限。然后它恢复原状,sysadmin以便它可以开始工作。

  • `为了能够开始其他人拥有的工作,你需要成为 msdb 中固定角色 SQLAgentOperatorRole 的成员`这就是我真正需要的(尽管你发布的代码看起来很有用)。用户可以运行任何作业。非常感谢! (3认同)