1

为了允许用户在不直接获得他们许可的情况下创建登录名,我决定使用上下文模拟子句EXECUTE AS[OWNER - in my case] 实现存储过程(参见下面的测试用例),但它不适用于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
4

1 回答 1

0

I found the answer here.

Because users do not have a server level privileges (create logins permission for example), we must execute our SP under login level impersonation (insted of user level). To do this we need:

  1. Remove with execute as 'dbo' clause from SP header

  2. Add execute as login='login_with_security_admin_privileges' clause to SP body

In my case it looks like this:

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

And also it is necessary to grant impersonate permission:

use master;
go
grant impersonate ON login::[login_with_security_admin_privileges] TO Unknown
go
于 2013-08-24T10:26:02.380 回答