MSSQLSERVER_15517
適用対象: SQL サーバー
詳細
属性 | Value |
---|---|
製品名 | SQL Server |
イベント ID | 15517 |
イベント ソース | MSSQLSERVER |
コンポーネント | SQLEngine |
シンボル名 | SEC_CANNOTEXECUTEASUSER |
メッセージ テキスト | プリンシパル "principal" が存在しない、この種類のプリンシパルを偽装できない、またはアクセス許可がないため、データベース プリンシパルとして実行できません。 |
説明
このエラーは通常、 EXECUTE AS
ステートメントを使用して、ユーザー ステートメントまたはモジュールで指定されたプリンシパルの実行コンテキストに関する情報を Microsoft SQL Server が取得できないために発生します。
SQL Server インスタンス上にデータベースを作成すると、ログイン情報セキュリティ識別子 (SID) は、sys.databases
テーブルの対応するデータベース行のデータベース所有者として、およびデータベース内のsys.database_principals
テーブルのdbo
ユーザー項目に対して自動的に保存されます。
dbo ユーザー用に格納されている SID エントリが有効な場合、 EXECUTE AS OWNER
句を使用するステートメントまたはモジュールは期待どおりに動作します。
Note
この問題は、 EXECUTE AS
ステートメントで使用され、データベースの復元先サーバーに存在しないプリンシパルで発生する可能性があります。
この問題が発生する可能性がある一般的なシナリオをいくつか次に示します。
バックアップが最初に作成されたのと同じサーバー インスタンスにデータベースを復元しますが、データベースを作成した SQL Server プリンシパルは何らかの理由で無効になりました。 次に例を示します。
- SQL Server 認証ログインが削除されました。
- 従業員が退職したため、Windows 認証 ログインは Active Directory の有効なユーザーに対して行われません。
バックアップが最初に作成されたインスタンスとは異なるサーバー上のデータベースを復元しますが、データベースを作成した SQL Server プリンシパルは、新しいサーバー上の有効なプリンシパルではありません。
- ユーザーが SQL Server ログインの場合、プリンシパルはターゲット サーバーまたは移行先サーバーに存在する可能性がありますが、
sid
値は異なります。 - ユーザーが Windows ログインの場合、ターゲット サーバーに Windows ログインが存在しないか、無効になります。
- ユーザーが SQL Server ログインの場合、プリンシパルはターゲット サーバーまたは移行先サーバーに存在する可能性がありますが、
ストアド プロシージャ、関数、またはトリガーを実行しているユーザーまたはアプリケーションには、 EXECUTE AS
ステートメントで指定されたプリンシパルを偽装するために必要なアクセス許可がありません。
ユーザー アクション
既存のプリンシパルの名前を使用するか、そのプリンシパルに対する IMPERSONATE 権限を必要なユーザーに付与します。
無効な dbo ユーザー エラーが原因で発生する問題を解決するには、次のコマンドを実行して、 dbo_User
の値をサーバー上の有効なログインに変更します。
ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]
サンプル シナリオ
2 つの一時プリンシパルを作成します。
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
これらのログインを sysadmin ロールに追加します (デモンストレーションのみ)。
login1
を使用して SQL Server インスタンスにログインします。次のスクリプトを実行して、
testexec
という名前のデモ データベースとストアド プロシージャを作成します。CREATE DATABASE Demodb_15517 GO USE Demodb_15517 GO CREATE procedure [dbo].[testexec] WITH EXECUTE AS owner AS SELECT @@VERSION GO EXEC dbo.testexec GO
次のクエリを実行し、
sid
値が有効なログインに解決されているかどうかを確認します。クエリ 1: sys.databases の
Owner_Name
値の値を確認します。SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName FROM sys.databases WHERE NAME = N'Demodb_15517';
Database_Name owner_sid OwnerName --------------------- -------------------------------------- ---------------------------- Demodb_15517 0xDB79ED7B6731CF4E8DC7DF02871E3E36 login1
クエリ 2: デモンストレーション データベース内の
sys.database_principals
テーブルのOwner_Name
値を確認します。SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name SID ------------- ------------------------------------------------ login1 0xDB79ED7B6731CF4E8DC7DF02871E3E36
次のスクリプトのようなクエリを使用して、デモ データベースをバックアップします。
BACKUP DATABASE [Demodb_15517] TO DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH NOFORMAT, NOINIT, NAME = N'Demodb_15517 Full backup', SKIP, EWIND, NOUNLOAD, STATS = 10 GO
デモ データベースを削除し、
login1
します。DROP DATABASE demodb_15517 GO DROP login login1 GO
login2
として SQL Server にログインします。次のスクリプトのようなステートメントを使用して、バックアップからデモ データベースを復元します。
USE [master] RESTORE DATABASE [Demodb_15517] FROM DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH FILE = 1, MOVE N'Demodb_15517' TO N'C:\SQLBackups\Demodb_15517.mdf', MOVE N'Demodb_15517_log' TO N'C:\SQLBackups\\Demodb_155172_log.ldf', NOUNLOAD, STATS = 5 GO
クエリ 1 とクエリ 2 を再実行します。
クエリ 1 で、
sys.databases
のOwner_Name
値の値を確認します。 値にlogin2
が反映されるようになりました。SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName FROM sys.databases WHERE NAME = N'Demodb_15517';
Database_Name owner_sid OwnerName -------------- --------------------------------------- --------------------- Demodb_15517 0xD63086DD7277BC4EB88013D359AF73A6 login2
クエリ 2 で、デモンストレーション データベース内の
sys.database_principals
テーブルのOwner_Name
値の値を確認します。 値にNULL
が反映されるようになりました。SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name sid ------------------ ----------------------------------------------- NULL 0xDB79ED7B6731CF4E8DC7DF02871E3E36
testexec
ストアド プロシージャを実行します。 "15517" というエラー メッセージが表示されます。USE Demodb_15517 GO EXEC dbo.testexec GO
Msg 15517, Level 16, State 1, Procedure dbo.testexec, Line 0 [Batch Start Line 19] Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
エラーを解決するには、次のコマンドを使用して、dbo を有効なユーザー (
login2
) に変更します。ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]
クエリ 2 を再実行し、dbo ユーザーが login2 ユーザーに解決されたことを確認します。
Owner_Name SID ---------------------------------------------------------------- login2 0xD63086DD7277BC4EB88013D359AF73A6
もう一度試して、テスト ストアド プロシージャを実行します。 正常に実行されていることに注意してください。
USE Demodb_15517 GO EXEC dbo.testexec GO
/* -- You get an output that resembles the following --------------------------------------------------------------------------------------------------------- Microsoft SQL Server 2019 (RTM-CU16-GDR) (KB5014353) - 15.0.4236.7 (X64) May 29 2022 15:55:47 Copyright (C) 2019 Microsoft Corporation Express Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 22621: ) (Hypervisor) */