如何在特定用户的特定数据库上确定有效权限(查询)

时间:2014-10-16 09:27:53

标签: tsql select permissions sql-server-2012 roles

我想创建一个查询来读取数据库上用户的所有有效权限。这包括固定角色权限和授予用户的任何其他权限。是这样开始的,但现在我被卡住了:

- 固定数据库角色的权限不会出现在sys.database_permissions中。因此,数据库主体可能具有此处未列出的其他权限。

    SELECT * FROM   
    (
        SELECT 
            perm.permission_name AS 'PERMISSION'
            ,perm.state_desc AS 'RIGHT'    
            ,perm.class_desc AS 'RIGHT_ON'
            ,p.NAME AS 'GRANTEE'
            ,m.NAME AS 'USERNAME'
            ,s.name AS 'SCHEMA'
            ,o.name AS 'OBJECT'
            ,IIF(perm.class = 0, db_name(), NULL) AS 'DATABASE'
        FROM
            sys.database_permissions perm
        INNER JOIN sys.database_principals p ON p.principal_id = perm.grantee_principal_id
        LEFT JOIN sys.database_role_members rm ON rm.role_principal_id = p.principal_id
        LEFT JOIN sys.database_principals m ON rm.member_principal_id = m.principal_id
        LEFT JOIN sys.schemas s ON perm.class = 3 AND perm.major_id = s.schema_id
        LEFT JOIN sys.objects AS o ON perm.class = 1 AND perm.major_id = o.object_id
    UNION ALL
        SELECT 
            perm.permission_name AS 'PERMISSION'
            ,perm.state_desc AS 'RIGHT'
            ,perm.class_desc AS 'RIGHT_ON'
            ,'SELF-GRANTED' AS 'GRANTEE'
            ,p.NAME AS 'USERNAME'
            ,s.name AS 'SCHEMA'
            ,o.name AS 'OBJECT'
            ,IIF(perm.class = 0, db_name(), NULL) AS 'DATABASE'
        FROM
            sys.database_permissions perm
        INNER JOIN sys.database_principals p ON p.principal_id = perm.grantee_principal_id
        LEFT JOIN sys.schemas s ON perm.class = 3 AND perm.major_id = s.schema_id
        LEFT JOIN sys.objects AS o ON perm.class = 1 AND perm.major_id = o.object_id
    ) AS [union]
        WHERE [union].USERNAME = 'Username'
        ORDER BY [union].GRANTEE,[union].RIGHT_ON, [union].PERMISSION

任何想法?

1 个答案:

答案 0 :(得分:0)

仍缺少固定服务器角色权限

    SELECT * FROM   
    (
    SELECT 
    perm.permission_name AS 'PERMISSION'
    ,perm.state_desc AS 'RIGHT'
    ,perm.class_desc AS 'RIGHT_ON'
    ,p.NAME AS 'GRANTEE'
    ,m.NAME AS 'USERNAME'
    ,s.name AS 'SCHEMA'
    ,o.name AS 'OBJECT'
    ,IIF(perm.class = 0, db_name(), NULL) AS 'DATABASE'
    FROM
    sys.database_permissions perm
    INNER JOIN sys.database_principals p ON p.principal_id = perm.grantee_principal_id
    LEFT JOIN sys.database_role_members rm ON rm.role_principal_id = p.principal_id
    LEFT JOIN sys.database_principals m ON rm.member_principal_id = m.principal_id
    LEFT JOIN sys.schemas s ON perm.class = 3 AND perm.major_id = s.schema_id
    LEFT JOIN sys.objects AS o ON perm.class = 1 AND perm.major_id = o.object_id
    UNION ALL
    SELECT 
    perm.permission_name AS 'PERMISSION'
    ,perm.state_desc AS 'RIGHT'
    ,perm.class_desc AS 'RIGHT_ON'
    ,NULL AS 'GRANTEE'
    ,p.NAME AS 'USERNAME'
    ,s.name AS 'SCHEMA'
    ,o.name AS 'OBJECT'
    ,IIF(perm.class = 0, db_name(), NULL) AS 'DATABASE'
    FROM
    sys.database_permissions perm
    INNER JOIN sys.database_principals p ON p.principal_id = perm.grantee_principal_id
    LEFT JOIN sys.schemas s ON perm.class = 3 AND perm.major_id = s.schema_id
    LEFT JOIN sys.objects AS o ON perm.class = 1 AND perm.major_id = o.object_id
    UNION ALL
    SELECT 
    perm.permission_name AS 'PERMISSION'
    ,perm.state_desc AS 'RIGHT' 
    ,perm.class_desc AS 'RIGHT_ON' 
    ,roleprinc.[name] AS 'GRANTEE'
    ,'All' AS 'USERNAME'      
    ,s.name AS 'SCHEMA'
    ,OBJECT_NAME(perm.major_id) AS 'OBJECT'
    ,IIF(perm.class = 0, db_name(), NULL) AS 'DATABASE'
    FROM sys.database_principals roleprinc
    LEFT JOIN sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]  
    LEFT JOIN sys.schemas s ON perm.class = 3 AND perm.major_id = s.schema_id
    LEFT JOIN sys.objects AS o ON perm.class = 1 AND perm.major_id = o.object_id
    WHERE roleprinc.[type] = 'R' 
    AND roleprinc.[name] = 'public'
    UNION ALL
    SELECT 
    perm.permission_name AS 'PERMISSION'
    ,perm.state_desc AS 'RIGHT'
    ,perm.class_desc AS 'RIGHT_ON'
    ,p.TYPE_DESC collate DATABASE_DEFAULT AS 'GRANTEE'
    ,p.NAME AS 'USERNAME'
    ,null AS 'SCHEMA'
    ,null AS 'OBJECT'
    ,null AS 'DATABASE'
    FROM
    sys.server_permissions perm 
    INNER JOIN sys.server_principals p ON p.principal_id = perm.grantee_principal_id
    LEFT JOIN sys.server_role_members rm ON rm.role_principal_id = p.principal_id
    LEFT JOIN sys.server_principals m ON rm.member_principal_id = m.principal_id
    UNION ALL
    select  
    NULL AS 'PERMISSION'
    ,NULL AS 'RIGHT'
    ,'SERVER' AS 'RIGHT_ON'
    ,SUSER_NAME(rm.role_principal_id) AS 'GRANTEE'
    ,lgn.name AS 'USERNAME'
    ,null AS 'SCHEMA'
    ,null AS 'OBJECT'
    ,null AS 'DATABASE'
    FROM
    sys.server_principals r 
    INNER JOIN sys.server_role_members rm ON r.principal_id = rm.role_principal_id
    INNER JOIN sys.server_principals lgn ON rm.member_principal_id = lgn.principal_id
    ) AS [union]
    WHERE [union].USERNAME = 'ALL'
    OR [union].USERNAME = 'Username' -- Insert Username/login Name here (have to be username = loginname)
    ORDER BY [union].GRANTEE,[union].RIGHT_ON, [union].PERMISSION