設置 TRUSTWORTHY On 使服務代理停止工作
我有一個在 SQL-Server 2012 DBMS 上執行的數據庫。考慮執行 SQL Server 的伺服器不是網路域的一部分。當我執行這個 sql 命令時
ALTER DATABASE myDatabase SET TRUSTWORTHY ON;
服務代理隊列(早期設置和工作)接收消息,但與隊列關聯的活動儲存過程未啟動。消息繼續流入隊列,但沒有其他任何事情發生。在 SQL SERVER 日誌中,我發現了這條消息
在隊列“proofSCHEMA.myQueue”上執行的啟動過程“proofSchema.mySP”輸出以下內容:“主數據庫中記錄的數據庫所有者 SID 與數據庫“myDatabase”中記錄的數據庫所有者 SID 不同。您應該通過使用 ALTER AUTHORIZATION 語句重置數據庫“myDatabase”的所有者來糾正這種情況。
如果我在網路域內的機器上執行相同的配置,一切正常。
我不明白髮生了什麼以及為什麼值得信賴的服務代理隊列迷戀。
在每個數據庫中都存在一個
dbo
使用者。這個User(Database-level)總是存在的,但是它映射到的SID(Security IDentifier)並不總是一樣的;它將映射到在創建數據庫時指定的任何登錄名(實例級別),或者在更改為具有新的“數據庫所有者”時。dbo
使用者是 中的條目之一sys.database_principals
。在最初設置Database Owner時
CREATE DATABASE
,或以後更改時,“所有者”的SID不僅放入sys.database_principals
,而且記錄在master.sys.databases
。如果數據庫從不離開創建它的實例,則 和 中的 SID 值之間不應該不sys.database_principals
匹配master.sys.databases
。但是,如果數據庫曾經恢復或附加到(或從)另一個實例,那麼 SID 值可能不匹配。您可以使用以下查詢檢查這兩個地方的值:USE [tempdb]; -- Change to whatever DB you want to check SELECT msd.owner_sid, msp.[name] FROM [master].[sys].[databases] msd INNER JOIN [master].[sys].[server_principals] msp ON msp.[sid] = msd.[owner_sid] WHERE msd.[database_id] = DB_ID(); SELECT sdp.[sid] FROM [sys].[database_principals] sdp WHERE sdp.[name] = N'dbo';
現在,預設情況下,涉及 Impersonation (ie) 的操作的權限
TRUSTWORTHY
設置為僅限於執行操作的數據庫。在模擬數據庫使用者,嘗試訪問另一個數據庫(甚至伺服器/實例級資源,我相信)時,SQL Server 將假定目前數據庫使用者的 SID(即被模擬的 SID)具有匹配的登錄名,因此它可以採取在這些權限上。這在 is 時被阻止,但將其設置為解除數據庫級隔離並允許模擬擴展到初始數據庫之外。使用者的 SID可能作為登錄名存在,但如果它與映射為數據庫所有者的 SID 不同OFF``EXECUTE AS``TRUSTWORTHY``OFF``ON``dbo``sys.databases
,那麼這清楚地表明某些事情是不正確的(並且很可能該數據庫來自另一個實例),並且在請求的操作中可能存在惡意意圖。