1. 程式人生 > >“孤立”用戶

“孤立”用戶

-- lte guest 維護 user dex design src 還原

在數據庫安全體系中,Login和User是兩個最基本的安全主體(Principal),Login用於登陸到SQL Server實例,而User用於訪問數據庫。Login和User之間有一個映射關系,通過SID(安全標識,Security ID)連接到一起。在一個數據庫中,如果一個User沒有相應的Login,稱作孤立用戶(Orphaned User),也就是說,該User的SID存在於sys.database_principals 中, 而不存在於 sys.server_principals 中。一般情況下,把備份的數據庫還原到在其它SQL Server實例之後,會產生孤兒用戶。還有一種情況,孤立用戶是DBA故意創建的,通過權限模擬來實現特定的系統維護任務。

一,檢查和修復孤立用戶

Login 和 User的映射關系是通過SID來關聯的,如果一個SID 存在於sys.database_principals,而不存在於 sys.server_principals,那麽這個User 除非是system user,否則就是孤立用戶。出現孤立用戶的根本原因是:數據庫User沒有對應的Login,解決孤立用戶問題的方法是:創建Login,建立Login和孤立用戶之間的映射。

1,使用以下腳本查看孤立用戶

在查看孤立用戶時,應該過濾掉系統預先創建的用戶,例如,dbo、sys和guest(來賓用戶),一般情況下,只查看SQL User,Windows Users和Windows Group這三個安全主體類型,通過以下腳本查看孤立用戶,並修復孤立用戶。大多數情況下,在把數據庫備份還原到不同的SQL Server實例時,會出現孤立用戶。

技術分享
select dp.name as UserName
    ,dp.type
    ,dp.type_desc
    ,dp.default_schema_name
    ,dp.is_fixed_role
    ,dp.authentication_type
    ,dp.authentication_type_desc
    ,dp.sid,dp.principal_id
from sys.database_principals dp
left join sys.server_principals sp 
    on dp.sid=sp.sid
where sp.sid is null
    and dp.[type] IN (N‘U‘, N‘S‘,N‘G‘)
    and dp.is_fixed_role = 0
    and dp.[Name] NOT IN (N‘dbo‘, N‘guest‘, N‘sys‘, N‘INFORMATION_SCHEMA‘)
技術分享

在視圖 sys.database_principals中,Principal的類型註釋如下:

  • S = SQL user
  • U = Windows user
  • G = Windows group

2,創建Windows Login

創建Windows Login,Logon Name的格式是:[<domainName>\<login_name>]

CREATE LOGIN [DomainName\WindowsLoginName] -- or [DomainName\WindowsGroupName] 
FROM WINDOWS WITH DEFAULT_DATABASE=[master], 
DEFAULT_LANGUAGE=[us_english]

3,重新創建Login 和 name之間的映射關系

通過為User指定新的Login,重新把User映射到Login。Login 和User的映射關系是通過SID(security Identifier)來關聯的,在重新映射時,數據庫引擎會把User的SID修改為Login的SID,以建立映射關系。

ALTER USER userName  
WITH LOGIN = loginName

註:The WITH LOGIN clause enables the remapping of a user to a different login.

二,自動修復孤立用戶問題

對於孤立用戶,由於User Name和 Login Name之間沒有直接的關系,因此,完全修復孤立用戶的可能性幾乎是沒有的。在特定的情況下,當使用Windows驗證創建User和Login時,把User Name 和 Login Name設置成相同的,這樣,可以檢測數據庫的User是否有對應的Login;如果沒有對應的Login,管理員可以新建相應的Windows Login,重建映射關系,進而修復孤立用戶。

以下是自動修復孤立用戶的腳本,僅供參考:

技術分享 View Code

三,來賓用戶(guest)

登錄(Login)用於用戶身份驗證,而數據庫用戶(User)用於數據庫的訪問和權限驗證。登錄(Login)通過安全識別符 (SID) 與用戶(User)關聯。如果數據庫中不存在針對特定登錄(Login)的用戶(User),使用該登錄(Login)的用戶即使能夠連接到 SQL Server 服務器,也無法訪問數據庫。但是,該情形的唯一例外是當數據庫包含“guest”用戶(User)時,與用戶(User)不關聯的登錄(Login)將被映射到 guest 用戶。如果存在數據庫用戶(User),但沒有與其關聯的登錄(Login),則該用戶將無法登錄到 SQL Server 服務器中。

四,創建孤立用戶

通過Create User 命令創建User和Login之間的映射關系,上文提到,這種映射關系是通過SID來關聯的,即Login訪問數據庫使用的User的SID和Login相同。

在創建新的User時,指定關聯的Login,就可以創建User和Login的映射關系,腳本如下:

CREATE USER user_name 
--FOR LOGIN login_name 
[ WITH DEFAULT_SCHEMA = schema_name ] 

在創建User時,如果沒有指定for login子句,那麽新建的User是孤立用戶,一般用作系統維護等特殊用途。

參考文檔:

Fixing orphaned database users in 2005 to 2012 – T-SQL Tuesday #025

Do you still use sp_change_users_login instead of ALTER USER UserName WITH LOGIN = UserName

“孤立”用戶