2016-06-24 3 views
4

SQL Server의 모든 사용자에게 sys.dm_db_index_usage_stats 뷰의 일부를 제공하려고합니다. 목표는 SQL Server 보안을 위반하지 않고 해당 정보를 제공하는 것입니다.공개 저장 프로 시저를 사용하여 sys.dm_db_index_usage_stats에 액세스

내가는 DB 전문가는 아니지만이 코드를 준비했습니다 : 나는 권한을

GRANT EXEC ON dbo.[LastTableUpdate] TO PUBLIC 

을 부여

CREATE PROCEDURE dbo.[LastTableUpdate] 
    @Table nvarchar(50) 
WITH EXECUTE AS OWNER 
AS 
SELECT 
    DB_NAME(database_id) as 'Database', 
    OBJECT_NAME(object_id) As TableName, 
    max(last_user_update) as user_update, 
    max(last_system_update) as system_update 
FROM sys.dm_db_index_usage_stats WHERe database_ID=DB_ID() AND object_id=OBJECT_ID(@Table) 
GROUP BY database_id, object_id 

다음을하지만 전화있을 때 그것은

Msg 15562, Level 16, State 1, Procedure LastTableUpdate, Line 5 
The module being executed is not trusted. Either the owner of the database of the module needs to be granted authenticate permission, or the module needs to be digitally signed. 
있어

나를 도울 수 있습니까? 어떻게해야합니까? 앞에서 언급했듯이 DB를 가능한 한 안전하게 유지하는 것이 목표입니다.

+0

왜 DMV 결과를 보는 것이 보안 문제입니까? – TheGameiswar

+0

사용자에게 VIEW SERVER STATE 권한을주지 않으려합니다. – azachert

답변

4

모듈 서명 (pimpin '과 달리)은 쉽습니다. 기본적으로, 당신은 :

  1. 해당 로그인에
  2. 권한을 부여
  3. 저장 프로 시저
  4. 에게

이익을 가입
  • 해당 인증서 기반의 로그인을 만들기 인증서
  • 만들기
    use master; 
    go 
    create login [foobar] with password = 'f00bar!23'; 
    go 
    CREATE PROCEDURE dbo.[LastTableUpdate] 
        @Table nvarchar(50) 
    AS 
    SELECT 
        DB_NAME(database_id) as 'Database', 
        OBJECT_NAME(object_id) As TableName, 
        max(last_user_update) as user_update, 
        max(last_system_update) as system_update 
    FROM sys.dm_db_index_usage_stats WHERe database_ID=DB_ID() AND object_id=OBJECT_ID(@Table) 
    GROUP BY database_id, object_id 
    go 
    grant execute on dbo.LastTableUpdate to public 
    go 
    EXEC sp_ms_marksystemobject 'LastTableUpdate' 
    go 
    create certificate [CodeSigningCertificate] 
        encryption by password = '[email protected]' 
        with expiry_date = '2099-01-01', 
        subject = 'Code Signing Cert' 
    go 
    create login [CodeSigningLogin] from certificate [CodeSigningCertificate] 
    grant view server state to [CodeSigningLogin]; 
    go 
    -- nothing up my sleeve 
    execute as login = 'foobar'; 
    exec dbo.LastTableUpdate 'n' 
    revert 
    
    -- doesn't work - login [foobar] doesn't have permissions 
    go 
    -- here's the magic 
    add signature to dbo.[LastTableUpdate] 
        by certificate [CodeSigningCertificate] 
        with password = '[email protected]'; 
    go 
    
    execute as login = 'foobar'; 
    exec dbo.LastTableUpdate 'n' 
    revert 
    
    -- works now! 
    

    참고 : 절차에서 EXECUTE AS OWNER 절을 꺼 냈습니다. 호출자가이 저장 프로 시저 실행의 컨텍스트에 대해서만 사용 권한을 갖게되므로 이제 필요하지 않습니다.

  • 관련 문제