Problème avec les autorisations de base de données pour sp_send_mail

8

J'essaye d'envoyer le courrier de base de données mais je reçois EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. Je code que je cours est le suivant:

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 = '[email protected]',
            @subject = 'Test',
              @body = 'Test'
REVERT;
DROP USER kyle_temp

La connexion Foo montre qu'il est mappé à l'utilisateur Foo dans msdb. Quand je regarde l'utilisateur foo dans msdb, je vois qu'il a "DatabaseMailUserRole" vérifié et a Exécuter sur dbo sp_send_dbmail.

Qu'est-ce que je rate?

Kyle Brandt
la source

Réponses:

10

Vous utilisez le mode redouté du «bac à sable» du EXECUTE AScontexte, comme décrit dans Extension de l'emprunt d'identité de base de données en utilisant EXECUTE AS . Dans le code court exécuté sous EXECUTE AS USER ...n'est approuvé que dans le contexte de la base de données , pas dans le contexte de l'instance.

Il existe trois solutions:

  • en toute simplicité: marquez la base de données actuelle comme TRUSTWORTHY ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • la bonne sortie: utilisez la signature de code
  • la triche: utiliser EXECUTE AS LOGIN

Si, dans votre environnement, la dbobase de données actuelle est approuvée, vous pouvez opter pour TRUSTWORTHY. Cela fonctionnera, mais si cette propriété est définie, n'importe laquelle db_ownerdans la base de données actuelle peut s'élever en tant qu'administrateur du serveur.

Si vous voulez une solution «correcte», alors:

  1. déplacer ce code dans un proc stocké
  2. signer le proc stocké avec un certificat
  3. supprimer la clé privée (afin qu'elle ne puisse plus jamais être utilisée pour signer quoi que ce soit)
  4. exporter la clé publique, l'importer dans [msdb]
  5. créer un utilisateur [msdb]dérivé de ce certificat
  6. accorder les autorisations nécessaires (AUTHENTICATE, EXECUTE sur sp_send_mail) à l'utilisateur dérivé du certificat

Trivial, hein? BTW, chaque fois que vous modifiez le processus stocké signé, la signature est perdue et la procédure doit être répétée. Voir Appel d'une procédure dans une autre base de données à partir d'une procédure activée pour un exemple.

Je ne recommande absolument pas d'utiliser à la EXECUTE AS LOGINplace.

Remus Rusanu
la source
À long terme, j'essaie de faire exécuter cela comme déclencheur, donc mon EXECUTE AS est un moyen de tester à court terme ...
Kyle Brandt
1
La façon la plus simple est d'avoir un proc stocké local dans votre base de données et d'avoir l'appel à msdb.dbo.sp_send_mailce corps SP local. Demandez au déclencheur d'appeler ce SP local. Code signe le SP.
Remus Rusanu