web-dev-qa-db-ja.com

ユーザー監査のためのシステムビューのトリガーの代替

タイトルを書いても、これを試してみたアイデアに夢中です(しかし、ちょっと、その過程で何かを学びました)。

開発者がデータベースで移行スクリプトを実行し、その過程でデータベースに既に存在するストアドプロシージャを上書きするという問題があります(DEV、thank a deity )。

ただし、次の理由により、これらの変更を誰が行ったかを知る方法はありません。

  1. 彼らはそれを認めない
  2. 誰もがdboとして接続しているため、SQL Serverはprincipal_idシステムビューのsys.objects列に値を入力しません( 詳細はこちら )。

だから、私はsys.objectsにトリガーを書いてみましたが、エラーが発生したため、うまくいきませんでした(なぜ私が予期していたのかわかりません)。

オブジェクト「DEV_DB.sys.objects」は存在しないか、この操作には無効です。

また、開発者ごとにユーザーを作成して、自動移行を行ったときにユーザーが使用するようにしました。うまくいけば、その開発者がsys.objectsに行ったすべての変更は、ユーザーとしてログに記録されます。でログインしました。

ただし、principal_idがまだ入力されていないため、これも機能しませんでした(私が行ったのは、各開発者とDBに新しいログイン/ユーザーを作成し、ログインを与えることでした- 特定のサーバーの役割publicdb_datawriterdb_datareaderdb_ddladmin)。

他に何を試すことができるかについての提案はありますか?

5
Radu Gheorghiu

デフォルトのトレースをいつでもタップして、ストアドプロシージャを含むオブジェクトへの変更をキャッチできます。

次のスクリプトを試してみてください。誰が何をいつ変更したかを見つけるのは簡単です。それは私が複数のずるい開発者を見つけるのを助けました;)

SELECT  t.DatabaseName, t.ObjectID,t.NTUserName,t.HostName,t.StartTime, te.name
FROM ::fn_trace_gettable('C:\Program Files\Microsoft SQL 
Server\MSSQL13.SQL2016\MSSQL\Log\log.trc', DEFAULT) t  
JOIN sys.trace_events te  on t.EventClass = te.trace_event_id  
ORDER BY t.StartTime DESC;

SQLトレースファイルが実行されている場所を見つけるには、SQLトレースファイルがどこにあるかにパスを変更する必要があります。

select path 
from sys.traces
where id = 1

ヒント:ファイル名から_numberを削除して、使用可能なすべてのトレースファイルを読み取ります。ファイル名がlog_16.trcの場合は、log.trcに変更します。

5
David Fowler

開発者が個別にログインしている場合は、DDLトリガーを検討してください。 CREATE_PROCEDUREALTER_PROCEDUREDROP_PROCEDUREイベントの例を以下に示します。

USE YourDatabase;
GO

CREATE TRIGGER trgStoredProcDDL
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE
AS
BEGIN
    --Get relevant info from EVENTDATA()
    DECLARE @Login SYSNAME= EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]', 'SYSNAME');
    DECLARE @DBUser SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/UserName)[1]', 'SYSNAME');
    DECLARE @Schema SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]', 'SYSNAME');
    DECLARE @Proc SYSNAME = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'SYSNAME');

    --Optional: error message for end user.
    RAISERROR ('Please stop!', 16, 1);

    --Optional: Rollback transaction that fired the DDL trigger
    ROLLBACK;

    --Optional: log some data to a table.
    BEGIN TRAN
        INSERT INTO guest.LogTable(LogMsg, LogDate, [Login], [User])
        VALUES('Stored Proc was created/altered/dropped: [' + @Schema + '].[' + @Proc+ ']', 
            CURRENT_TIMESTAMP,
            @Login,
            @DBUser);
    COMMIT

    --Optional: send an email/alert.
    DECLARE @Subj NVARCHAR(255) 
    SET @Subj = @@SERVERNAME + ' - Stored Proc created/altered/dropped'
    EXEC msdb..sp_send_dbmail
        @recipients = '[email protected]', 
        @subject = @Subj,
        @body = 'Your message...'
END;

DDLトリガーを使用したイベントの処理に関するブログ投稿をいくつか説明します。 SQL Serverイベント処理:DDLイベント

2
Dave Mason