Probleme mit Datenbankberechtigungen für sp_send_mail


8

Ich versuche, Datenbank-Mail zu senden, aber ich bekomme EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. Der Code, den ich verwende, lautet wie folgt:

SELECT SUSER_NAME(), USER_NAME();
Create USER kyle_temp FOR LOGIN Foo
EXECUTE AS USER = 'kyle_temp';
SELECT SUSER_NAME(), USER_NAME();
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Mail Profile',
            @recipients = 'test@test.com',
            @subject = 'Test',
              @body = 'Test'
REVERT;
DROP USER kyle_temp

Das Foo-Login zeigt an, dass es dem Foo-Benutzer in msdb zugeordnet ist. Wenn ich mir den foo-Benutzer in msdb ansehe, sehe ich, dass "DatabaseMailUserRole" aktiviert ist und Execute on dbo hat sp_send_dbmail.

Was vermisse ich?

Antworten:


10

Sie befinden sich im gefürchteten Sandbox-Modus des EXECUTE ASKontexts, wie unter Erweitern des Datenbankidentitätswechsels mithilfe von EXECUTE AS beschrieben . In Kurzcode wird unter EXECUTE AS USER ...nur im Datenbankkontext und nicht im Instanzkontext als vertrauenswürdig eingestuft .

Es gibt drei Auswege:

  • Der einfache Weg: Markieren Sie die aktuelle Datenbank als VERTRAUEN ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • der richtige Ausweg: Verwenden Sie die Codesignatur
  • der Betrüger: verwenden EXECUTE AS LOGIN

Wenn in Ihrer Umgebung der dboaktuellen Datenbank vertraut wird, können Sie sich für TRUSTWORTHY entscheiden. Es wird funktionieren, aber wenn diese Eigenschaft festgelegt ist, db_ownerkann sich jeder in der aktuellen Datenbank zum Serveradministrator erheben.

Wenn Sie eine "richtige" Lösung wünschen, dann:

  1. Verschieben Sie diesen Code in einen gespeicherten Prozess
  2. Unterschreiben Sie den gespeicherten Prozess mit einem Zertifikat
  3. Löschen Sie den privaten Schlüssel (damit er nie wieder zum Signieren verwendet werden kann).
  4. Exportieren Sie den öffentlichen Schlüssel, importieren Sie ihn in [msdb]
  5. Erstellen Sie einen Benutzer, [msdb]der von diesem Zertifikat abgeleitet ist
  6. Erteilen Sie dem vom Zertifikat abgeleiteten Benutzer die erforderlichen Berechtigungen (AUTHENTICATE, EXECUTE on sp_send_mail)

Trivial, heh? Übrigens, jedes Mal, wenn Sie den signierten gespeicherten Prozess ändern, geht die Signatur verloren und der Vorgang muss wiederholt werden. Ein Beispiel finden Sie unter Aufrufen einer Prozedur in einer anderen Datenbank von einer aktivierten Prozedur .

Ich empfehle überhaupt nicht, EXECUTE AS LOGINstattdessen zu verwenden.


Auf lange Sicht versuche ich, dies als Auslöser ausführen zu lassen, daher ist mein EXECUTE AS eine Möglichkeit, kurzfristig zu testen ...
Kyle Brandt

1
Am saubersten ist es, einen lokal gespeicherten Prozess in Ihrer Datenbank zu haben und den Aufruf msdb.dbo.sp_send_mailin diesem lokalen SP-Body zu haben. Lassen Sie den Trigger diesen lokalen SP aufrufen. Code signieren Sie den SP.
Remus Rusanu
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.