web-dev-qa-db-ja.com

SQL Serverエージェントジョブの非sysadmin、非所有者に実行を許可する

SSISパッケージを実行するジョブがあります。

現在、所有者はプロキシアカウントです。 sys-adminアカウントからジョブを手動で実行できます。

当社のWebサービスは、制限付きアカウントを使用してログインします。ジョブを実行する必要があります。現在、ジョブをまったく表示できません(名前で実行しようとすると、存在しないと表示されます)。

オーナー限定のアカウントに変更してみました。これでジョブを表示できましたが、SSISパッケージを実行できなくなったため、ジョブは実行に失敗しました。

制限付きアカウントが別のアカウントが所有するジョブを実行できるようにする方法が必要ですか?

9
Cruncher

ユーザーが自分で実行するのに十分な権限を持っていないジョブを実行する権限を付与するメソッドを設定することができます。

EDIT:SQLAgentOperatorRoleをオプションとして明示的に示し、3番目のソリューションに説明を追加することで、3つのオプションを明確にする。

(1)ユーザーがすべてのジョブの実行を管理できる場合は、そのユーザーをSQLAgentOperatorRoleのメンバーにします。ユーザーは、そのサーバーでSQLエージェントジョブを開始(および停止、有効化、無効化)できます。 (この解決策は、元の質問者を満足させることが判明しました。)

(2)Erland Sommarskogは、副署名を使用してストアドプロシージャを通じてアクセス許可を付与する方法について多くのことを書いています。彼は解決策を持っています:

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

重要な点は次のとおりです。「他のユーザーが所有するジョブを開始できるようにするには、SQLAgentOperatorRoleの固定ロールmsdbのメンバーである必要があります。最初に、次のようなストアドプロシージャを記述します。この特定のジョブに対してsp_start_jobを呼び出し、証明書でその手順に署名してから、証明書からユーザーを作成し、そのユーザーをSQLAgentOperatorRoleのメンバーにします。

(3)私の一般的な解決策は、StartAgentJobデータベースにmsdbストアドプロシージャを作成して、ユーザーが開始できるようにすることでした他の誰かが所有する仕事。

これには、誰がどのジョブを実行できるかの構成を維持するためのテーブルが必要です。次の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に戻り、ジョブを開始できるようにします。

17
RLF