跨数据库所有权不起作用

时间:2011-12-28 18:12:15

标签: sql security sql-server-2008 ownership

我读过一篇文章

http://www.sommarskog.se/grantperm.html#ownershipchaining

有关于SQL Server中所有权链接的非常好的信息。

这就是我在SQL Server 2008上所做的,

  1. 创建了2个数据库DatabaseA,DatabaseB with login sa
  2. 在DatabaseA中创建了一个程序'TestProc',它执行DatabaseB中的过程
  3. 创建了登录'testuser'
  4. 以DatabaseA中的用户身份添加此登录名,并授予执行'TestProc'程序
  5. 的权限

    正如您所看到的,我的目标是让'testuser'在DatabaseB中执行一个过程,而无需在DatabaseB中添加此用户,也无需授予他对DatabaseB中过程的直接执行权。

    我确实在服务器级别和两个数据库上启用了所有权链接。我重新启动了SQL Server服务。

    但仍然收到此错误

    Msg 916,Level 14,State 1,Procedure TestProc,Line 18 服务器主体“testuser”无法访问当前安全上下文下的数据库“DatabaseB”。

    我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:0)

所有权链接适用于数据库内的对象。它不允许您输入数据库本身。因此,您必须在您读取的任何数据库中创建登录名,例如:

use DatabaseB
exec sp_grantdbaccess 'testuser'

所有权链接确实授予存储过程权限。因此数据库登录可以没有任何权限。它必须存在。

创建两个测试数据库并在一个中调用过程的查询:

use master
if exists (select * from sys.databases where name = 'TestDatabase1')
    drop database TestDatabase1
if exists (select * from sys.databases where name = 'TestDatabase2')
    drop database TestDatabase2
create database TestDatabase1
go
use TestDatabase1
exec sp_changedbowner 'sa'
go
create procedure dbo.sp1 as select 'hello world!'
go
create database TestDatabase2
go
use TestDatabase2
exec sp_changedbowner 'sa'
go
create procedure dbo.sp2 as exec TestDatabase1.dbo.sp1
go
use TestDatabase2
exec sp_grantdbaccess 'testuser'
grant execute on sp2 to testuser as dbo
use TestDatabase1
-- Either of the below lines would work
-- exec sp_grantdbaccess 'guest'
-- exec sp_grantdbaccess 'testuser'
use TestDatabase2
execute as login = 'testuser'
exec sp2
revert -- Revert back to original login

查询以显示数据库和过程的所有权:

select  d.name
,       l.name
from    sys.databases d
join    sys.syslogins l
on      d.owner_sid = l.sid
where   d.name like '...your database...'

select  p.name
,       dp.name
from    TestDatabase.sys.procedures p
join    TestDatabase.sys.schemas s
on      s.schema_id = p.schema_id
join    TestDatabase.sys.database_principals dp
on      s.principal_id = dp.principal_id
where   p.name like '...your stored procedure...'