我需要向使用者提供哪些最低權限才能檢查 SQL Server 代理服務的狀態?
我創建了一個使用者並為其授予了許多權限和角色,包括
SQLAgentUserRole
和SQLAgentReaderRole
.我的應用程序檢查 SQL Server Agent 的狀態以查看它是否正在執行,並且每當我嘗試使用我創建的使用者執行我的應用程序時,它都無法辨識Running SQL Server Agent。
當我使用
sysadmin
角色中的使用者做同樣的事情時,它工作正常。我們
master..xp_servicecontrol
用來檢查 SQL 代理服務的狀態,我已經向使用者提供了GRANT EXECUTE ON SYS.XP_PROP_OLEDB_PROVIDER TO User;
仍然無法正常工作。有什麼幫助嗎?
我需要向使用者提供哪些最低權限才能檢查 SQL Server 代理服務的狀態?
沒有 :-)
從 SQL Server 2005 開始,Microsoft 提供了一種通過“代理”推斷權限的機制。權限的代理是登錄名(用於伺服器級權限)或使用者(用於數據庫級權限)。在任何一種情況下,主體(伺服器或數據庫)都是從非對稱密鑰或證書創建的,被授予適當的權限,然後通過使用ADD SIGNATURE對一段或多段程式碼進行簽名來推斷權限。通過這樣做,您正在提供程式碼您授予該伺服器或數據庫主體的權限。因此,現在您可以創建一個儲存過程或函式來執行非常具體的操作,並有效地僅授予該程式碼適當的權限以正常執行。然後,您只需將 EXECUTE / SELECT 權限授予僅應允許執行該操作的那些使用者或角色,即可自然地處理權限。
在執行方面
xp_servicecontrol
,如果您EXECUTE
將其授予使用者,則該使用者可以執行它以獲取有關任何服務的資訊,這不像只允許執行它以獲取有關一項特定服務的資訊那樣經過微調。考慮到推斷權限方法,我們可以創建一個登錄名並將其放置在
sysadmin
角色中,但我們甚至不需要走那麼遠。從 SQL Server 2008 R2 的 SP1 開始,引入了一個新的 DMV,它顯示了與 SQL Server 相關的 Windows/NT 服務的狀態資訊:sys.dm_server_services。該 DMV 需要的唯一權限是VIEW SERVER STATE
. 但同樣,您甚至不需要向相關使用者授予此權限。你可以:
- 創建一個函式(UDF 或多語句 TVF)或儲存過程來封裝此 DMV 的非常具體的用法
- 創建證書
- 基於該證書創建登錄
- 授予
VIEW SERVER STATE
該登錄- 在相關使用者所在的數據庫中創建相同的證書
- 使用該證書籤署函式和/或儲存過程
- 授予該
EXECUTE
功能和/或儲存過程的相關使用者在此設置中,使用者在執行儲存過程或函式之外沒有獲得任何權限。雖然該
VIEW SERVER STATE
權限允許查看大量資訊,但該權限僅用於執行儲存過程或函式中的任何程式碼。並且只要該程式碼不是動態 SQL,那麼該權限就不能在該狹義定義的用途之外應用(或在已由同一證書籤名的任何其他程式碼之外)。擔心您可能會滑倒並意外授予
ALTER PROCEDURE
該使用者,然後他們可以輸入任何需要該權限的程式碼?錯誤的!任何完全更改為已簽名的對象將從該對像中刪除簽名。因此,即使有人確實設法更改了該函式或儲存過程,它也將不再由證書籤名,因此將不再能夠從基於證書的登錄中推斷出權限。即使該使用者以某種方式有權向對象添加簽名,如果沒有用於創建證書的密碼,這也無濟於事。如果使用者可以訪問您的密碼(或可能擁有密碼的部署腳本),那麼您的流程和標準存在嚴重缺陷,在這種情況下,不值得花時間和精力做所有這些,而只是讓那個人扮演這個sysadmin
角色;-)。嘗試以下操作:
最初設定:
USE [Test]; GO ------------------------------------------------------------- -- DROP PROCEDURE dbo.CheckSqlAgent CREATE PROCEDURE dbo.CheckSqlAgent AS SET NOCOUNT ON; SELECT dss.[status], dss.[status_desc] FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server Agent (%'; GO ------------------------------------------------------------- -- DROP FUNCTION dbo.IsSqlAgentRunning CREATE FUNCTION dbo.IsSqlAgentRunning() RETURNS BIT AS BEGIN DECLARE @IsRunning BIT = 0; IF (EXISTS(SELECT dss.* FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE N'SQL Server Agent (%' AND dss.[status] = 4 -- Running ) ) BEGIN SET @IsRunning = 1; END; RETURN @IsRunning; END; GO ------------------------------------------------------------- CREATE USER [MrNoLogin] WITHOUT LOGIN; GRANT EXECUTE ON dbo.CheckSqlAgent TO [MrNoLogin]; GRANT EXECUTE ON dbo.IsSqlAgentRunning TO [MrNoLogin];
測試#1:
SELECT SESSION_USER AS [SessionUser]; EXEC dbo.CheckSqlAgent; SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning];
回報:
SessionUser ----------- dbo status status_desc ------ ----------- 4 Running IsSqlAgentRunning ----------------- 1
測試#2:
EXECUTE AS USER='MrNoLogin'; SELECT SESSION_USER AS [SessionUser]; EXEC dbo.CheckSqlAgent; SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning];
回報:
SessionUser ----------- MrNoLogin Msg 297, Level 16, State 1, Procedure CheckSqlAgent, Line 7 The user does not have permission to perform this action. Msg 297, Level 16, State 1, Line 6 The user does not have permission to perform this action.
修復:
REVERT; SELECT SESSION_USER AS [SessionUser]; ------------------------------------------------------------- USE [master]; -- DROP CERTIFICATE [DoStuffCert]; CREATE CERTIFICATE [DoStuffCert] ENCRYPTION BY PASSWORD = N'W0rdUp,Yo!' WITH SUBJECT = N'Certificate for Managing Special Permissions'; CREATE LOGIN [MrDoStuff] FROM CERTIFICATE [DoStuffCert]; GRANT VIEW SERVER STATE TO [MrDoStuff]; BACKUP CERTIFICATE [DoStuffCert] TO FILE = 'C:\TEMP\ViewSqlAgentStatus.CER' WITH PRIVATE KEY ( FILE = 'C:\TEMP\ViewSqlAgentStatus.PVK', DECRYPTION BY PASSWORD = 'W0rdUp,Yo!', ENCRYPTION BY PASSWORD = 'DontStartNoneWontBeNone' ); ------------------------------------------------------------- USE [Test]; CREATE CERTIFICATE [DoStuffCert] FROM FILE = 'C:\temp\ViewSqlAgentStatus.CER' WITH PRIVATE KEY ( FILE = 'C:\temp\ViewSqlAgentStatus.PVK', DECRYPTION BY PASSWORD = 'DontStartNoneWontBeNone', ENCRYPTION BY PASSWORD = 'W0rdUp,Yo!' ); ADD SIGNATURE TO dbo.CheckSqlAgent BY CERTIFICATE [DoStuffCert] WITH PASSWORD = 'W0rdUp,Yo!'; ADD SIGNATURE TO dbo.IsSqlAgentRunning BY CERTIFICATE [DoStuffCert] WITH PASSWORD = 'W0rdUp,Yo!';
測試#3:
EXECUTE AS USER='MrNoLogin'; SELECT SESSION_USER AS [SessionUser]; EXEC dbo.CheckSqlAgent; SELECT dbo.IsSqlAgentRunning() AS [IsSqlAgentRunning]; REVERT;
現在兩者都為
MrNoLogin
:-)工作。
要為註冊伺服器中的 SQL Server 代理設置服務啟動帳戶
,請點擊加號以展開數據庫引擎。
- 點擊加號展開本地伺服器組文件夾
.
右鍵點擊要設置服務啟動帳戶的伺服器實例,然後選擇 SQL Server 配置管理器…。
在“使用者帳戶控制”對話框中,點擊“是”。
在 SQL Server 配置管理器的控制台窗格中,選擇 SQL Server 服務。
在詳細資訊窗格中,右鍵點擊 SQL Server 代理 (server_name),其中 server_name 是您要更改服務啟動帳戶的 SQL Server 代理實例的名稱,然後選擇“屬性”。在 SQL Server 代理 (server_name) 屬性對話框的登錄選項卡中,選擇登錄為下的以下選項之一:
內置帳戶:如果您的作業僅需要來自本地伺服器的資源,請選擇此選項。有關如何選擇 Windows 內置帳戶類型的資訊,請參閱為 SQL Server 代理服務選擇帳戶。
重要說明 重要
SQL Server 代理服務不支持 SQL Server Management Studio 中的本地服務帳戶
.
此帳戶:如果您的工作需要跨網路的資源,包括應用程序資源,請選擇此選項;如果您想將事件轉發到其他 Windows 應用程序日誌;或者如果您想通過電子郵件或尋呼機通知操作員。如果選擇此選項:
在“帳戶名”框中,輸入將用於執行 SQL Server 代理的帳戶。或者,點擊瀏覽打開選擇使用者或組對話框並選擇要使用的帳戶。
在密碼框中,輸入帳戶的密碼。在確認密碼框中重新輸入密碼。
點擊確定。
在 SQL Server 配置管理器中,點擊關閉按鈕。