为了允许用户在没有直接获得权限的情况下创建登录,我决定使用上下文模拟子句EXECUTE AS
[OWNER - 在我的情况下]实现存储过程(请参阅下面的测试用例),但它不起作用对于CREATE LOGIN
声明 - 我收到错误“用户无权执行此操作。”。
我怀疑数据库级别(用户范围)模拟在服务器级别(登录范围)没有意义。
也许有其他方法可以实现这个?或者也许我错了,程序应该有效?
任何建议将不胜感激
select system_user;
-- I'm dbo
go
create procedure dbo.CreatePlayer
@player_name nvarchar(10),
@player_password nvarchar(20)
with execute as 'dbo' /* or execute as owner - whatever */
as begin
exec('CREATE LOGIN ' + @player_name + ' WITH PASSWORD = '''+@player_password+''', CHECK_POLICY = OFF');
--CREATE LOGIN Player1 WITH PASSWORD = 'Password', CHECK_POLICY = OFF
end;
create login Unknown with password = 'Unknown', check_policy = off;
create user Unknown for login Unknown;
grant execute on [dbo].CreatePlayer to Unknown;
execute as user = 'Unknown'
select system_user
-- I'm Unknown
-- throws "User does not have permission to perform this action."
exec dbo.CreatePlayer 'Player1', 'Password';
revert;
select system_user;
-- I'm dbo
-- if I specify [with execute as 'dbo'] above in the procedure declaration
-- , this line throws "User does not have permission to perform this action."
-- too - that was surprising for me, because I'm dbo
exec dbo.CreatePlayer 'Player1', 'Password';
-- cleanup
drop login Player1
drop user Unknown
drop login Unknown
drop procedure dbo.CreatePlayer
答案 0 :(得分:0)
我找到了答案here。
由于用户没有服务器级别权限(例如,创建登录权限),我们必须在登录级别模拟(用户级别)下执行我们的SP。要做到这一点,我们需要:
从SP标题中删除with execute as 'dbo'
子句
将execute as login='login_with_security_admin_privileges'
子句添加到SP正文
就我而言,它看起来像这样:
create procedure dbo.CreatePlayer
@player_name nvarchar(10),
@player_password nvarchar(20)
as begin
exec('CREATE LOGIN ' + @player_name + ' WITH PASSWORD = '''+@player_password+''', CHECK_POLICY = OFF')
as login = 'login_with_security_admin_privileges';
end;
go
还有必要授予模仿权限:
use master;
go
grant impersonate ON login::[login_with_security_admin_privileges] TO Unknown
go