Problemas com permissões de banco de dados para sp_send_mail

8

Estou tentando enviar email do banco de dados, mas estou recebendo EXECUTE permission denied on the object 'sp_send_dbmail' database 'msdb', schema 'dbo'.. O código que estou executando é o seguinte:

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

O logon do Foo mostra que ele é mapeado para o usuário do Foo no msdb. Quando olho para o usuário foo no msdb, vejo que ele tem "DatabaseMailUserRole" marcado e tem Execute no dbo sp_send_dbmail.

o que estou perdendo?

Kyle Brandt
fonte

Respostas:

10

Você está executando o modo temido 'sandboxed' do EXECUTE AScontexto, conforme descrito em Estendendo a representação do banco de dados usando EXECUTE AS . Em resumo, o código executado em EXECUTE AS USER ...é confiável somente dentro do contexto do banco de dados , não no contexto da instância.

Existem três saídas:

  • da maneira mais fácil: marque o banco de dados atual como TRUSTWORTHY ALTER DATABASE [...] SET TRUSTWORTHY ON;
  • a saída correta: use a assinatura de código
  • o truque: use EXECUTE AS LOGIN

Se em seu ambiente o dbobanco de dados atual for confiável, você poderá usar o TRUSTWORTHY. Funcionará, mas se essa propriedade estiver definida, qualquer um db_ownerno banco de dados atual poderá se elevar para o administrador do servidor.

Se você deseja uma solução 'correta', então:

  1. mova esse código em um processo armazenado
  2. assine o processo armazenado com um certificado
  3. solte a chave privada (para que ela nunca possa ser usada novamente para assinar nada)
  4. exportar a chave pública, importá-la para [msdb]
  5. criar usuário [msdb]derivado deste certificado
  6. conceda as permissões necessárias (AUTHENTICATE, EXECUTE em sp_send_mail) ao usuário derivado do certificado

Trivial, hein? BTW, toda vez que você modifica o processo armazenado assinado, a assinatura é perdida e o procedimento deve ser repetido. Consulte Chamar um procedimento em outro banco de dados a partir de um procedimento ativado para obter um exemplo.

Eu totalmente não recomendo usar EXECUTE AS LOGIN.

Remus Rusanu
fonte
No longo prazo, eu estou tentando ter este executado como um gatilho, então minha EXECUTAR AS é uma forma de testar no curto prazo ...
Kyle Brandt
11
A maneira mais limpa é ter um processo armazenado local no seu banco de dados e fazer a chamada msdb.dbo.sp_send_mailnesse corpo local do SP. Faça com que o gatilho chame esse SP local. Código assine o SP.
Remus Rusanu