Es posible configurar un método para otorgar derechos para ejecutar un trabajo que un usuario no tiene suficiente autoridad para ejecutar por sí mismo.
EDITAR: para mayor claridad sobre las tres opciones presentadas al mencionar explícitamente el SQLAgentOperatorRole como una opción y al agregar alguna explicación sobre la tercera solución.
(1) Si el usuario puede administrar la ejecución de todos los trabajos, haga que ese usuario sea miembro de SQLAgentOperatorRole. El usuario podrá iniciar (así como detener, habilitar y deshabilitar) cualquier trabajo del Agente SQL en ese servidor. (Esta solución resultó satisfacer al autor de la pregunta original).
(2) Erland Sommarskog ha escrito mucho sobre cómo otorgar permisos a través de procedimientos almacenados utilizando contra-firmas. Él tiene una solución en:
http://www.sommarskog.se/grantperm.html#countersignatures
El punto clave es: "Para ser capaz de iniciar un trabajo propiedad de otra persona, usted necesita ser miembro de la función fija SQLAgentOperatorRole
en msdb
un inicio es escribir un procedimiento almacenado que las llamadas. sp_start_job
De este trabajo específico, firman este procedimiento con un certificado , y luego cree un usuario a partir del certificado y haga que ese usuario sea miembro de SQLAgentOperatorRole
".
(3) Mi resolución general fue crear un StartAgentJob
procedimiento almacenado en la msdb
base de datos que permitiera a un usuario iniciar trabajos propiedad de otra persona.
Esto requiere una tabla para mantener la configuración de quién puede ejecutar qué trabajo. Dado que la siguiente dbo.msdbJobMap
tabla es específica del trabajo del Agente SQL Server, crearía la tabla en msdb
. Pero podría crearse en alguna otra base de datos de servicios si lo desea.
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');
El procedimiento almacenado también permite que cualquier miembro de un grupo específico inicie un trabajo, ya que se utiliza IS_MEMBER
para verificar la pertenencia al 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 puede ver, el procedimiento depende de la ejecución como sysadmin
en msdb
. Al cambiar al contexto de la ORIGINAL_LOGIN
, puede usar IS_MEMBER
para verificar que ORIGINAL_LOGIN
efectivamente se le han otorgado derechos a través de la dbo.msdbJobMap
tabla. Luego vuelve a ser sysadmin
para que pueda comenzar el trabajo.
To be able to start a job owned by someone else, you need to be member of the fixed role SQLAgentOperatorRole in msdb
era todo lo que necesitaba en realidad (aunque el código que publicaste parece útil). Se confía en el usuario para ejecutar cualquier trabajo. ¡Muchas gracias!