有没有办法为我的数据库中的用户提供访问权限以执行 msdb.dbo.sp_send_dbmail
而无需将它们添加到MSDB数据库和DatabaseMailUserRole?
我试过这个:
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
但是我收到了这个错误:
The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.
谢谢!
答案 0 :(得分:5)
您的方法没问题,但您的包装器proc必须位于msdb数据库中。 然后,执行“EXEC msdb.dbo._TestSendMail”
这仍然会在msdb中留下dbo._TestSendMail的权限问题。 但是public / EXECUTE就足够了:它只暴露你需要的3个参数。
如有疑问,请添加WITH ENCRYPTION。这足以阻止没有sysadmin权限的任何人查看代码
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
答案 1 :(得分:2)
您实际上可以使用证书签名存储过程来执行此操作,并且不必在msdb中执行此操作:
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] 'someemail@domain.com', '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] 'someemail@domain.com', '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
*/
答案 2 :(得分:1)
一种可能的解决方案是将邮件封装为存储过程,例如mail_error_as_MAILER(你稍后会打电话) 和另一个存储过程 e.g。
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
但这需要: *硬编码密码(确保用户无法查看存储过程的定义......) *让用户访问sp_oacreate等...(打开其他安全问题,例如DOS)
通过这种方式,他们只能以您希望的方式使用邮件,而不会授予他们邮寄其他内容的权限。或更安全, 让用户将邮件放入某种mail_queue(你可以控制他们可以放入什么)并让代理人定期发送这些邮件
或者:允许他们发送邮件,但是让一个大型俱乐部滥用滥用