简体   繁体   English

SQL Server:向存储过程中的受限用户授予非常高的特权

[英]SQL Server: granting very high privileges to a limited user inside a stored procedure

We are building a management app for our system, and one of the app's abilities is to create new databases for new users. 我们正在为我们的系统构建一个管理应用程序,该应用程序的功能之一就是为新用户创建新的数据库。 This app needs to CREATE DATABASE, RESTORE DATABASE, CREATE USER, grant permissions, etc - so the user needs to have some very strong permissions. 此应用需要创建数据库,还原数据库,创建用户,授予权限等-因此用户需要具有一些非常强大的权限。

We are contracting these services to an external company and we do not want to give them unrestricted access to our system, we only want them to be able to do what we allow them to do. 我们正在将这些服务外包给外部公司,我们不想让它们不受限制地访问我们的系统,我们只希望它们能够做我们允许他们做的事情。 So we thought about encapsulating the entire process in a stored procedure, granting EXECUTE on this to a specific domain user, and running it with EXECUTE AS 'SA'. 因此,我们考虑将整个过程封装在一个存储过程中,将EXECUTE授予特定的域用户,然后使用EXECUTE AS'SA'运行它。

Unfortunately that is not possible - SA is not a database user and when we try to define it as one, we get the error 不幸的是,这是不可能的-SA不是数据库用户,并且当我们尝试将其定义为一个数据库时,会出现错误

Msg 15405, Level 16, State 1, Line 1
Cannot use the special principal 'sa'.

We then thought about using DBO and setting up cross-database ownership chaining, but this is all beginning to be a serious headache. 然后,我们考虑使用DBO并建立跨数据库所有权链接,但这一切都开始令人头疼。 Does anyone know of an elegant way to do this? 有人知道这样做的优雅方式吗?

This is perfectly possible with module signing . 使用模块签名完全可以做到这一点。

  • Create a procedure that executes the elevated code. 创建一个执行提升代码的过程。
  • Add EXECUTE AS CALLER to the procedure EXECUTE AS CALLER添加到过程
  • Create a certificate and private key 创建证书和私钥
  • Sign the procedure 签署程序
  • Drop the private key 删除私钥
  • Export the certificate 导出证书
  • Import the certificate in [master] 将证书导入到[master]
  • Create a login derived from the certificate 创建从证书派生的登录名
  • Grant the required privileges to the certificate derived login 授予证书派生登录名所需的特权

Note that any alteration to the procedure will invalidate the signature and will require to redo the procedure. 请注意,对过程的任何更改都会使签名无效,并需要重做该过程。 Dropping the private key is very important because otherwise the vendor can sign a different procedure and get the elevated permissions on arbitrary code. 删除私钥非常重要,因为否则供应商可以签署不同的过程并获得任意代码的提升权限。 See Signing an Activated Procedure for an example. 有关示例,请参见签署激活的过程

To manage things inside a database, you can use EXECUTE AS OWNER and make sure dbo owns the stored procedure. 要管理数据库中的内容,可以使用EXECUTE AS OWNER并确保dbo拥有存储过程。 No problems there 那里没问题

However, CREATE DATABASE etc requires server level permissions. 但是,CREATE DATABASE等需要服务器级别的权限。 Note: you don't need sysadmin permissions. 注意:您不需要sysadmin权限。

With SQL Server 2012 you can use server roles , and GRANT CREATE DATABASE to this server role. 使用SQL Server 2012,您可以使用服务器角色 ,并将GRANT CREATE DATABASE授予该服务器角色。 For earlier versions, you can grant this directly to the login. 对于早期版本,您可以将其直接授予登录名。 Or use dbcreator if your prefer. 或根据需要使用dbcreator

If you decide they need to manage logins however, securityadmin has the same effective permissions as sysadmin 但是,如果您决定他们需要管理登录名,则securityadmin具有与sysadmin相同的有效权限。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM