最近看apue,簡單記錄對設置用戶id理解(設置組id同理)。
1. 相關的id好像很多,共有哪些?
文件2個id 2個位:
擁有者id 擁有者組id
設置用戶id位 設置組id位
進程6個或更多的id(如果有附加組id):
實際用戶id 實際組id (僅僅標志我們是誰,不參與文件訪問權限檢測)
有效用戶id 有效組id (用於文件訪問檢測)
保存的設置用戶id 保存的設置組id (有exec函數保存)
2. 進程打開、創建、刪除文件時的權限測試?
測試的參與者是進程的有效用戶id、有效組id、文件的擁有者id、文件擁有者組id。
(1)進程的有效用戶id是0(超級用戶),則允許訪問;
(2)進程的有效用戶id等於文件擁有者id,則按照擁有者的權限訪問;
(3)進程有效組id或附加組id之一等於文件擁有者組id,則按照文件擁有者組的權限訪問;
(4)否則,按照文件的其他用戶訪問權限訪問;
上述的四步是按續依次進行的。
3. 什么時候用到設置用戶id和設置組id?
當進程通過exec函數執行某個文件的時候,而且文件的設置用戶id只會影響到進程的有效用戶id
(其實也足夠了,因為只有有效用戶id參與權限測試),這樣說不夠嚴謹,因為進程的保存設置用
戶id和保存設置組id會被exec函數從有效用戶id和有效組id復制過來,所以保存的設置用戶id和
保存的設置組id也會隨之改變。
(1)當文件的設置用戶id位和設置組id位沒有打開:
進程的有效用戶id和有效組id保持不變,嚴格按照第2步進行權限測試;
(2)文件的設置用戶id位和設置組id位被打開:
exec函數才會把進程的有效用戶id和有效組id設置為文件擁有者的用戶id和組id,這時再進
行權限測試,進程就擁有了和文件擁有者一樣的訪問權限。
4. 進程保存設置用戶id和保存設置組id有什么用?
顧名思義,這兩個id存在的價值就是保存,保存誰呢?保存有效用戶id和有效組id。當進程的
實際用戶id和有效用戶id不同時(組id同理),保存的設置用戶id才有意義。因為這樣就可以通
過調用setuid()把有效用戶id切換為與進程的實際用戶id或保存的設置用戶id相同的值,不保存下
來,我們就弄丟了。
書上例子:
man程序文件的所有者及他屬組通常是為man自身保留的用戶和組, man可能需要執行許多其
他命令,以處理包含顯示手冊頁的文件,為了防止被欺騙或重寫錯誤文件, man在兩種權限間
切換: 運行man命令用戶的權限, 擁有man可執行文件用戶的權限。下面列出其工作步驟:
(1)man擁有者是名為man的用戶,且設置用戶id位已經設置。當我們exec此程序時,用戶id情況:
實際用戶ID = 我們的用戶ID
有效用戶ID = man //設置用戶id位已設置,有效用戶id改變
保存的設置用戶ID = man // 復制有效用戶ID
(2) 進程訪問需要的配置文件和手冊頁,這些文件由man用戶擁有, 因為有效用戶ID是man,
所以可以訪問
(3)man 代表我們運行任一命令前, 調用setuid(getuid()) , 我們不是超級用戶, 所以僅僅改變有效
用戶ID,
用戶ID情況變成:
實際用戶ID = 我們的用戶ID (未改變)
有效用戶ID = 我們的用戶ID
保存的設置用戶ID = man //看出來了吧,如果不保存下來,我們就把man用戶丟了,再想
setuid(man)就不會成功, 因為只允許將有效用戶id設置為與實際用戶id或保存的設置用戶id
相同的值。 這時候,我們做回了自己,就只能訪問我們通常可以訪問的東西,沒有特殊權限了。
man代表我們安全執行一次過濾。
(4)執行完過濾后,man再調用setuid(euid)(euid是man的數值用戶id,man自己通過 geteuid
獲得並保存的)。因為euid 等於保存的設置用戶id,設置成功。(保存的設置用戶id的價值所在)
得到:
實際用戶ID = 我們的用戶ID (未改變)
有效用戶ID = man
保存的設置用戶ID = man (未改變)
5) 因為有效用戶是man, 所以現在可以對其他文件進行操作了