SQL Server 2008 R2跨数据库所有权链接不起作用?

问题描述:

我已将两个SQL Server 2005数据库(DB1 & DB2)还原到运行SQL Server 2008 R2的新框。SQL Server 2008 R2跨数据库所有权链接不起作用?

所有对象都被DBO

我有一个存储过程DB1.dbo.mp_SPTest拥有。我已授予SQLUser1的执行权限。

CREATE PROCEDURE mp_SPTest 
AS 
SELECT DB2.dbo.mf_UserHasAccess("BasicUser", "bob") 

mp_SPTest调用DB2 DB2.dbo.mf_UserHasAccess()标量函数,这个函数检查传递的用户名是一个SQL角色的成员.....

CREATE FUNCTION [dbo].[mf_UserHasAccess] (@RoleName varchar(50), @UserName varchar(128)) 
RETURNS bit 
AS 
BEGIN 
    DECLARE @Result bit 

    SELECT @Result = 1 
    WHERE @RoleName IN (
    SELECT CASE 
     WHEN (usg.uid is null) THEN 'public' 
     ELSE usg.name 
     END AS RoleName 
    FROM dbo.sysusers usu 
    LEFT OUTER JOIN (dbo.sysmembers mem 
     INNER JOIN dbo.sysusers usg 
     ON mem.groupuid = usg.uid) 
    ON usu.uid = mem.memberuid 
    LEFT OUTER JOIN master.dbo.syslogins lo 
    ON usu.sid = lo.sid 
    WHERE 
     (usu.islogin = 1 AND usu.isaliased = 0 AND usu.hasdbaccess = 1) 
    AND (usg.issqlrole = 1 OR usg.uid is NULL) 
    AND usu.name = @UserName) 

    IF @Result <> 1 
    BEGIN 
     SET @Result = 0 
    END 

    RETURN @Result 
END 

当我运行这个程序称为“SQLUser1 “它告诉我,bob不是BasicUser的成员,但是当我将它运行为”sa“时,它告诉我他是一个成员。

据我所知......因为程序和函数都属于dbo,所以test2数据库中的函数将运行的上下文,因此它应该可以访问相同的用户和登录表。

这在SQL Server 2005上运行良好,无法弄清楚。

希望这是有道理的,在此先感谢。

很可能旧的SQL Server 2005启用cross db ownership chaining选项,而新的SQL Server 2008 R2实例将该选项保留为其默认值(off)。

但是,您认为DB1中的'dbo'等同于DB2中的'dbo'是错误的。 DB1中的'dbo'是与sys.databases中的DB1的owner_sid对应的登录名。 DB2中的'dbo'同样也是对应于DB2的sys.databases中的onwer_sid的登录名。如果两个登录名不同(如果两个数据库的owner_sid不同),则DB1的很可能'dbo'将映射到某个其他用户,并且所有权链中断,即使启用跨数据库。运行ALTER AUTHORIZATION ON DATABASE::[DB..] TO [sa]会解决这个问题(即它会强制owner_sid匹配)。

最后,你在做什么根本上是有缺陷的,因为它依赖于激活数据库间的所有权链接,这是一个巨大的安全漏洞,请参阅Potential Threats。很多better avenue is to use code signing

+0

感谢您的帮助。我对安全问题感到满意,如果我已经在第一个地方建立了数据库,那么所有表都将在同一个数据库中。它们在功能上是分离的,但不应该是。 – NoseBagUK 2011-05-09 09:09:23

+0

交叉数据库所有权链接已打开。 'ALTER OWNER ON'语法不起作用我用'Exec sp_changedbowner sa,false',但是我仍然遇到同样的问题 – NoseBagUK 2011-05-09 09:16:43

+0

我也尝试向mp_SPTest添加WITH'EXECUTE AS'dbo''。当我这样做时,我得到.....'服务器主体“sa”无法在当前安全上下文下访问数据库“DB2”。这似乎很奇怪,因为SA是该数据库上的dbo – NoseBagUK 2011-05-09 10:08:06

我解决了这个相同的问题,使架构的视图或过程运行在它需要访问的数据库架构的所有者之下。

USE [TargetDB]

ALTER AUTHORIZATION ON SCHEMA :: [TargetSchema]至[SourceSchema]

例如 USE [DB1]

ALTER AUTHORIZATION ON SCHEMA :: [MEM] TO [dbo] GO

允许视图以DB2.DBO.view的形式运行,假设链接已打开,以访问DB1.mem.table中的表。本质上,跨数据库链接会导致它访问目标数据库作为视图所在的模式,而不是拥有数据库的用户。