我正在尝试从 MyDB.dbo.MyStoredProc 执行 msdb.dbo.sp_start_Job 以执行 MyJob
1)我知道如果我为用户提供 SqlAgentUser 角色,他将能够运行他拥有的作业(但这是我的观察到的:用户能够启动/停止/重新启动 SQL 代理,所以我不想走这条路) - 如果我错了请告诉我,但我不明白为什么这样一个权限较低的用户能够启动/停止代理。
2)我知道如果我授予执行用户的执行权限给 msdb.dbo.Sp_Start_job 并启用所有权链或在用户数据库上启用可信度,它就会起作用(但我不想在用户数据库上启用所有权链或可信度)
3)我认为这可以通过代码签名来实现
用户数据库 i)创建一个存储过程 MyDB.dbo.MyStoredProc ii)创建一个证书 job_exec iii)使用证书 job_exec 签署 MyDB.dbo.MyStoredProc iv)导出证书
数据库 i) 导入证书 ii) 从此证书创建派生用户 iii) 授予此派生用户的身份验证权限 iv) 授予派生用户在 msdb.dbo.sp_start_job 上的执行权限 v) 授予执行 MyDB.dbo.MyStoredProc 的用户在 msdb.dbo.sp_start_job 上的执行权限
但是我尝试过了,它并没有起到作用——我不知道我遗漏了哪一部分或者做错了哪一部分。
因此,请为我提供一个简单的示例(带有脚本),用于使用代码签名从用户存储产品 MyDB.dbo.MyStoredProc 执行 msdb.dbo.sp_start_job
提前致以万分感谢
谢谢 Ram
答案1
1) 我认为 SSMS 正在做一些可以被视为“功能”的事情。您观察到的是,SSMS 允许您使用 Windows 权限重新启动 SQL Server 代理,无论您在 SQL Server 中拥有什么权限,或者您在对象资源管理器中登录到服务器的权限如何。例如,我在 msdb 中创建了一个仅具有 SqlAgentUser 角色的 sql 帐户,并且能够重新启动代理,尽管我以本地管理员身份启动了 SSMS。
我尝试再次执行相同的操作,尽管我创建了一个本地 Windows 用户帐户并使用 Run As.. 作为该本地非管理员用户启动了 SSMS。我发现我无法停止代理,事实上,当我尝试时 SSMS 崩溃了(天哪!)但代理仍在运行。...所以这个故事的寓意是,确保您只希望能够运行特定作业的用户不是 SQL Server 框上的本地管理员。如果是,那么他们可以已经重新启动代理和 SQL Server!所以别紧张!!
2) 您可以执行一些操作,例如创建自己的存储过程来调用msdb.dbo.sp_start_job
@yourjobid,并在该存储过程中使用 EXECUTE AS 或 setuser。然后授予您的用户仅对该存储过程的权限。
3)你疯了吗?!?!?!
答案2
代码签名是执行此操作的正确方法。我发现您的描述中唯一缺少的是 MyDB.dbo.MyStoredProc必须有一个 EXECUTE AS 子句(即使是 EXECUTE AS CALLER),否则代码签名不会生效。
答案3
Jonathan Kehayias 发布了一个对您来说似乎完美的解决方案。
看看这个,看看它是否适合您。 http://www.sqlservercentral.com/articles/Security/68873/