Problemas con los permisos de la base de datos para sp_send_mail

8

Estoy tratando de enviar correo electrónico a la base de datos pero estoy recibiendo EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. El código que estoy ejecutando es el siguiente:

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

El inicio de sesión de Foo muestra que está asignado al usuario de Foo en msdb. Cuando miro al usuario foo en msdb, veo que tiene "DatabaseMailUserRole" marcado y tiene Execute en dbo sp_send_dbmail.

¿Qué me estoy perdiendo?

Kyle Brandt
fuente

Respuestas:

10

Se está ejecutando en el temido modo 'sandboxed' del EXECUTE AScontexto, como se describe en Ampliación de la suplantación de bases de datos mediante EXECUTE AS . En resumen, el código que se ejecuta EXECUTE AS USER ...solo es confiable dentro del contexto de la base de datos , no en el contexto de la instancia.

Hay tres salidas:

  • la manera fácil: marque la base de datos actual como CONFIABLE ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • la salida correcta: use la firma de código
  • el truco: uso EXECUTE AS LOGIN

Si en su entorno la dbobase de datos actual es confiable, puede usar TRUSTWORTHY. Funcionará, pero si se establece esta propiedad, cualquiera db_ownerde las bases de datos actuales puede elevarse a administrador del servidor.

Si desea una solución 'correcta', entonces:

  1. mover este código en un proceso almacenado
  2. firmar el proceso almacenado con un certificado
  3. suelte la clave privada (para que nunca se pueda volver a usar para firmar nada)
  4. exportar la clave pública, importarla en [msdb]
  5. crear usuario [msdb]derivado de este certificado
  6. conceder los permisos necesarios (AUTENTICAR, EJECUTAR en sp_send_mail) al usuario derivado del certificado

Trivial, ¿eh? Por cierto, cada vez que modifica el proceso almacenado firmado, la firma se pierde y el procedimiento debe repetirse. Consulte Llamar a un procedimiento en otra base de datos desde un procedimiento activado para ver un ejemplo.

No recomiendo usar en su EXECUTE AS LOGINlugar.

Remus Rusanu
fuente
A la larga, estoy tratando de ejecutar esto como un disparador, por lo que mi EJECUTAR AS es una forma de probar a corto plazo ...
Kyle Brandt
1
La forma más limpia es tener un proceso almacenado local en su base de datos y tener la llamada msdb.dbo.sp_send_mailen este cuerpo SP local. Haga que el disparador llame a este SP local. Código de firmar el SP.
Remus Rusanu