我们正在为我们的系统构建管理应用程序,该应用程序的一项功能是为新用户创建新数据库。此应用程序需要CREATE DATABASE,RESTORE DATABASE,CREATE USER,授予权限等 - 因此用户需要拥有一些非常强大的权限。
我们正在将这些服务与外部公司签订合同,我们不希望他们不受限制地访问我们的系统,我们只希望他们能够做我们允许他们做的事情。因此,我们考虑将整个流程封装在存储过程中,将EXECUTE授予特定域用户,并使用EXECUTE AS'SA'运行它。
不幸的是,这是不可能的 - SA不是数据库用户,当我们尝试将其定义为一个时,我们会收到错误
Msg 15405, Level 16, State 1, Line 1
Cannot use the special principal 'sa'.
然后我们考虑使用DBO并设置跨数据库所有权链接,但这一切都开始成为一个严重的问题。 有谁知道这样做的优雅方式?
答案 0 :(得分:4)
使用module signing完全可以实现。
EXECUTE AS CALLER
添加到过程[master]
请注意,对该过程的任何更改都将使签名无效,并且需要重做该过程。删除私钥非常重要,否则供应商可以签署不同的过程并获得对任意代码的提升权限。有关示例,请参阅Signing an Activated Procedure。
答案 1 :(得分:2)
要管理数据库中的内容,可以使用EXECUTE AS OWNER
并确保dbo拥有存储过程。没有问题
但是,CREATE DATABASE等需要服务器级权限。注意:您不需要sysadmin
权限。
使用SQL Server 2012,您可以将server roles和GRANT CREATE DATABASE
用于此服务器角色。对于早期版本,您可以直接将其授予登录。如果您愿意,也可以使用dbcreator
。
如果您决定他们需要管理登录,securityadmin
具有与sysadmin
相同的有效权限
答案 2 :(得分:-2)
create database admin;
GO
alter database admin set trustworthy on
GO
alter authorization on database::admin to [sa]
GO
use admin
GO
create procedure adminProc
with execute as 'dbo'
as
create database test
GO
create login tmp with password = 'tmp', check_policy = off
GO
create user tmp
GO
grant execute on adminProc to tmp
GO
execute as login = 'tmp'
GO
-- This fails
create database test
-- This works
exec adminProc
GO
revert
GO
drop database test
GO