UNIX/Linux下關於文件執行權限的表示和查看想必是最熟悉不過的,然而你是否真正了解用戶文件的權限標識和用戶的權限呢?
實際上文件權限標識不僅僅只有U, G, O
11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
SUID | GUID | SBIT | R | W | X(S/s) | R | W | X(S/s) | R | W | X(S/s) |
如上所示,linux中除了常見的讀(r)、寫(w)、執行(x)權限以外,還有3個特殊的權限,分別是setuid、setgid和stick bit
1、setuid、setgid
先看個實例,查看你的/usr/bin/passwd 與/etc/passwd文件的權限
[root@MyLinux ~]# ls -l /usr/bin/passwd /etc/passwd -rw-r--r-- 1 root root 1549 08-19 13:54 /etc/passwd -rwsr-xr-x 1 root root 22984 2007-01-07 /usr/bin/passwd
眾所周知,/etc/passwd文件存放的各個用戶的賬號與密碼信息,/usr/bin/passwd是執行修改和查看此文件的程序,但從權限上看,/etc/passwd僅有root權限的寫(w)權,可實際上每個用戶都可以通過/usr/bin/passwd命令去修改這個文件,於是這里就涉及了linux里的特殊權限setuid,正如-rwsr-xr-x中的s
setuid就是:讓普通用戶擁有可以執行“只有root權限才能執行”的特殊權限,
setgid同理指”組“
作為普通用戶是沒有權限修改/etc/passwd文件的,但給/usr/bin/passwd以setuid權限后,普通用戶就可以通過執行passwd命令,臨時的擁有root權限,去修改/etc/passwd文件了
2、stick bit (粘貼位)
再看個實例,查看你的/tmp目錄的權限
[root@MyLinux ~]# ls -dl /tmp drwxrwxrwt 6 root root 4096 08-22 11:37 /tmp
tmp目錄是所有用戶共有的臨時文件夾,所有用戶都擁有讀寫權限,這就必然出現一個問題,A用戶在/tmp里創建了文件a.file,此時B用戶看了不爽,在/tmp里把它給刪了(因為擁有讀寫權限),那肯定是不行的。實際上是不會發生這種情況,因為有特殊權限stick bit(粘貼位)權限,正如drwxrwxrwt中的最后一個t
stick bit (粘貼位)就是:除非目錄的屬主和root用戶有權限刪除它,除此之外其它用戶不能刪除和修改這個目錄。
也就是說,在/tmp目錄中,只有文件的擁有者和root才能對其進行修改和刪除,其他用戶則不行,避免了上面所說的問題產生。用途一般是把一個文件夾的的權限都打開,然后來共享文件,象/tmp目錄一樣。
3、如何設置以上特殊權限
setuid:chmod u+s xxx chmod 4*** xxx
setgid: chmod g+s xxx chmod 2*** xxx
stick bit : chmod o+t xxx chmod 1*** xxx
或者使用八進制方式,在原先的數字前加一個數字,三個權限所代表的進制數與一般權限的方式類似,如下:
suid guid stick bit
1 1 1
最后,在一些文件設置了特殊權限后,字母不是小寫的s或者t,而是大寫的S和T,那代表此文件的特殊權限沒有生效,是因為你尚未給它對應用戶的x權限
以上介紹了文件的權限和uid gid等概念,也許又會有疑問,用戶的uid,gid 和上述uid ,gid是同一概念嗎? 他們之間有什么聯系嗎?
1、當我們創建用戶時,由我們為新建用戶命名和設置密碼,同時系統會為我們所創建的用戶名關聯一個ID,就是所謂的用戶uid。同時我們還可以把這個用戶放到某個用戶群里,類似的,用戶群也可以我們手工建立。如果建立用戶時,不指明所建的用戶屬於哪個用戶群,則系統會自動建立一個跟用戶名同名的用戶群。不管手工建立還是自動建立,系統都會為用戶群關聯一個號,這個號稱之為gid。用戶uid所屬的群的gid就是用戶的gid。
2、系統在運行每個進程時都會關聯幾個ID,分別為pid、ppid、uid、euid。
進程的pid為運行進程時,系統自動分配的,用於唯一標識此進程的一個整數。
進程的ppid就是進程的父進程的pid。
同時,系統還會為運行的進程分配一個進程uid和進程euid,用於判斷文件的執行權限。
一般情況下,進程uid和進程euid等於運行這個進程的用戶uid。
對於某文件,它的執行權限分成三組: 文件擁有者權限、文件擁有者同組權限、其他用戶權限。
當在某個用戶A下執行該文件,該文件所在的進程 uid 就是A用戶的uid;而euid則需要根據該文件的suid標識位和文件擁有者用戶來決定。也就是說,如果suid設置為 "s",那么euid就是文件擁有者用戶的uid;這樣euid可以設置進程擁有擁有什么級別的執行權限。
簡單來講,如果可執行文件的setuid位無效,則運行這個可執行文件時,進程uid和euid都是用戶的uid;
如果可執行文件的setuid位有效,則運行這個可執行文件時,進程uid還是用戶的uid,而進程euid則會暫時被修改成該可執行文件的所有者用戶uid,直到該進程結束。
一句話,在某個進程中,進程pid和ppid是唯一標識該進程的,它不會改變,而進程uid與運行該進程的用戶uid相同,進程euid則與uid相同,只有運行設置了setuid位的文件時才會把euid改為這個文件的所有者用戶uid。
同理,進程gid和進程egid則類似。
在shell中執行ls -l命令,則會顯示如下:
drwxr-xr-x 2 root root 652 Jul 31 2006 /root/hello
d表示文件,后面幾個表示文件所有者、同組用戶、其他用戶的執行權限,文件數量,文件所有者,文件創建者(注意,RHEL這項是文件所有群),文件大小,日期,文件所在路徑
du -sh xxx可以測量xxx文件或目錄所占內存大小。
內核會給每個進程關聯兩個和進程ID無關的用戶ID,一個是真實用戶ID(RUID real uid){用戶區},還有一個是有效用戶ID(EUID effetive uid) --{ 內核進程表中(SUID), 用戶區(EUID) }。
真實用戶ID用於標識由誰為正在運行的進程負責。
有效用戶ID用於為新創建的文件分配所有權、檢查文件訪問許可,還用於通過kill系統調用向其 它進程發送信號時的許可檢查。
內核允許一個進程以exec調用一個setuid程序或者顯式執行setuid系統調用的方式改變它的有效用戶ID。 所謂setuid程序是指一個設置了許可模式字段中的setuid bit的可執行文件。當一個進程exec一個setuid程序的時候,內核會把進程表以及用戶區中的有效用戶ID設置成該文件所有者的ID。為了區分這兩個字段,我們把進程表中的那個字段稱作保存用戶ID(SUID saved uid)。可以通過一個例子來演示這兩個字段的區別。
setuid系統調用的語法是 setuid(uid) ,其中,uid是新的用戶ID,該系統調用的結果取決於有效用戶ID的當前值。
如果調用進程的有效用戶ID是超級用戶,內核會把進程表以及用戶區中的真實和有效用戶ID都設置成uid。
如果調用進程的有效用戶ID不是超級用戶,僅當uid等於真實用戶ID或保存用戶ID時,內核才會把u區中的有效用戶ID設置成uid。
否則,該系統調用將返回錯誤。
一般來說,一個進程會在fork系統調用期間從父進程那兒繼承它的真實和有效用戶ID,這些數值即使經過 exec系統調用也會保持不變。 存儲在用戶區中的有效用戶ID是最近一次setuid系統調用或是exec一個setuid程序的結果;只有它會被用於文件訪問許可(euid)。進程表中的保存用戶 ID使得一個進程可以通過執行setuid系統調用把有效用戶ID設置成它的值,以此來恢復最初的有效用戶ID。
非root用戶是不可能通過setuid或者seteuid取得其他權限(包括root權限)的,它只能恢復原來的權限。允許通過setuid或者seteuid取得root權限是非常危險的,這樣他就可以在程序的后邊做任何想做的事了(包括kill掉你的系統)。只能通過exec一個設置了setuid位的可執行程序,來取得其他(程序文件所有者)權限(包括root權限)。
例如用戶執行su即可獲得root權限(su的屬主為root)。
-rwsr-xr-x 1 root root 27108 2008-11-23 /bin/su
注意其中的s,該標志即為setuid標志(文件除基本的r、w、x權限外,還有s)。出於安全,防止普通用戶取得root權限后威脅系統安全,該權限只針對不可更改的可執行文件(不能執行自定義程序)。
要想取得root權限就必須exec一個root所有的可執行文件(當然首先得有執行權限),而該程序由root所有,其安全就由root負責。所以非root用戶就不可能以root身份運行屬於root以外的程序。至於sudo之類的,是因為sudo本身里有setuid和exec調用(root用戶允許的,給非root用戶開了一個后門),通過sudo取得root權限,作為中介來exec所有程序。但也有限制,就是該用戶是sudoers(后門的鑰匙,root的親戚才有,又是安全)!(現在流行靠關系、開后門,到時如果出問題,就該抱怨了:都是開后門惹的禍!)
su=super user
sudo是什么的縮寫?super user ? ?(應為swicth user)
還有非root權限用戶,不能改變實際用戶ID,而只能改變有效用戶ID,包括通過exec一個setuid程序。
只有root用戶進程才能更改實際用戶ID。這樣普通用戶進程就不能通過改變實際用戶ID,然后再通過setuid,設置有效用戶ID為實際用戶ID,進而取得與該實際用戶ID對應的權限了(包括root)。正如上面說過的:允許通過setuid或者seteuid取得root權限是非常危險的。
對於文件訪問權限的驗證是根據有效用戶ID。有些文件只有root用戶才有讀寫或者執行的權力,對於這些文件,普通用戶程序就需要以root權限(進程的有效用戶ID為0)來訪問。
參考:
[1]. Linux中的文件特殊權限 http://www.cnblogs.com/huangzhen/archive/2011/08/22/2149300.html
[2]. 進程pid和ppid、進程的uid和euid、用戶的uid和gid、文件的創建者和所有者的關系辨析. http://blog.csdn.net/tianyahaijiaozd/article/details/6275006
[3]. setuid函數. http://blog.csdn.net/todd911/article/details/7738069