我读过一篇文章
http://www.sommarskog.se/grantperm.html#ownershipchaining
有关于SQL Server中所有权链接的非常好的信息。
这就是我在SQL Server 2008上所做的,
正如您所看到的,我的目标是让'testuser'在DatabaseB中执行一个过程,而无需在DatabaseB中添加此用户,也无需授予他对DatabaseB中过程的直接执行权。
我确实在服务器级别和两个数据库上启用了所有权链接。我重新启动了SQL Server服务。
但仍然收到此错误
Msg 916,Level 14,State 1,Procedure TestProc,Line 18 服务器主体“testuser”无法访问当前安全上下文下的数据库“DatabaseB”。
我在这里错过了什么吗?
答案 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...'