代码之家  ›  专栏  ›  技术社区  ›  Jason

如何查询特定用户访问权限

  •  4
  • Jason  · 技术社区  · 16 年前

    我继承了一个旧数据库。访问权限在任何地方都没有明确定义,我正在寻找一种快速的方法来为每个人获取它们。假设我的数据库中有一个不属于任何成员角色的用户。但是,它们被授予对特定表执行特定操作的权限。例如,他们可以在表X上运行select查询,在表Y上运行update查询。我知道我可以通过访问每个用户的属性来了解他们有什么。不过,我可以想象,在某个地方,必须有一个系统表,其中定义了所有这些内容,并使其易于查询。这个查询是什么样子的?

    仅供参考:我正在使用SQL Server 2005

    更新:是否还有一种方法可以为服务器上的所有数据库执行此操作?

    2 回复  |  直到 16 年前
        1
  •  5
  •   doza    16 年前

    看看 Security Catalog Views 然后看看丹尼先生的答案 here 它提供一个查询来列出用户的权限。我在这里复制(整理到我喜欢的程度)。

    SELECT  [Schema]            =   sys.schemas.name 
    ,       [Object]            =   sys.objects.name 
    ,       username            =   sys.database_principals.name 
    ,       permissions_type    =   sys.database_permissions.type 
    ,       permission_name     =   sys.database_permissions.permission_name
    ,       permission_state    =   sys.database_permissions.state 
    ,       state_desc          =   sys.database_permissions.state_desc
    ,       permissionsql       =   state_desc + ' ' + permission_name 
                                     + ' on ['+ sys.schemas.name + '].[' + sys.objects.name 
                                     + '] to [' + sys.database_principals.name + ']' 
                                      COLLATE LATIN1_General_CI_AS 
    FROM sys.database_permissions 
     INNER JOIN sys.objects ON sys.database_permissions.major_id =      sys.objects.object_id 
     INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id 
     INNER JOIN sys.database_principals ON sys.database_permissions.grantee_principal_id =  sys.database_principals.principal_id 
    ORDER BY 1, 2, 3, 5
    
        2
  •  3
  •   Remus Rusanu    16 年前

    实际上情况有点棘手。有效权限是内部数据库权限的组合(可查询,如上面Doza所示的Denny的查询) Windows组成员身份。不幸的是,它存储在SQL之外的AD模式中,所以您不能真正地查询它。

    因此,如果您的目标是显示“向域\someuser和域\somegroup授予对表x的访问权限,并拒绝向域\someothergroup授予访问权限”,那么您可以使用目录元数据并进行查询,如Doza的文章所示。

    但是,如果您的目标是回答“用户域\某人有权访问表X吗?”您无法从上面的查询中获得答案。没错,尽管你看到一条记录说域\someuser被授予访问权,你 不能 回答是否有效访问。记住,单个拒绝胜过所有授予,如果域\用户是域\其他组的成员,则域\其他用户有效 否认 访问。

    要回答后面的问题,必须使用不同的机制,即必须在SQL级别模拟用户并通过 HAS_PERM_BY_NAME :

    EXECUTE AS USER = 'domain\someuser';
    SELECT HAS_PERMS_BY_NAME('X','TABLE','SELECT');
    REVERT;
    

    值得注意的是,第一个问题可以由对安全目录具有查看权限的任何人回答,而后面的问题则需要模拟权限,这是一个更强大的权限。