web-dev-qa-db-ja.com

DDLトリガー許可エラー

user1user2という2人のユーザーがいます。

User1にはsysadmin権限があり、saを介してデータベースレベルのトリガーを作成しました。

現在、user2権限とdb-ddladminを持つdb_datareaderを介してテーブルを作成しようとしています。

エラーが発生します:

 'Msg 297, Level 16, State 1, Procedure TR_CaptureDBChanges, Line 35
The user does not have permission to perform this action.

コード:

CREATE  TRIGGER [TR_CaptureDBChanges]
ON DATABASE
FOR  CREATE_PROCEDURE, ALTER_PROCEDURE,DROP_PROCEDURE,CREATE_TABLE, ALTER_TABLE,DROP_TABLE,CREATE_TRIGGER,ALTER_TRIGGER,DROP_TRIGGER,CREATE_VIEW,ALTER_VIEW,DROP_VIEW,CREATE_FUNCTION, ALTER_FUNCTION,
         DROP_FUNCTION
BEGIN 
DECLARE @ed XML 
SET @ed = EVENTDATA() 
DECLARE    @ip VARCHAR(32) =   (SELECT client_net_address FROM sys.dm_exec_connections  WHERE session_id = @@SPID);

    INSERT INTO DBChangesLogs ( EventDate,DBName)VALUES(GetDate(),@ed.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)'))
END
3
KD29

おそらく問題は、testuserVIEW SERVER STATEサーバーレベルの権限がないことです。 sys.dm_exec_connections DMVにアクセスするには、その権限(DDLトリガーを持つデータベースのユーザーではなく、[master]データベースのログインに割り当てられている)が必要です。したがって、次のいずれかを実行する必要があります。

  1. GRANT the testuserログインVIEW SERVER STATEサーバーレベルの権限、または

  2. VIEW SERVER STATEサーバーレベルのアクセス許可が割り当てられた証明書ベースのログインを作成し、ADD SIGNATUREを使用してその証明書でDDLトリガーに署名します。この手順は、フォロワーの回答に記載されています。

    SQL Serverエージェントサービスの状態を確認できるように、ユーザーに最低限必要なアクセス許可を提供する必要がありますか?

セキュリティの観点からは、証明書ベースのログインを処理し、トリガーに署名するために少し余分な作業を行うことをお勧めします。このアプローチでは、実際のログイン/ユーザーに追加の権限は付与されず、DDLトリガーを起動させるアクションを実行するための適切なDDL権限を持つすべてのユーザーに適用されます。また、testuserは単なるテストケースであり、これらの権限は最終的なシステムでより広く適用する必要があると想定すると、これらすべてのユーザーにVIEW SERVER STATEを付与したくない場合があります。役割にも。

これらと同じように、所有権チェーンはINSERTに対するDBChangesLogs権限を処理するため、ユーザーに明示的に権限を付与する必要がないと考えました。そうでない場合は、このアクセス許可を1人以上のユーザーに付与するのではなく、またはアクセス権を付与するユーザーをdb_datawriterロールに追加するよりも確かに優れています(そしてINSERTだけではありません)すべてのテーブルに対して-このトリガーにDBChangesLogsテーブルに挿入する機能を許可するには、他の回答ですでに概説されているものを超えて、2つの追加の簡単な手順を実行するだけです。

  1. (上記の「最低限のアクセス許可...」の回答で概説されている手順から始めます。最後の部分は、DDLトリガーが存在するデータベースに証明書を作成することです)
  2. 前の手順で作成した証明書ベースのログインからユーザーを作成します(または、このデータベースにも含まれている同じ証明書から作成します。作成したユーザーはどちらの場合も同じです)
  3. GRANTこのユーザーINSERTテーブルに対するDBChangesLogs権限
CREATE USER [MrDoStuff] FROM LOGIN [MrDoStuff];
GRANT INSERT ON dbo.DBChangesLogs TO [MrDoStuff];

PS:@ip変数を宣言して設定します。この許可の問題が解決したら、あなたはそれを使用すると思いますか?

1
Solomon Rutzky

SELECTステートメントはsys.dm_exec_connections上にあり、VIEW SERVER STATE権限が必要です。

したがって、権限を付与するには、次のコマンドを実行します。

USE MASTER
GO
GRANT VIEW SERVER STATE TO user2;
GO

次は、トリガーのINSERTステートメントです。ログインuser2には、DATABASEテーブルに書き込むテーブルを作成しているDBChangesLogsに対するdb_datawriter権限が必要です。

sp_addrolememberを使用して、読み取りと書き込みを許可できます。

USE [DATABASE_NAME]
GO
EXEC sp_addrolemember N'db_datareader', N'user2'
GO
USE [DATABASE_NAME]
GO
EXEC sp_addrolemember N'db_datawriter', N'user2'
GO

最後に、トリガーの作成に使用しているコードには、BEGINの前に「AS」がありません。

1
sql_handle