更深入地了解Linux權限
譯文【51CTO.com快譯】在Linux上查看文件權限時,有時你看到的不僅僅是普通的r、w、x和-這些名稱。你可能看到的不是rwx,而是s或t,如下例所示:
- drwxrwsrwt
進一步明確這點的一種方法是使用stat命令來查看權限。stat的輸出結果中第四行顯示了八進制和字符串格式的文件權限:
- $ 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: -
該輸出提醒我們,分配給文件權限的位數超過9個,實際上有12個。這多出來的3位為分配平常的讀取、寫入和執行之外的權限提供了一種方法;比如說,3777(二進制011111111111)表示在使用兩個額外的設置。
這個特定值中的***個1(第2位)表示SGID(設置組ID),并分配運行文件的臨時權限,或使用擁有關聯組權限的目錄。
011111111111
^
SGID為使用該文件充當該組成員的人員賦予了臨時權限。
第二個1(第3位)是“粘性”位。它確保只有文件的所有者才能刪除或重命名文件或目錄。
011111111111
^
如果權限是7777而不是3777,我們已知道SUID(設置UID)字段也已被設置。
111111111111
^
SUID為使用該文件充當文件所有者的用戶賦予了臨時權限。
至于我們在上面看到的/var/mail目錄,所有用戶都需要一定的訪問權限,因此需要一些特殊值來提供它。
但現在讓我們更進一步。
特殊權限位的一個常見用途是用于passwd命令之類的命令。如果你看一下/usr/bin/passwd文件,會注意到SUID位已設置,允許你更改密碼(因而更新/etc/shadow文件的內容),即使你以普通(非特權)用戶的身份來運行,對該文件沒有讀取或寫入權限。當然,passwd命令很聰明,不允許你更改其他人的密碼,除非你實際上以root的身份運行或使用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
現在,不妨看一下可以用這些特殊權限做什么。
如何分配特殊文件權限 ?
與Linux命令行上的許多內容一樣,你在如何發出請求方面有一些選擇。chmod命令讓你可以以數字方式或使用字符表達式來更改權限。
想以數字方式更改文件權限,可以使用這樣的命令來設置setuid位和setgid位:
- $ chmod 6775 tryme
或者可以使用這樣的命令:
- $ chmod ug+s tryme <== for SUID and SGID permissions
如果添加特殊權限的文件是腳本,你可能會驚訝于它未符合你的期望。這是個很簡單的例子:
- $ cat tryme
- #!/bin/bash
- echo I am $USER
即使SUID位和SGID位已設置,這個文件是root擁有的文件,運行這樣的腳本也不會帶來你可能預計的“我是root”響應。為什么?因為Linux忽略腳本上的set-user-ID位和set-group-ID位。
- $ ls -l tryme
- -rwsrwsrwt 1 root root 29 May 26 12:22 tryme
- $ ./tryme
- I am jdoe
另一方面,如果你使用編譯的程序嘗試類似的操作,就像這個簡單的C程序一樣,會看到不同的效果。在該示例程序中,我們提示用戶輸入文件并為其創建文件,并將寫入權限賦予文件。
- #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;
- }
一旦你編譯程序,運行命令使root成為所有者并設置所需的權限后,你會看到它以預期的root權限運行,留下新創建的root擁有的文件。當然,你必須擁有sudo權限才能運行一些所需的命令。
- $ 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權限運行,不會發生這種情況。
權限字符串(比如rwsrwsrwt)中不常見設置的位置可以幫助提醒我們每個位的含義。至少***個“s”(SUID)位于所有者權限區域,第二個(SGID)位于組權限區域。為什么粘性位是“t”而不是“s”不在本文的探討范圍。無論如何,額外的權限設置為Linux及其他Unix系統提供了許多附加功能。
原文標題:A deeper dive into Linux permissions,作者:Sandra Henry-Stocker
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】