web-dev-qa-db-ja.com

ユーザーがアクセスできるテーブルとビューを見つける方法は?

SQL Server 2008データベースがあり、すべてのテーブルとビューを特定のユーザーIDから遠ざけるように制限しています。長年にわたり、ユーザーのニーズに基づいて一度に1つずつバックテーブルとビューを許可してきました。

ベンダーがpublicロールへの読み取り/書き込みアクセス権をデフォルトで提供しているため、この方法で行う必要があり、このユーザーのロールを作成し、すべてのアクセス権を削除して、必要なものだけを付与する必要がありました。 。

今日は、これらのテーブルとビューのみを含むレプリケートされたデータベースを作成し、ユーザーが本番システムを劣化させることなくレポートを実行できるようにします。問題は、このユーザーがアクセスできるテーブルとビューがわからないことです。何年にもわたって、一度に1つずつアクセスを許可している人が多いためです。

このユーザーのアクセスを確認するクエリはありますか?

PS Imはアプリ開発者なので、必要に応じてこれを初級として自由に説明してください。


編集-ロールとアクセスが最初に作成された方法


------------------------------
-- CREATE ROLE db_finrep_deny
------------------------------

DECLARE @RoleName sysname
set @RoleName = N'db_finrep_deny'
IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = @RoleName AND type = 'R')
Begin
    DECLARE @RoleMemberName sysname
    DECLARE Member_Cursor CURSOR FOR
    select [name]
    from sys.database_principals 
    where principal_id in ( 
        select member_principal_id 
        from sys.database_role_members 
        where role_principal_id in (
            select principal_id
            FROM sys.database_principals where [name] = @RoleName  AND type = 'R' ))

    OPEN Member_Cursor;

    FETCH NEXT FROM Member_Cursor
    into @RoleMemberName

    WHILE @@FETCH_STATUS = 0
    BEGIN

        exec sp_droprolemember @rolename=@RoleName, @membername= @RoleMemberName

        FETCH NEXT FROM Member_Cursor
        into @RoleMemberName
    END;

    CLOSE Member_Cursor;
    DEALLOCATE Member_Cursor;
End
GO
-- dropping the role itself
IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = N'db_finrep_deny' AND type = 'R')
DROP ROLE [db_finrep_deny]
GO


------------------------------
-- Grant access (read/write/select/upd) to only select tables
------------------------------
CREATE ROLE [db_finrep_deny]
AUTHORIZATION [dbo]
GO
exec sp_addrolemember 'db_finrep_deny', 'finrep'
GO

-- run the dynamic sql generated by this statement
select  'DENY SELECT, INSERT, UPDATE, DELETE ON '
        + ss.name
        + '.'
        + st.name
        + ' TO db_finrep_deny;'
from sys.tables st
inner join sys.schemas ss on st.schema_id=ss.schema_id
where st.name not in ('TABLE1','TABLE2','TABLE3','TABLE4')
order by ss.name, st.name;

grant select on dbo.vwFINMASTER to db_finrep_deny;

Aaron-これは、クエリを実行すると表示されるもので、ビューのみが表示され、テーブルは表示されません


(No column name)    name    permission_name
dbo     dtproperties    REFERENCES
dbo     vwFINMASTER     SELECT
dbo     vwLEDGERVIEW    SELECT
4

関数fn_my_permissionsを使用してユーザーになりすまし、ユーザーがアクセスできるオブジェクトを確認できます。タイプをプロシージャやさまざまなタイプの関数に拡張したい場合があります...

 USE Your_Database;
 GO
 EXECUTE AS USER = N'the_user_name';
 GO
 SELECT 
    s.name,
    o.name,
    p.[permission_name]
 FROM sys.objects AS o 
 INNER JOIN sys.schemas AS s
 ON o.[schema_id] = s.[schema_id]
 CROSS APPLY sys.fn_my_permissions(QUOTENAME(s.name) 
   + N'.' + QUOTENAME(o.name), N'OBJECT') AS p
   WHERE o.[type] IN (N'U', N'V') -- tables and views
   AND p.subentity_name = N''; -- ignore column permissions 
 GO
 REVERT;

互換レベル100以上でのみテストされています。古い互換モードでは、少し異なる方法で構造化する必要がある場合があります(最初の例 ここ を参照)。

実際のロールには、承認を通じてテーブルへのimplicitのアクセス権が多数付与されているので、おそらく以下を試してください:

-- all the tables and views in the system
SELECT 
  schemaName = s.name,  
  objectName = o.name, 
  o.[object_id] 
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
  ON o.[schema_id] = s.[schema_id]
WHERE type IN (N'U',N'V')
AND NOT EXISTS
(
  -- except those that have been *explicitly* denied
  SELECT 1
  FROM sys.database_permissions AS p
  WHERE p.class = 1
  AND p.state_desc = N'DENY'
  AND p.major_id = o.[object_id]
  AND p.grantee_principal_id IN (USER_ID(N'db_finrep_deny'),USER_ID(N'finrep'))
);
5
Aaron Bertrand