ユーザーがQA環境ですべてのDb接続を閉じることができるようにするストアドプロシージャを作成しました。私はSAで、プロシージャを作成しました。
SPを変更すると、「所有者として実行」なしで実行すると結果が表示されます。「所有者として実行」を追加すると、結果が表示されません。
理由を理解しようとしています。
create procedure [dbo].[DatabaseConnectionClose]
@DatabaseName varchar(255)
with execute as owner
as
DECLARE @kill varchar(8000) = '';
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'
FROM sys.dm_exec_sessions
WHERE database_id = db_id(@DatabaseName)
select @kill as CloseConnectionScript
EXEC(@kill);
EXECUTE AS
ステートメントのCREATE {module_type}
句の使用は偽装ですが、データベースレベルでのみです。所有者は "dbo"(この場合は少なくとも)ですが、それは単なるユーザーです。データベースレベルのプリンシパル。 KILL
コマンドには、インスタンスレベルの権限が必要です。デフォルトでは、データベースレベルの偽装(EXECUTE AS
句またはEXECUTE AS USER
ステートメント))を使用すると、プロセスは現在のプロセスに隔離されます。データベース、そのユーザーが適切な権限を持つログイン(同じSIDを持つ)にマップされている場合でもこの制限のため、プロセスはインスタンスレベルまでのアクセス権をチェックするためにインスタンスに到達することはできません。
これを正しく行うには:
EXECUTE AS
を取り除くモジュール署名を使用してこれを実装します。
誰にでも許可せずに安全かつ簡単に高レベルのアクセス許可を使用する:サーバーレベル (私のブログ投稿;外部ですが、より良い説明があります)
SQL Serverエージェントサービスのステータスを確認できるように、ユーザーに最低限必要なアクセス許可を提供する必要がありますか? (私の回答の1つ。ここではDBA.SEにあります)
証明書ベースのログインに付与する必要がある唯一の権限は、ALTER ANY CONNECTION
です(ドキュメントの [〜#〜] kill [〜#〜] のとおり)
モジュール署名の詳細については、次のWebサイトをご覧ください。 モジュール署名情報
また、質問に対するコメントでAaron Bertrandが述べた優れた点に加えて、SQL Serverエージェントなどの正当なプロセスのセッションを強制終了しないように注意する必要があります。少なくともprogram_name
sys.dm_exec_sessions
の列。ただし、そうでない場合はlogin_name
(および場合によってはその他)。
ただし、ALTER DATABASE [{db_name}] SET...
が続行する方法になる場合は、次の投稿をガイドとして使用してください。その場合、インスタンスレベルの権限は関係ありません。