【问题标题】:SQL Server 2008 R2 Cross Database Ownership Chaining Not working?SQL Server 2008 R2 跨数据库所有权链接不起作用?
【发布时间】:2011-05-08 03:31:23
【问题描述】:

我已将两个 SQL Server 2005 db(DB1 和 DB2)恢复到运行 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 db 中的函数将运行的上下文,因此它应该可以访问相同的用户和登录表。

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

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

【问题讨论】:

    标签: sql-server sql-server-2008 login


    【解决方案1】:

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

    但是您认为 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

    【讨论】:

    • 感谢您的帮助。我对安全问题感到满意,如果我首先构建了数据库,那么所有表都将在同一个数据库中。它们在功能上是分开的,但不应如此。
    • 跨数据库所有权链接已开启。 ALTER OWNER ON 语法不起作用我使用 Exec sp_changedbowner sa, false 但我仍然遇到同样的问题
    • 我也尝试将 WITH 'EXECUTE AS 'dbo'' 添加到 mp_SPTest。当我这样做时,我得到.....'服务器主体“sa”无法在当前安全上下文下访问数据库“DB2”'。这似乎很奇怪,因为 sa 是该数据库上的 dbo
    • 我已经通过将 WITH EXECUTE AS 'dbo' 添加到函数 mf_UserHasAccess 来实现此功能。仍然不明白为什么它不起作用
    • 我已经解决了我的问题的这个方面,但是我仍然遇到与同一件事相关的问题。我已经开始new question,因为我认为标题没有误导
    【解决方案2】:

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

    使用[目标数据库]

    将 SCHEMA::[TargetSchema] 的授权更改为 [SourceSchema]

    例如 使用 [DB1]

    将 SCHEMA::[mem] 的授权更改为 [dbo] 去吧

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 2012-02-18
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多