É possível configurar um método para conceder direitos para executar uma tarefa que um usuário não possui autoridade suficiente para executar por conta própria.
Edição: para maior clareza sobre as três opções apresentadas, mencionando explicitamente o SQLAgentOperatorRole como uma opção e adicionando algumas explicações sobre a terceira solução.
(1) Se o usuário tiver permissão para gerenciar a execução de todas as tarefas, torne esse usuário membro de SQLAgentOperatorRole. O usuário poderá iniciar (além de parar, ativar e desativar) qualquer trabalho do SQL Agent nesse servidor. (Essa solução acabou satisfazendo o solicitante original.)
(2) Erland Sommarskog escreveu muito sobre como conceder permissões por meio de procedimentos armazenados usando contra-assinaturas. Ele tem uma solução em:
http://www.sommarskog.se/grantperm.html#countersignatures
O ponto-chave é: "Para ser capaz de iniciar um trabalho de propriedade de outra pessoa, você precisa ser membro da função fixa SQLAgentOperatorRole
em msdb
Um começo é escrever um procedimento armazenado que as chamadas. sp_start_job
Para este trabalho específico, assinar esse procedimento com um certificado e crie um usuário a partir do certificado e faça desse usuário um membro SQLAgentOperatorRole
".
(3) Minha resolução geral foi criar um StartAgentJob
procedimento armazenado no msdb
banco de dados, permitindo que um usuário iniciasse trabalhos pertencentes a outras pessoas.
Isso requer uma tabela para manter a configuração de quem pode executar qual trabalho. Como a dbo.msdbJobMap
tabela a seguir é específica da tarefa do SQL Server Agent, eu criaria a tabela msdb
. Mas poderia ser criado em outro banco de dados de serviço, se desejado.
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');
O procedimento armazenado também permite que qualquer membro de um grupo especificado inicie um trabalho, pois ele usa IS_MEMBER
para verificar a associação ao grupo.
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;
Como você pode ver, o procedimento depende da execução como sysadmin
em msdb
. Ao alternar para o contexto do, ORIGINAL_LOGIN
ele pode usar IS_MEMBER
para verificar ORIGINAL_LOGIN
se realmente foram concedidos direitos através da dbo.msdbJobMap
tabela. Depois, volta a ser sysadmin
para que possa começar o trabalho.
To be able to start a job owned by someone else, you need to be member of the fixed role SQLAgentOperatorRole in msdb
era tudo o que eu realmente precisava (embora o código que você postou pareça útil). O usuário é confiável para executar qualquer trabalho. Muito obrigado!