摘要:非sysadmin使用者執行xp_cmdshell會有2秒延遲
-- 建立proxy account
-- (sysadmin role 會透過SQL service account跟OS溝通
-- 非sysadmin role的user,會透過proxy account跟OS溝通)
Use Master
GO
EXEC sp_xp_cmdshell_proxy_account 'ADVWKS\OS_User','P@ssw0rd'
-- 建立非sysadmin role的user
Use Master
GO
create login abc with password='P@ssw0rd'
GO
create user abc for login abc
GO
-- grant 執行xp_cmdshell的權限
grant exec on xp_cmdshell to abc
GO
-- 以有sysadmin role的使用者執行dos commend
set statistics time on
exec xp_cmdshell 'cmd /c time /t'
set statistics time off
-- 以沒有sysadmin role的執行dos commend
set statistics time on
exec as user='abc'
exec xp_cmdshell 'cmd /c time /t'
revert
可以發現沒有sysadmin role的使用者執行xp_cmdshell時,會有2秒左右的延遲。其實2秒好像也不是太嚴重,但是當一支stored procedure裡重覆執行xp_cmdshell時,就明顯有「慢」的感覺了…..
這個問題查了一個多月,最後在微軟的協助下發現與OS 底層MPR (Multiple Provider Router) 呼叫的Network Provider有關。
http://www.symantec.com/business/support/index?page=content&id=TECH168053
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\HwOrder]
[原來的機碼順序]
"ProviderOrder"="PDVFSNP,SnacNp,RDPNP,LanmanWorkstation"
[修改後的機碼順序]
"ProviderOrder"="SnacNp,RDPNP,LanmanWorkstation,PDVFSNP"
因PDVFSNP(PureDisk agent) 的DLL 無法做即時的回應,造成了非sysadmin role的使用者在做LogonUser API 呼叫時都會延遲的問題,所以要把順序調到後面。
PS. 這是去年就解決的問題了。只是前幾天server上windows patch,結果不知道哪支patch又把機碼順序改回去…… 難道以後每次上patch都要來檢查一下順序嗎…. @@
後來跟老師討論這個問題時,發現SQL server可以讀寫registry key 值 :
/**** 讀registry ****/
DECLARE @returnValue NVARCHAR(1000)
EXEC master.dbo.xp_regread
@rootkey = N'HKEY_LOCAL_MACHINE',
@key = N'SYSTEM\CurrentControlSet\Control\NetworkProvider\Order',
@value_name = N'ProviderOrder',
@value = @returnValue output
SELECT @returnValue as Value
/**** 修改 registry ****/
EXECUTE master..xp_regwrite
@rootkey = N'HKEY_LOCAL_MACHINE',
@key = N'SYSTEM\CurrentControlSet\Control\NetworkProvider\Order',
@value_name = N'ProviderOrder',
@data_type = 'REG_SZ',
@value = 'RDPNP,SnacNp,LanmanWorkstation,webclient,EmLogon'
若要透過SQL 修改registry key值,則需將regitry key的權限grant給SQL serice account