Sql-Server

我需要向使用者提供哪些最低權限才能檢查 SQL Server 代理服務的狀態?

  • August 13, 2017

我創建了一個使用者並為其授予了許多權限和角色,包括SQLAgentUserRoleSQLAgentReaderRole.

我的應用程序檢查 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 配置管理器中,點擊關閉按鈕。

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