web-dev-qa-db-fra.com

Autoriser un non-administrateur système, non propriétaire d'un travail de l'Agent SQL Server à l'exécuter

J'ai un travail qui exécute un package SSIS.

Actuellement, le propriétaire est un compte proxy. Je peux exécuter le travail manuellement à partir d'un compte administrateur système.

Notre service Web se connecte à l'aide d'un compte limité. Il doit exécuter le travail. Actuellement, il ne peut pas voir le travail du tout (lorsque j'essaie de l'exécuter par son nom, il dit qu'il n'existe pas).

J'ai essayé de changer de propriétaire du travail pour le compte limité. Maintenant, il pouvait voir le travail, mais l'exécution du travail a échoué car il ne peut plus exécuter le package SSIS.

Il doit y avoir un moyen d'autoriser le compte limité à exécuter un travail appartenant à un autre compte, n'est-ce pas?

9
Cruncher

Il est possible de configurer une méthode pour accorder des droits d'exécution d'un travail qu'un utilisateur ne dispose pas des droits suffisants pour s'exécuter seul.

EDIT: Pour plus de clarté sur les trois options présentées en mentionnant explicitement SQLAgentOperatorRole comme option et en ajoutant quelques explications sur la troisième solution.

(1) Si l'utilisateur est autorisé à gérer l'exécution de tous les travaux, faites de cet utilisateur un membre de SQLAgentOperatorRole. L'utilisateur pourra démarrer (ainsi qu'arrêter, activer et désactiver) tout travail de l'Agent SQL sur ce serveur. (Cette solution s'est avérée satisfaire le demandeur d'origine.)

(2) Erland Sommarskog a beaucoup écrit sur la façon d'accorder des autorisations via des procédures stockées à l'aide de contre-signatures. Il a une solution à:

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

Le point clé est: "Pour pouvoir démarrer un travail appartenant à quelqu'un d'autre, vous devez être membre du rôle fixe SQLAgentOperatorRole dans msdb. Un début consiste à écrire une procédure stockée qui appels sp_start_job pour ce travail spécifique, signez cette procédure avec un certificat, puis créez un utilisateur à partir du certificat et faites de cet utilisateur un membre de SQLAgentOperatorRole. "

(3) Ma résolution générale était de créer une procédure stockée StartAgentJob dans la base de données msdb permettant à un utilisateur de démarrer emplois appartenant à quelqu'un d'autre.

Cela nécessite une table pour conserver la configuration de qui peut exécuter quel travail. Depuis le dbo.msdbJobMap la table est spécifique au travail de l'Agent SQL Server, je créerais la table dans msdb. Mais il pourrait être créé dans une autre base de données de services si vous le souhaitez.

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

La procédure stockée permet également à tout membre d'un groupe spécifié de démarrer un travail car il utilise IS_MEMBER pour vérifier l'appartenance au groupe.

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;

Comme vous pouvez le voir, la procédure dépend de l'exécution en tant que sysadmin dans msdb. En passant au contexte du ORIGINAL_LOGIN il est capable d'utiliser IS_MEMBER pour vérifier que le ORIGINAL_LOGIN a en effet obtenu des droits par le biais de dbo.msdbJobMap table. Ensuite, il redevient sysadmin pour pouvoir démarrer le travail.

17
RLF