Problemi con le autorizzazioni del database per sp_send_mail


8

Sto cercando di inviare la posta del database ma sto ricevendo EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. Il codice che sto eseguendo è il seguente:

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

Il Foo Login mostra che è mappato all'utente Foo in msdb. Quando guardo l'utente foo in msdb vedo che ha "DatabaseMailUserRole" selezionato e ha Execute su dbo sp_send_dbmail.

Cosa mi sto perdendo?

Risposte:


10

Si sta eseguendo la temuta modalità "sandboxed" del EXECUTE AScontesto, come descritto in Estensione della rappresentazione del database mediante EXECUTE AS . In breve, il codice in esecuzione sotto EXECUTE AS USER ...è attendibile solo all'interno del contesto del database , non nel contesto dell'istanza.

Ci sono tre modi per uscire:

  • il modo più semplice: contrassegnare il database corrente come TRUSTWORTHY ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • l'uscita corretta: utilizzare la firma del codice
  • il trucco: usa EXECUTE AS LOGIN

Se nel tuo ambiente il dbodatabase corrente è attendibile, puoi andare su TRUSTWORTHY. Funzionerà, ma se questa proprietà è impostata, qualsiasi db_ownernel DB corrente può elevarsi all'amministratore del server.

Se vuoi una soluzione "corretta", allora:

  1. sposta questo codice in un proc memorizzato
  2. firmare il proc memorizzato con un certificato
  3. rilascia la chiave privata (in modo che non possa più essere utilizzata per firmare nulla)
  4. esporta la chiave pubblica, importala in [msdb]
  5. creare l'utente [msdb]derivato da questo certificato
  6. concedere le autorizzazioni necessarie (AUTHENTICATE, EXECUTE su sp_send_mail) all'utente derivato dal certificato

Trivial, eh? A proposito, ogni volta che modifichi il proc memorizzato firmato la firma viene persa e la procedura deve essere ripetuta. Vedere Chiamare una procedura in un altro database da una procedura attivata per un esempio.

Non consiglio assolutamente di usarlo EXECUTE AS LOGIN.


A lungo termine sto cercando di far eseguire questo come trigger, quindi il mio EXECUTE AS è un modo di testare a breve termine ...
Kyle Brandt

1
Il modo più pulito è avere un proc locale memorizzato nel tuo DB e avere la chiamata msdb.dbo.sp_send_mailin questo corpo SP locale. Chiedi al trigger di chiamare questo SP locale. Il codice firma il SP.
Remus Rusanu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.