更深入地了解Linux權(quán)限
譯文【51CTO.com快譯】在Linux上查看文件權(quán)限時(shí),有時(shí)你看到的不僅僅是普通的r、w、x和-這些名稱。你可能看到的不是rwx,而是s或t,如下例所示:
- drwxrwsrwt
進(jìn)一步明確這點(diǎn)的一種方法是使用stat命令來查看權(quán)限。stat的輸出結(jié)果中第四行顯示了八進(jìn)制和字符串格式的文件權(quán)限:
- $ stat /var/mail
- File: /var/mail
- Size: 4096 Blocks: 8 IO Block: 4096 directory
- Device: 801h/2049d Inode: 1048833 Links: 2
- Access: (3777/drwxrwsrwt) Uid: ( 0/ root) Gid: ( 8/ mail)
- Access: 2019-05-21 19:23:15.769746004 -0400
- Modify: 2019-05-21 19:03:48.226656344 -0400
- Change: 2019-05-21 19:03:48.226656344 -0400
- Birth: -
該輸出提醒我們,分配給文件權(quán)限的位數(shù)超過9個(gè),實(shí)際上有12個(gè)。這多出來的3位為分配平常的讀取、寫入和執(zhí)行之外的權(quán)限提供了一種方法;比如說,3777(二進(jìn)制011111111111)表示在使用兩個(gè)額外的設(shè)置。
這個(gè)特定值中的***個(gè)1(第2位)表示SGID(設(shè)置組ID),并分配運(yùn)行文件的臨時(shí)權(quán)限,或使用擁有關(guān)聯(lián)組權(quán)限的目錄。
011111111111
^
SGID為使用該文件充當(dāng)該組成員的人員賦予了臨時(shí)權(quán)限。
第二個(gè)1(第3位)是“粘性”位。它確保只有文件的所有者才能刪除或重命名文件或目錄。
011111111111
^
如果權(quán)限是7777而不是3777,我們已知道SUID(設(shè)置UID)字段也已被設(shè)置。
111111111111
^
SUID為使用該文件充當(dāng)文件所有者的用戶賦予了臨時(shí)權(quán)限。
至于我們在上面看到的/var/mail目錄,所有用戶都需要一定的訪問權(quán)限,因此需要一些特殊值來提供它。
但現(xiàn)在讓我們更進(jìn)一步。
特殊權(quán)限位的一個(gè)常見用途是用于passwd命令之類的命令。如果你看一下/usr/bin/passwd文件,會(huì)注意到SUID位已設(shè)置,允許你更改密碼(因而更新/etc/shadow文件的內(nèi)容),即使你以普通(非特權(quán))用戶的身份來運(yùn)行,對該文件沒有讀取或?qū)懭霗?quán)限。當(dāng)然,passwd命令很聰明,不允許你更改其他人的密碼,除非你實(shí)際上以root的身份運(yùn)行或使用sudo。
- $ ls -l /usr/bin/passwd
- -rwsr-xr-x 1 root root 63736 Mar 22 14:32 /usr/bin/passwd
- $ ls -l /etc/shadow
- -rw-r----- 1 root shadow 2195 Apr 22 10:46 /etc/shadow
現(xiàn)在,不妨看一下可以用這些特殊權(quán)限做什么。
如何分配特殊文件權(quán)限 ?
與Linux命令行上的許多內(nèi)容一樣,你在如何發(fā)出請求方面有一些選擇。chmod命令讓你可以以數(shù)字方式或使用字符表達(dá)式來更改權(quán)限。
想以數(shù)字方式更改文件權(quán)限,可以使用這樣的命令來設(shè)置setuid位和setgid位:
- $ chmod 6775 tryme
或者可以使用這樣的命令:
- $ chmod ug+s tryme <== for SUID and SGID permissions
如果添加特殊權(quán)限的文件是腳本,你可能會(huì)驚訝于它未符合你的期望。這是個(gè)很簡單的例子:
- $ cat tryme
- #!/bin/bash
- echo I am $USER
即使SUID位和SGID位已設(shè)置,這個(gè)文件是root擁有的文件,運(yùn)行這樣的腳本也不會(huì)帶來你可能預(yù)計(jì)的“我是root”響應(yīng)。為什么?因?yàn)長inux忽略腳本上的set-user-ID位和set-group-ID位。
- $ ls -l tryme
- -rwsrwsrwt 1 root root 29 May 26 12:22 tryme
- $ ./tryme
- I am jdoe
另一方面,如果你使用編譯的程序嘗試類似的操作,就像這個(gè)簡單的C程序一樣,會(huì)看到不同的效果。在該示例程序中,我們提示用戶輸入文件并為其創(chuàng)建文件,并將寫入權(quán)限賦予文件。
- #include
- int main()
- {
- FILE *fp; /* file pointer*/
- char fName[20];
- printf("Enter the name of file to be created: ");
- scanf("%s",fName);
- /* create the file with write permission */
- fp=fopen(fName,"w");
- /* check if file was created */
- if(fp==NULL)
- {
- printf("File not created");
- exit(0);
- }
- printf("File created successfully\n");
- return 0;
- }
一旦你編譯程序,運(yùn)行命令使root成為所有者并設(shè)置所需的權(quán)限后,你會(huì)看到它以預(yù)期的root權(quán)限運(yùn)行,留下新創(chuàng)建的root擁有的文件。當(dāng)然,你必須擁有sudo權(quán)限才能運(yùn)行一些所需的命令。
- $ cc -o mkfile mkfile.c <== compile the program
- $ sudo chown root:root mkfile <== change owner and group to “root”
- $ sudo chmod ug+s mkfile <== add SUID and SGID permissions
- $ ./mkfile <== run the program
- Enter name of file to be create: empty
- File created successfully
- $ ls -l empty
- -rw-rw-r-- 1 root root 0 May 26 13:15 empty
請注意,該文件由root擁有――如果程序未以root權(quán)限運(yùn)行,不會(huì)發(fā)生這種情況。
權(quán)限字符串(比如rwsrwsrwt)中不常見設(shè)置的位置可以幫助提醒我們每個(gè)位的含義。至少***個(gè)“s”(SUID)位于所有者權(quán)限區(qū)域,第二個(gè)(SGID)位于組權(quán)限區(qū)域。為什么粘性位是“t”而不是“s”不在本文的探討范圍。無論如何,額外的權(quán)限設(shè)置為Linux及其他Unix系統(tǒng)提供了許多附加功能。
原文標(biāo)題:A deeper dive into Linux permissions,作者:Sandra Henry-Stocker
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】