MSSQL CLR 拒絕訪問路徑“c:somepath”
我認為這是一個權限問題,但我無法找到它。
我在一台伺服器(SQL Server 2016)上有一組 CLR,它們可以正常工作。所有這些都標記為 UNSAFE,並且它們執行各種類型的文件 I/O(讀取、寫入、複製、移動、重命名等)。我可以通過 SSMS 或從工作中同樣輕鬆地執行它們。
我需要將它們安裝在另一台伺服器(也是 SQL Server 2016)上。使用原始的 Visual Studio 項目,我已將它們部署到新伺服器。它們出現在 SSMS 中。那部分看起來不錯。
當我從 SSMS 嘗試執行一個時,我收到以下錯誤:“訪問路徑’無論我傳入什麼路徑’都被拒絕。”
我在 Windows 登錄下登錄到 SSMS。我對數據庫有權限,我是 dbo。我是伺服器的管理員。我在文件系統中有權限。
我還能錯過什麼?
我對數據庫有權限,我是 dbo。我是伺服器的管理員。我在文件系統中有權限。
通常,這些都不重要。除非您(或編寫 SQLCLR 方法的任何人)實現了模擬,否則用於外部操作的安全上下文是執行 SQL Server 的服務帳戶的安全上下文(類似於
xp_cmdshell
行為)。正是該帳戶需要您嘗試訪問的路徑的權限。為了完整起見文件訪問權限:
對於本地(在盒子上)訪問,它很簡單
需要權限的數據庫引擎(即 MSSQLSERVER 或 MSSQL$InstanceName)服務的服務帳戶(預設行為),或
如果在程式碼中實現了模擬
- 並且執行程式碼的登錄名是 Windows 登錄名,而不是 SQL Server 登錄名,那麼需要權限的是那個Windows 帳戶
- 但是正在使用 SQL Server 登錄,外部訪問仍然作為數據庫引擎服務帳戶完成
對於遠端訪問(共享驅動器),可能需要設置約束委派(通過 Active Directory;包括 SPN)。好的’ol Kerberos 雙跳問題。在這種情況下,您會發現從另一台電腦(而不是執行它的伺服器)登錄到 SQL Server 與直接登錄到執行 SQL Server 的伺服器然後連接到本地 SQL Server 實例之間的區別。
請記住,“DENY”優先於“GRANT”(就像 SQL Server 權限一樣)。
為了確定用於外部訪問的帳戶是否實際上具有對文件夾和/或文件的必要權限:
- 轉到相關路徑的“屬性”(報告錯誤的特定文件或文件夾)
- 轉到“安全”選項卡
- 點擊“高級”按鈕
- 轉到“有效訪問”選項卡
- 點擊“選擇使用者”連結
- 輸入完整的帳戶名稱(例如
NT Service\MSSQLSERVER
)- 點擊“確定”按鈕
- 點擊“查看有效訪問”按鈕
- 該帳戶是否有權訪問該資源?
您嘗試訪問的路徑中的任何位置是否有任何 DENY 權限?
此外,如果所有程式碼都是文件系統的東西,那麼很可能您不需要將程序集標記為
UNSAFE
,而應該是EXTERNAL_ACCESS
. 不需要太多的文件系統操作UNSAFE
。其中之一是獲取固定驅動器的列表,但不確定還有什麼。