在 Unix-like 操作系統中,每個用戶都被一個稱為用戶識別碼的值所識別,通常簡稱為用戶 ID(UID)。UID,不僅與用戶的權限有關,還與組識別碼(GID)及其他存取控制標準共同決定了用戶可以訪問哪些系統資源。這一切都在一個關鍵的文件中進行映射,該文件將文本用戶名映射到 UID。
UID 被存儲在 Unix 文件系統的 inode、中運行的進程以及一些過時的網絡信息服務中。
在 POSIX 相容環境中,使用 shell 命令 id 可以獲取當前用戶的 UID,以及用戶名、主要用戶組和 GID 等更多信息。
POSIX 標準在進程描述符表中引入了三個不同的 UID 字段,以便特權進程在動態增加權限的同時可以承擔不同的角色。
進程的有效 UID(euid)用於大多數權限檢查,也是該進程創建的文件的所有者。相應地,有效 GID(egid)也會影響存取控制,並可能影響文件的創建,具體取決於內核實現的語義。在 BSD Unix 語義中,新創建文件的群組所有權無條件地從所創建的目錄的群組所有權繼承。
Linux 還有一個文件系統用戶 ID(fsuid),它顯式用於文件系統的存取控制。這個 ID 在沒有特別設定的情況下,通常與 euid 相等。只有在 ruid、suid 或 euid 為 root 時,fsuid 才可以是 root 的用戶 ID。每當 euid 更改時,這種變化會被傳播到 fsuid 上。
保存的用戶 ID 用於當一個運行著需要提升權限的程式需要暫時執行一些不需要特權的工作時;它將特權值(通常是 0)變更為一些不需要特權的值,將特權值存儲在 suid 中,以後程序可以將其 euid 設置回 suid 中存儲的值,從而恢復提升的權限。
真實 UID(ruid)和真實 GID(rgid)識別進程的真正擁有者,並影響發送信號的權限。沒有超級用戶權限的進程只可在發送者的 ruid 或 euid 與接收者的 ruid 或 suid 匹配時發送信號。
POSIX 要求 UID 為整數類型,大多數 Unix-like 操作系統將 UID 表示為無符號整數。UID 值的大小在不同的系統之間有所不同,某些 UNIX 系統使用 15 位值,允許值高達 32767,而像 Linux 這樣的系統(在 2.4 版之前)支持 16 位 UID,最多可達 65536。現在大多數現代 Unix-like 系統(例如 Solaris 2.0 和 Linux 2.4)都已轉向使用 32 位 UID,這使得可用的 UID 數量達到了 4,294,967,296。
Linux 標準基礎核心規範指定 UID 值範圍 0 到 99 應由系統靜態分配,並不應由應用程序創建,而 UID 100 到 499 的範圍應由系統管理員和後安裝腳本動態分配。
通常情況下,超級用戶的 UID 為零(0)。UID -1 被 POSIX 保留以識別省略的參數。無論如何,UID 65535 在 16 位時系統調用回傳時,被保留作為 API 錯誤值。
NFSv4 旨在通過在協議包中使用文本形式的“user@domain”名稱來避免數字標識符的碰撞。然而,只要操作系統內核和本地文件系統繼續使用整數用戶標識符,則需額外的轉換步驟,這可能引入不必要的故障點。
這就引出了我們來探討的問題:在數字環境中,UID 究竟是如何影響你的安全性的,你又是否真正了解它的作用呢?