如何在没有获得权限的情况下允许SQL用户创建LOGIN?

时间:2013-07-28 15:13:42

标签: security login sql-server-2012 impersonation

为了允许用户在没有直接获得权限的情况下创建登录,我决定使用上下文模拟子句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

1 个答案:

答案 0 :(得分:0)

我找到了答案here

由于用户没有服务器级别权限(例如,创建登录权限),我们必须在登录级别模拟(用户级别)下执行我们的SP。要做到这一点,我们需要:

  1. 从SP标题中删除with execute as 'dbo'子句

  2. execute as login='login_with_security_admin_privileges'子句添加到SP正文

  3. 就我而言,它看起来像这样:

    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