Unix中常見的幾個(gè)概念,下面做一個(gè)解釋.
首先需要明確一點(diǎn),這幾個(gè)概念都是和進(jìn)程相關(guān)的.
real user ID表示的是實(shí)際上進(jìn)程的執(zhí)行者是誰,effective user ID主要用于校驗(yàn)該進(jìn)程在執(zhí)行時(shí)所獲得的文件訪問權(quán)限,也就是說當(dāng)進(jìn)程訪問文件時(shí)檢查權(quán)限時(shí)實(shí)際上檢查的該進(jìn)程的"effective user ID",saved set-user-ID 僅在effective user ID發(fā)生改變時(shí)保存.
一般情況下,real user ID就是進(jìn)程的effective user ID,但是當(dāng)要運(yùn)行的可執(zhí)行程序設(shè)置了"set-user-ID"位之后,進(jìn)程的effective user ID變成該文件的屬主用戶id,同時(shí)該進(jìn)程的"saved set-user-ID"變成此時(shí)進(jìn)程的"effective user ID",也就是該可執(zhí)行程序的屬主用戶ID,該進(jìn)程在執(zhí)行一些與文件訪問權(quán)限相關(guān)的操作時(shí)系統(tǒng)檢查的是進(jìn)程的effective user ID.
為什么需要一個(gè)"saved set-user-ID"?因?yàn)楫?dāng)進(jìn)程沒有超級(jí)用戶權(quán)限的時(shí)候,進(jìn)程在設(shè)置"effective user ID"時(shí)需要將需要設(shè)置的ID和該進(jìn)程的"real user ID"或者"saved set-user-ID"進(jìn)行比較.
APUE2中進(jìn)行的解釋是:
1)If the process has superuser privileges, the setuid function sets the real user ID, effective user ID, and saved set-user-ID to uid.
2)If the process does not have superuser privileges, but uid equals either the real user ID or the saved set-user-ID, setuid sets only the effective user ID to uid. The real user ID and the saved set-user-ID are not changed.
3)If neither of these two conditions is true, errno is set to EPERM, and 1 is returned
也就是說:
1)當(dāng)用戶具有超級(jí)用戶權(quán)限的時(shí)候,setuid 函數(shù)設(shè)置的id對(duì)三者都起效.
2)否則,僅當(dāng)該id為real user ID 或者saved set-user-ID時(shí),該id對(duì)effective user ID起效.
3)否則,setuid函數(shù)調(diào)用失敗.
也就是說,這個(gè)saved set-user-ID更多的作用是在進(jìn)程切換自己的effective user ID起作用.
需要特別提醒的是:并沒有任何的API可以獲取到進(jìn)程的saved set-user-ID,它僅僅是系統(tǒng)在調(diào)用setuid函數(shù)時(shí)進(jìn)行比較而起作用的.
APUE2中關(guān)于此事的原話如下:
Note that we can obtain only the current value of the real user ID and the effective user ID with the functions getuid and geteuid from Section 8.2. We can't obtain the current value of the saved set-user-ID.
舉一個(gè)例子說明問題,假設(shè)這樣的一種情況,系統(tǒng)中有兩個(gè)用戶A,B,還有一個(gè)由B創(chuàng)建的可執(zhí)行程序proc,該可執(zhí)行程序的set-
user-id位已經(jīng)進(jìn)行了設(shè)置.
當(dāng)A用戶執(zhí)行程序proc時(shí),
程序的real user ID = A的用戶ID,effective user ID = B的用戶ID, saved set-user-ID=B的用戶ID.
假如在該進(jìn)程結(jié)束了對(duì)某些限制只能由用戶B訪問的文件操作后,程序?qū)ffective user ID設(shè)置回A,也就是說此時(shí):
程序的real user ID = A的用戶ID,effective user ID = A的用戶ID, saved set-user-ID=B的用戶ID.
這個(gè)改動(dòng)之所以能成功,原因在于上面列舉出的情況2):該ID為進(jìn)程的real user ID.
最后,假設(shè)由于種種原因進(jìn)程需要再次切換effective user ID為B,可是因?yàn)椴荒芡ㄟ^API獲取進(jìn)程的saved set-user-ID(該值為B的用戶ID),所以只能通過兩種途徑獲得(可能還有別的途徑):
a)在設(shè)置effective user ID變回A之前保存effective user ID,它的值為B的用戶ID.
b)調(diào)用函數(shù)getpwnam( "B"),在返回的struct passwd *指針中成員pw_uid存放的就是用戶B的ID.
這樣,這個(gè)調(diào)用setuid(B的用戶ID)就會(huì)成功,原因也在于上面說的情況2):該ID與進(jìn)程的saved set-user-ID相同.
APUE2中關(guān)于這幾個(gè)值的相關(guān)解釋在section4.4和section8.11中都有涉及.