sp_send_dbmail query profile_name name mail enviar correo con sql-server-2005 stored-procedures permissions

sql-server-2005 - query - sp_send_dbmail sql 2016



Cómo ejecutar sp_send_dbmail mientras se limitan los permisos (3)

Una solución posible es encapsular el correo como un procedimiento almacenado, por ejemplo mail_error_as_MAILER (que luego llamará) y otro procedimiento almacenado, por ejemplo

ALTER PROCEDURE [dbo].[mail_error](@error_ID int) SET NOCOUNT ON declare @rc int declare @object int declare @src varchar(255) declare @desc varchar(255) declare @osql_cmd varchar(1000) -- create shell object exec @rc = sp_oacreate ''wscript.shell'', @object out if @rc0 begin exec sp_oageterrorinfo @object, @src out, @desc out return END DECLARE @user VARCHAR(50) DECLARE @password VARCHAR(50) DECLARE @database VARCHAR(50) DECLARE @server VARCHAR(50) DECLARE @sql varchar(200) SET @user=MAILER,@password=XXXXXX,@database=XXXXXX,@server=XXXXX SET @sql= ''EXEC mail_ERROR_as_MAILER @error_ID='' + CAST(@error_id as varchar(10)) set @osql_cmd=''osql -U''+@user+'' -P''+@password+'' -d''+@database+'' -S"''+@server+''" -Q"'' +@sql+''"'' exec @rc= sp_oamethod @object, ''run'', null, @osql_cmd --print @rc if @rc0 begin exec sp_oageterrorinfo @object, @src out, @desc out return end -- destroy shell object exec sp_oadestroy @object

Pero esto requiere: * contraseña de hardcoding (asegúrese de que los usuarios no puedan ver la definición del procedimiento almacenado ...) * dando acceso a los usuarios a sp_oacreate, etc ... (abre otros problemas de seguridad, por ejemplo, DOS)

de esa manera solo pueden usar el correo de la forma que desee sin darles permiso para enviar por correo otras cosas.

O más seguro, permita que los usuarios coloquen el correo en algún tipo de mail_queue (que puede controlar lo que pueden poner) y solicite a un agente que envíe estos correos periódicamente

O bien: dales permiso para enviar correos pero toma un club grande con picos oxidados en el abuso

¿Hay alguna manera de proporcionar acceso a los usuarios en mi base de datos para ejecutar msdb.dbo.sp_send_dbmail sin la necesidad de agregarlos a la base de datos MSDB y al DatabaseMailUserRole?

He intentado esto:

ALTER PROCEDURE [dbo].[_TestSendMail] ( @To NVARCHAR(1000), @Subject NVARCHAR(100), @Body NVARCHAR(MAX) ) WITH EXECUTE AS OWNER AS BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = N''myProfile'', @recipients = @To, @subject = @Subject, @body = @Body END

Pero me sale este error:

The EXECUTE permission was denied on the object ''sp_send_dbmail'', database ''msdb'', schema ''dbo''.

¡Gracias!


De hecho, puede hacerlo con un procedimiento almacenado con certificado firmado y no tiene que ser en msdb para hacerlo:

CREATE DATABASE TestDBMail GO USE [TestDBMail] GO CREATE PROCEDURE [dbo].[TestSendMail] ( @To NVARCHAR(1000), @Subject NVARCHAR(100), @Body NVARCHAR(MAX) ) WITH EXECUTE AS OWNER AS BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = N''Database Mail Profile'', @recipients = @To, @subject = @Subject, @body = @Body END GO -- This should fail EXECUTE [dbo].[TestSendMail] ''[email protected]'', ''test'', ''body'' -- Create a certificate to sign stored procedures with CREATE CERTIFICATE [DBMailCertificate] ENCRYPTION BY PASSWORD = ''$tr0ngp@$$w0rd'' WITH SUBJECT = ''Certificate for signing TestSendMail Stored Procedure''; GO -- Backup certificate so it can be create in master database BACKUP CERTIFICATE [DBMailCertificate] TO FILE = ''d:/Backup/DBMailCertificate.CER''; GO -- Add Certificate to Master Database USE [master] GO CREATE CERTIFICATE [DBMailCertificate] FROM FILE = ''d:/Backup/DBMailCertificate.CER''; GO -- Create a login from the certificate CREATE LOGIN [DBMailLogin] FROM CERTIFICATE [DBMailCertificate]; GO -- The Login must have Authenticate Sever to access server scoped system tables -- per http://msdn.microsoft.com/en-us/library/ms190785.aspx GRANT AUTHENTICATE SERVER TO [DBMailLogin] GO -- Create a MSDB User for the Login USE [msdb] GO CREATE USER [DBMailLogin] FROM LOGIN [DBMailLogin] GO -- Add msdb login/user to the DatabaseMailUserRole EXEC msdb.dbo.sp_addrolemember @rolename = ''DatabaseMailUserRole'', @membername = ''DBMailLogin''; GO USE [TestDBMail] GO -- Sign the procedure with the certificate''s private key ADD SIGNATURE TO OBJECT::[TestSendMail] BY CERTIFICATE [DBMailCertificate] WITH PASSWORD = ''$tr0ngp@$$w0rd''; GO -- This will succeed EXECUTE [dbo].[TestSendMail] ''[email protected]'', ''test'', ''body'' /* -- Cleanup USE [msdb] GO DROP USER [DBMailLogin] GO USE [master] GO DROP LOGIN [DBMailLogin] DROP CERTIFICATE [DBMailCertificate] DROP DATABASE [TestDBMail] -- Delete the certificate backup from disk */


Su enfoque está bien, pero su proceso de contenedor debe estar en la base de datos msdb. Luego, ejecuta "EXEC msdb.dbo._TestSendMail"

Esto todavía deja el problema de los permisos en dbo._TestSendMail en msdb. Pero public / EXECUTE será suficiente: solo expone los 3 parámetros que necesita.

Si tiene dudas, agregue CON ENCRIPTACIÓN. Esto es lo suficientemente bueno para detener a cualquier persona sin derechos de administrador de sistemas viendo el código

USE msdb GO CREATE PROCEDURE [dbo].[_TestSendMail] ( @To NVARCHAR(1000), @Subject NVARCHAR(100), @Body NVARCHAR(MAX) ) -- not needec WITH EXECUTE AS OWNER AS BEGIN EXEC dbo.sp_send_dbmail @profile_name = N''myProfile'', @recipients = @To, @subject = @Subject, @body = @Body END