我的理解是,我可以将该EXECUTE AS OWNER
子句用作我创建的过程的一部分,以使该过程的主体作为不同的用户运行。我的目标是执行一个需要sysadmin
角色 ( DBCC TRACEON(1224)
) 的命令。此过程应该由非特权用户调用。
我在用户下运行了以下脚本sa
:
SELECT USER_NAME(), USER_ID(), IsSysAdmin = IS_SRVROLEMEMBER('sysadmin')
-- dbo 1 1
IF EXISTS(SELECT * FROM sys.procedures WHERE name = 'MyProc')
DROP PROCEDURE MyProc
GO
CREATE PROCEDURE MyProc
WITH EXECUTE AS OWNER
AS
SELECT USER_NAME(), USER_ID(), IsSysAdmin = IS_SRVROLEMEMBER('sysadmin');
-- dbo 1 0
DBCC TRACEON(1224)
--Msg 2571, Level 14, State 3, Procedure MyProc, Line 7
--User 'dbo' does not have permission to run DBCC TRACEON.
RETURN
GO
EXEC MyProc
输出在注释中内联。事实证明,在程序之外,我似乎拥有sysadmin
会员资格,但在程序内部却没有。
该过程归dbo
用户所有。我知道不可能将sysadmin
角色授予数据库用户(至少 GUI 不提供这种可能性)。所以我看不出我怎么能让数据库用户拥有服务器角色。
我也尝试EXECUTE AS 'sa'
了哪个结果Cannot execute as the user 'sa', because it does not exist or you do not have permission.
。文档指出我只能指定用户名,而不是登录名。所以我明白为什么这不起作用。
如何使用sysadmin
角色成员身份运行我的程序?
通过允许非特权用户以 sysadmin 角色运行,您在安全性上打了一个洞。
如果您尝试设置
1224
traceflag,它会根据锁的数量禁用锁升级,您可以在表级别使用ALTER TABLE
例如,下面可以将锁升级到分区表上的分区级别。如果表未分区,则在 TABLE 级别设置锁升级。
ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
-- 有效选项为 AUTO、TABLE 和 DISABLE现在您可以只授予非特权用户更改表权限。
高温高压
它可以完成,但通常被认为是相当危险的。在一个非常基本的级别上,您
trustworthy
在数据库上设置标志,然后在execute as
sp 上使用您时,它可以利用它的服务器级别主体安全访问。由于这是多么危险,我不想在这里详细介绍。但是,我已经在此处发布了有关它的博客,并提供了有关如何执行此操作的具体说明。
话虽如此,请确保您绝对
NEED
这样做。你正在打开一个很大的安全漏洞。如果您决定这样做,请将您的 SP 放入它自己的数据库中,并且只授予用户连接和执行对 sp 的访问权限。创建一个 SQL Server 代理作业(由系统管理员成员拥有)可以解决问题,尽管我意识到这不是一个非常漂亮的解决方案。
用户可以使用 msdb.dbo.sp_start_job 启动作业(异步)。但是,如果需要,同步运行代理作业需要多几行代码。此外,显然,您需要启动并运行 SQL Server 代理服务。