2 sql-server permissions sql-server-2012 connections impersonation
我创建了一个存储过程,允许用户在 QA 环境中关闭所有数据库连接。我是 SA 并创建了程序。
当我修改 SP 时,在没有“以所有者身份执行”的情况下运行它,我得到了结果。当我添加“以所有者身份执行”时,我没有收到任何结果。
试图理解为什么。
create procedure [dbo].[DatabaseConnectionClose]
@DatabaseName varchar(255)
with execute as owner
as
DECLARE @kill varchar(8000) = '';
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'
FROM sys.dm_exec_sessions
WHERE database_id = db_id(@DatabaseName)
select @kill as CloseConnectionScript
EXEC(@kill);
Run Code Online (Sandbox Code Playgroud)
使用语句的EXECUTE AS
子句CREATE {module_type}
是模拟,但仅限于数据库级别。所有者是“dbo”(至少在这种情况下),但这只是一个用户;数据库级主体。该KILL
命令需要实例级权限。默认情况下,当使用数据库级模拟(EXECUTE AS
子句或 EXECUTE AS USER
语句)时,进程被隔离到当前数据库,即使该用户映射到具有适当权限的登录(通过具有相同的 SID)。由于此限制,不允许进程到达实例以检查实例级别的权限。
要正确执行此操作:
EXECUTE AS
使用模块签名来实现:
在不授予任何人的情况下安全轻松地使用高级权限:服务器级(我的博客文章;外部,但有更好的解释)
我需要为用户提供哪些最低权限才能检查 SQL Server 代理服务的状态?(我的答案之一,在 DBA.SE 上)
您需要授予基于证书的登录的唯一权限是:(ALTER ANY CONNECTION
根据KILL的文档)
有关模块签名的更多信息,请访问:模块签名信息
此外,除了由阿龙贝特朗在关于这个问题的意见提出的非常好的一点,你必须要小心不要杀会议合法程序,如SQL Server代理,等你应该至少过滤上program_name
的柱sys.dm_exec_sessions
,如果不是login_name
(也可能是其他人)。
但是,如果ALTER DATABASE [{db_name}] SET...
最终成为继续进行的方式,则使用以下帖子作为指南,因为在这种情况下您不会关心实例级别的权限: