Man*_*eld 10 sql-server sql-server-agent sql-server-2014
我需要允许用户在没有任何能力启动其他代理的情况下启动特定的代理作业。为此,我创建了以下过程(简化):
ALTER PROCEDURE [dbo].[RunJob]
@job_name nvarchar(200)
WITH EXECUTE AS 'sysadminaccount'
AS
BEGIN
--SET NOCOUNT ON;
BEGIN TRY
EXEC msdb.dbo.sp_start_job @job_name = @job_name
-- Wait for job to finish
DECLARE @job_history_id AS INT = NULL
DECLARE @job_result AS INT = NULL
WHILE 1=1
BEGIN
SELECT TOP 1 @job_history_id = activity.job_history_id
FROM msdb.dbo.sysjobs jobs
INNER JOIN msdb.dbo.sysjobactivity activity ON activity.job_id = jobs.job_id
WHERE jobs.name = @job_name
ORDER BY activity.start_execution_date DESC
IF @job_history_id IS NULL
BEGIN
WAITFOR DELAY '00:00:01'
CONTINUE
END
ELSE
BREAK
END
-- Check exit code
SET @job_result = (SELECT history.run_status
FROM msdb.dbo.sysjobhistory history
WHERE history.instance_id = @job_history_id)
RETURN @job_result;
END TRY
BEGIN CATCH
THROW;
RETURN;
END CATCH
END
Run Code Online (Sandbox Code Playgroud)
但是,当我调用此过程时(已通过“sysadminaccount”验证它正在运行),我收到以下错误消息:
消息 229,级别 14,状态 5,过程 sp_start_job,第 1 行 对象“sp_start_job”、数据库“msdb”、架构“dbo”上的 EXECUTE 权限被拒绝。
该帐户是 sysadmin 角色的成员,因此据我所知,启动工作应该没有任何问题。我已经验证它是 msdb 中三个 sqlagent 角色的成员,并且这些角色都对sp_start_job
.
我怎样才能给这个帐户适当的权限?由于模拟,还有其他需要做的事情吗?
Aar*_*and 13
我不喜欢这个TRUSTWORTHY
选项,因为它会显着增加你接触各种事物的机会。正如 Remus 在这个答案中解释的那样,它基本上将 any 提升db_owner
到sysadmin
. 一些其他的事情值得一读的是一系列TRUSTWORTHY
由塞巴斯蒂安MEINE,在BOL主题和知识库文章(即使组件部分可能不是与您无关,在这种情况下):
(还有很多其他帖子警告不要盲目使用这个属性——仅仅因为它有效并且很容易并不意味着它是正确的做法——事实上这应该让你更加质疑它。)所以我建议采用不同的方法(还有其他方法,例如使用证书签名,但这对我来说一直有效):
msdb
。为该用户的登录创建一个用户msdb
:
USE msdb;
GO
CREATE USER floobarama FROM LOGIN floobarama;
Run Code Online (Sandbox Code Playgroud)授予用户对存储过程的执行权限:
GRANT EXECUTE ON [dbo].[RunJob] TO floobarama;
Run Code Online (Sandbox Code Playgroud)测试它 - 通过从另一个数据库调用过程:
USE tempdb;
GO
EXECUTE AS LOGIN = N'floobarama';
GO
EXEC msdb.dbo.RunJob @job_name = N'whatever';
GO
REVERT;
Run Code Online (Sandbox Code Playgroud)
或者更简单的测试,以防您现在不想运行任何作业并且不想等到该用户执行它来确定他们是否有足够的访问权限msdb
:
USE msdb;
GO
CREATE PROCEDURE dbo.whatever
WITH EXECUTE AS N'sysadminaccount'
AS
BEGIN
SET NOCOUNT ON;
SELECT [I am really...] = SUSER_SNAME();
END
GO
GRANT EXECUTE ON dbo.whatever TO floobarama;
USE tempdb;
GO
EXECUTE AS LOGIN = N'floobarama';
GO
EXEC msdb.dbo.whatever;
GO
REVERT;
Run Code Online (Sandbox Code Playgroud)
结果应该是:
I am really...
---------------
sysadminaccount
Run Code Online (Sandbox Code Playgroud)验证这不会msdb
向该用户公开任何其他内容:
USE tempdb;
GO
EXECUTE AS LOGIN = N'floobarama';
GO
SELECT job_id FROM msdb.dbo.sysjobs;
GO
REVERT;
Run Code Online (Sandbox Code Playgroud)
结果应该是...
消息 229,级别 14,状态 5,第 21 行
对象“sysjobs”、数据库“msdb”、架构“dbo”的 SELECT 权限被拒绝。
...因为在数据库中创建用户并没有赋予他们对该数据库中任何内容的自动权限;您需要为该用户或他们所在的角色或组(包括public
)明确这样做。
归档时间: |
|
查看次数: |
52181 次 |
最近记录: |