Sql-Server

現有連接是否會立即兌現對 TRUSTWORTHY 設置的更改?

  • December 22, 2021

當您更改TRUSTWORTHY設置時,現有連接會立即接受此更改嗎?

我的經歷似乎表明現有的連接不會立即兌現更改,但這似乎不正確,所以我只想得到確認,這樣我就知道我在處理什麼。

不是在查詢期間。我的意思是,如果您在 SSMS 中打開會話並且設置發生更改,那麼您的下一個查詢會受到同一會話中的更改的影響嗎?

我不確定需要TRUSTWORTHY為特定程序打開哪個數據庫,所以我正在測試以查看。我在一個數據庫中關閉了它,它仍然執行良好。然後我在另一個數據庫中將其關閉,它仍然執行良好。然而,該過程稍後沒有為另一個使用者執行,所以我立即在兩個數據庫中重新打開它。我認為奇怪的是,在我開始在兩個數據庫中將其關閉後,該過程成功執行,因為我幾乎可以肯定,一個數據庫中的觸發器必須打開才能寫入另一個數據庫中的表D b。

我正在嘗試從 更改ONOFF

設置的更改TRUSTWORTHY確實很明顯,至少在查詢/語句之間,而會話仍處於活動狀態。從ONto的更改OFF不會影響正在執行的查詢(從OFFto的更改ON是無關緊要的,因為如果設置開始為並且這樣的條件產生錯誤,則查詢永遠不會開始OFF),即使它有一個OUTER APPLY將執行“外部" 表達式/對像多次。在再次檢查設置之前允許執行查詢完成。我已經測試了這兩種情況,下面是對第一種情況(更明顯和常見的情況)的測試。

測試

CREATE DATABASE [A];
ALTER DATABASE [A] SET RECOVERY SIMPLE, TRUSTWORTHY OFF;

CREATE DATABASE [B];
ALTER DATABASE [B] SET RECOVERY SIMPLE, TRUSTWORTHY OFF;

USE [B];
CREATE TABLE dbo.Stuffs(col1 INT);
INSERT INTO dbo.Stuffs([col1]) VALUES (1);

USE [A];
CREATE TABLE dbo.Here ([col1] INT);

GO
CREATE OR ALTER TRIGGER dbo.[tr_Here_Ins] ON dbo.[Here]
WITH EXECUTE AS N'dbo'
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
   INSERT INTO [B].dbo.[Stuffs] ([col1])
       SELECT [col1]
       FROM   inserted
END;
GO

CREATE USER [Testy] WITHOUT LOGIN;
GRANT INSERT ON dbo.[Here] TO [Testy];

EXECUTE AS USER = N'Testy';

INSERT INTO dbo.[Here] ([col1]) VALUES (1);
/*
Msg 916, Level 14, State 2, Procedure tr_Here_Ins, Line 7 [Batch Start Line XXXX]
The server principal "ALBRIGHT\Solomon" is not able to access the database "B"
under the current security context.
*/


-- In another tab/session:
-- ALTER DATABASE [A] SET TRUSTWORTHY ON;

INSERT INTO dbo.[Here] ([col1]) VALUES (2);
-- Success
SELECT SESSION_USER; -- Testy


-- In the other tab/session:
-- ALTER DATABASE [A] SET TRUSTWORTHY OFF;

INSERT INTO dbo.[Here] ([col1]) VALUES (3);
/*
Msg 916, Level 14, State 2, Procedure tr_Here_Ins, Line 7 [Batch Start Line XXXX]
The server principal "ALBRIGHT\Solomon" is not able to access the database "B"
under the current security context.
*/


REVERT;
SELECT SESSION_USER; -- dbo

SELECT * FROM [B].dbo.[Stuffs];

清理

USE [master];
DROP DATABASE [A];
DROP DATABASE [B];

關於需要TRUSTWORTHY設置哪個數據庫ON以避免某些權限錯誤:

  • Snarky(雖然也是理想的)答案:“無”,因為您應該使用模組簽名(請參閱我的網站,Module Singing Info,了解更多資訊)。見下文。
  • 直截了當的回答:只有請求來自的數據庫才需要TRUSTWORTHY啟用,如果TRUSTWORTHY必須使用的話。這與跨數據庫所有權連結不同,在跨數據庫所有權連結中,當沒有為實例上的所有數據庫啟用時,請求中涉及的所有數據庫都需要DB_CHAINING啟用。

關於理想(非TRUSTWORTHY基於)選項:

  1. 在包含觸發器的數據庫 (A) 中創建證書
  2. ALTER刪除WITH EXECUTE AS...子句的觸發器
  3. 使用ADD SIGNATURE對觸發器進行簽名
  4. 將證書(僅限公鑰)複製到觸發器正在寫入的數據庫 (B)
  5. 從證書中創建另一個數據庫 (B) 中的使用者
  6. 授予新的基於證書的使用者INSERT對正在寫入的表的權限
  7. ALTER使用觸發器禁用的數據庫 (A)TRUSTWORTHY

引用自:https://dba.stackexchange.com/questions/303906