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


9

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

当前所有者是代理帐户。我可以从sys-admin帐户手动运行作业。

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

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

必须有一种方法允许受限帐户运行另一个帐户拥有的工作,对吗?

Answers:


17

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

编辑:为清楚起见,通过显式提及SQLAgentOperatorRole作为选项并通过在第三个解决方案上添加一些解释,从而提供了三个选项。

(1)如果允许用户管理所有作业的执行,则使该用户成为SQLAgentOperatorRole的成员。用户将能够在该服务器上启动(以及停止,启用和禁用)任何SQL Agent作业。 (事实证明,此解决方案可以满足最初的要求。)

(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');    

由于存储过程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;

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


3
To be able to start a job owned by someone else, you need to be member of the fixed role SQLAgentOperatorRole in msdb实际上是我所需要的(尽管您发布的代码看起来很有用)。信任用户可以运行任何作业。非常感谢!
Cruncher 2014年

1
此代码非常有用。当您希望用户可以访问一个或两个作业时,SQLAgentOperatorRole的范围过大。
Steve Mangiameli '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.