Erlauben Sie Nicht-Sysadmin, Nicht-Eigentümer eines SQL Server-Agent-Jobs, ihn auszuführen

9

Ich habe einen Job, der ein SSIS-Paket ausführt.

Derzeit ist der Eigentümer ein Proxy-Konto. Ich kann den Job manuell über ein Systemadministratorkonto ausführen.

Unser Webservice meldet sich mit einem begrenzten Konto an. Es muss den Job ausführen. Derzeit kann der Job überhaupt nicht angezeigt werden (wenn ich versuche, ihn mit Namen auszuführen, heißt es, dass er nicht vorhanden ist).

Ich habe versucht, zum Eigentümer des Jobs auf das eingeschränkte Konto zu wechseln. Jetzt konnte der Job angezeigt werden, aber die Ausführung des Jobs schlug fehl, da das SSIS-Paket nicht mehr ausgeführt werden kann.

Es muss eine Möglichkeit geben, dem eingeschränkten Konto zu ermöglichen, einen Job auszuführen, der einem anderen Konto gehört, oder?

Cruncher
quelle

Antworten:

17

Es ist möglich, eine Methode zum Gewähren von Rechten zum Ausführen eines Jobs einzurichten, für die ein Benutzer nicht über die erforderlichen Berechtigungen verfügt, um sie selbst auszuführen.

BEARBEITEN: Zur Verdeutlichung der drei Optionen, indem Sie die SQLAgentOperatorRole explizit als Option erwähnen und einige Erläuterungen zur dritten Lösung hinzufügen.

(1) Wenn der Benutzer die Ausführung aller Jobs verwalten darf, machen Sie diesen Benutzer zu einem Mitglied von SQLAgentOperatorRole. Der Benutzer kann jeden SQL Agent-Job auf diesem Server starten (sowie stoppen, aktivieren und deaktivieren). (Diese Lösung stellte sich heraus, um den ursprünglichen Fragesteller zufrieden zu stellen.)

(2) Erland Sommarskog hat viel darüber geschrieben, wie Berechtigungen durch gespeicherte Prozeduren unter Verwendung von Gegensignaturen erteilt werden. Er hat eine Lösung bei:

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

Der entscheidende Punkt ist: "Um einen Job starten zu können, der einer anderen Person gehört, müssen Sie Mitglied der festen Rolle SQLAgentOperatorRolein sein msdb. Ein Start besteht darin, eine gespeicherte Prozedur zu schreiben, die sp_start_jobdiesen bestimmten Job anfordert, und diese Prozedur mit einem Zertifikat zu signieren und erstellen Sie dann einen Benutzer aus dem Zertifikat und machen Sie diesen Benutzer zu einem Mitglied von SQLAgentOperatorRole. "

(3) Mein allgemeiner Beschluss bestand darin, eine StartAgentJobgespeicherte Prozedur in der msdbDatenbank zu erstellen , mit der ein Benutzer Jobs starten kann, die jemand anderem gehören.

Dies erfordert eine Tabelle, um die Konfiguration zu verwalten, wer welchen Job ausführen kann. Da die folgende dbo.msdbJobMapTabelle auftragsspezifisch für SQL Server-Agenten ist, würde ich die Tabelle in erstellen msdb. Auf Wunsch kann es jedoch auch in einer anderen Servicedatenbank erstellt werden.

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

Die gespeicherte Prozedur ermöglicht es auch jedem Mitglied einer angegebenen Gruppe, einen Job zu starten, da damit die IS_MEMBERGruppenmitgliedschaft überprüft wird.

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;

Wie Sie sehen können, hängt die Prozedur davon ab, wie sysadminin ausgeführt zu werden msdb. Durch Umschalten in den Kontext des ORIGINAL_LOGINkann IS_MEMBERüberprüft werden, ob dem ORIGINAL_LOGINtatsächlich Rechte über die dbo.msdbJobMapTabelle gewährt wurden . Dann wird es wieder sysadminso, dass es den Job starten kann.

RLF
quelle
3
To be able to start a job owned by someone else, you need to be member of the fixed role SQLAgentOperatorRole in msdbwar alles, was ich brauchte (obwohl der Code, den Sie gepostet haben, nützlich aussieht). Dem Benutzer wird vertraut, dass er einen Job ausführt. Vielen Dank!
Cruncher
1
Dieser Code ist unglaublich nützlich. Die SQLAgentOperatorRole ist zu umfangreich, wenn ein Benutzer Zugriff auf einen oder zwei Jobs haben soll.
Steve Mangiameli