Permitir que no sea administrador del sistema, no propietario de un trabajo del Agente SQL Server para ejecutarlo

9

Tengo un trabajo que ejecuta un paquete SSIS.

Actualmente el propietario es una cuenta proxy. Puedo ejecutar el trabajo manualmente desde una cuenta sys-admin.

Nuestro servicio web inicia sesión con una cuenta limitada. Necesita ejecutar el trabajo. Actualmente no puede ver el trabajo (cuando trato de ejecutar por nombre, dice que no existe).

Traté de cambiar al propietario del trabajo a la cuenta limitada. Ahora podía ver el trabajo, pero el trabajo falló en la ejecución porque ya no puede ejecutar el paquete SSIS.

Tiene que haber una manera de permitir que la cuenta limitada ejecute un trabajo propiedad de otra cuenta, ¿verdad?

Cruncher
fuente

Respuestas:

17

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 SQLAgentOperatorRoleen msdbun inicio es escribir un procedimiento almacenado que las llamadas. sp_start_jobDe 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 StartAgentJobprocedimiento almacenado en la msdbbase 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.msdbJobMaptabla 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_MEMBERpara 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 sysadminen msdb. Al cambiar al contexto de la ORIGINAL_LOGIN, puede usar IS_MEMBERpara verificar que ORIGINAL_LOGINefectivamente se le han otorgado derechos a través de la dbo.msdbJobMaptabla. Luego vuelve a ser sysadminpara que pueda comenzar el trabajo.

RLF
fuente
3
To be able to start a job owned by someone else, you need to be member of the fixed role SQLAgentOperatorRole in msdbera 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!
Cruncher
1
Este código es increíblemente útil. El SQLAgentOperatorRole es demasiado amplio cuando desea que un usuario tenga acceso a uno o dos trabajos.
Steve Mangiameli