文件模式设置用户ID/设置组ID/sticky bit_转
S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
S_ISGID (02000) set-group-ID (set process effective group ID on execve(2); mandatory locking, as described in fcntl(2);
take a new file's group from parent directory, as described in chown(2) and mkdir(2))
S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))
Linux的文件,有个16位的字来表示文件的类型和属性信息,其中4位表示文件的类型信息,剩下的12位表示文件的模式。
在传统的unix和linux文件系统模型中,每个文件都有一个9个权限位用来控制谁能够读写和执行该文件内容,还有一个3个权限位来影响可执行程序运行,这12个位就共同构成了该文件的“模式”(mode)。
权限位
9个权限位就分别被分成3组,每组有3位。最前面的一组3位控制属主的访问权限,第二个三位组控制组的访问权限,最后的三位组控制其他每个人访问权限。在每个3位组中,高位是读取位,中间位是写入位,低位是执行位。
在普通文件上,读取位允许打开文件并读取它的内容。写入位允许修改和删截该文件的内容。不过,能否删除和重命名(或者删除后再建)该文件则由该文件的父目录上的权限设置所控制,因为名字到数据空间的映射关系实际上存储在父目录中。执行位表示该文件是否是可执行的。
对于目录来说,其实也是文件文件,只是有点不同。当分析路径名时,执行位(在这种上下文环境中,也经常叫做“搜索(search)”位或者叫做“扫描(scan)”位)的作用是控制是否能够进入或者通过该目录,读取位和执行位的组合作用才是控制是否列出目录的内容,写入位和执行位的组合作用则表示是否允许在目录中创建、删除和重命名文件。
setuid和setgid位
3个特殊权限位是控制进程运行时的表现的,这3位中高位是setuid位,中间位是setgid位,低位是sticky位(粘附位)。在继续探讨这3个位之前,我们先来简单介绍一些辅助信息。
linux的进程至少有7个与之相关的标识:一个真实 UID(real UID)、一个有效UID(effective UID)和一个保存UID(saved UID);一个真实GID(read GID)、一个有效GID(effective GID)和一个保存GID(saved GID);还有一个文件系统UID(filesystem UID)。
简单的说,read UID/GID就是进程创建者的UID/GID。EUID(effective UID)/EGID用来确定进程在任何给定的时刻对哪些资源或者文件具有访问权限,即进程在运行时其当前的“虚拟身份”,也就是说在进程运行时候其UID 和GID可能不是创建它的用户的UID和GID,但是在一般情况下,UID/GID和EUID/EGID是一样的。SUID(saved UID)/SGID(saved GID)表示进程刚刚开始执行时刻,进程EUID/EGID的副本。而FSUID(filesystem UID),它只用来对文件系统权限的判断,但在内核之外并不常用。
尽管通常对于一个进程来说不大可能会改变它自己的归属关系状态(即默认情况UID/GID=EUID/EGID),但在一种特殊情况下,可以修改进程的EUID和EGID。当 执行设置了setuid和setgid的权限位的命令时,则当该命令运行时,其EUID/EGID为该程序命令的映像文件的UID或者GID,而不是启动运行该命令的用户UID/GID。一个例子就是passwd命令,其程序命令的映像文件的UID/GID都是root,但是当一个普通用户运行这个命令时 (因为passwd可执行文件设置了其他人的执行权限),则这个用户开启的passwd命令进程的EUID/EGID=root而非该普通用户。
既然setuid和setgid设置后的进程的EUID/EGID不是进程启动者的UID/GID,而是进程映像文件所有者的UID/GID,故该程序所产生的任何操作的“身份”都是这个“虚拟身份”,即EUID/EGID。
举个例子touch
默认情况:
~$ls /bin/touch -al
-rwxr-xr-x 1 root root 55080 Jan 14 2015 /bin/touch
~$touch wang
~$ls -al wang
-rw-rw-r-- 1 yuxi yuxi 0 Jul 29 18:49 wang
setuid
~$sudo chmod u+s /bin/touch
[sudo] password for yuxi:
~$ls -al /bin/touch
-rwsr-xr-x 1 root root 55080 Jan 14 2015 /bin/touch
~$rm wang
~$touch wang
~$ls -al wang
-rw-rw-r-- 1 root yuxi 0 Jul 29 18:52 wang
setuid+setgid
~$sudo chmod g+s /bin/touch
~$rm wang
~$touch wang
~$ls -al wang
-rw-rw-r-- 1 root root 0 Jul 29 18:54 wang
简单的总结一下,就是setuid和setgid是让程序执行的时候“临时的”的拥有了程序文件所有者的uid和gid,等程序执行完后再恢复到发起者的权限。
对于目录,如果在某个目录上设置了setgid位以后,在这个目录中创建的文件具有该目录的属组权限而不是创建该文件的用户的默认属组。至于对目录设置setuid,是不起任何作用的。
~$mkdir a b c
~$chmod u+s a
~$chmod g+s b
~$chmod +s c
~$ls -al
total 20
drwxrwxr-x 5 yuxi yuxi 4096 Jul 29 19:00 .
drwxrwxrwt 7 root root 4096 Jul 29 18:48 ..
drwsrwxr-x 2 yuxi yuxi 4096 Jul 29 19:00 a
drwxrwsr-x 2 yuxi yuxi 4096 Jul 29 19:00 b
drwsrwsr-x 2 yuxi yuxi 4096 Jul 29 19:00 c
-rw-rw-r-- 1 root root 0 Jul 29 18:54 wang
~$touch a/u
~$touch b/u
~$touch c/u
~$ls -l a b c
a:
total 0
-rw-rw-r-- 1 root root 0 Jul 29 19:04 u
b:
total 0
-rw-rw-r-- 1 root yuxi 0 Jul 29 19:04 u
c:
total 0
-rw-rw-r-- 1 root yuxi 0 Jul 29 19:04 u
sticky bit
mode中特殊权限位的低位就是sticky位,称为“粘附位”。在早期的unix系统上,它作为限定符对于可执行文件来说很重要。不过,粘附位的含义现在已经过时了,现在操作系统已经悄然地忽略了它。
如果在目录上设置了这个粘贴位,那么除非您是该目录的属主、该文件的属主或者是超级用户,否则文件系统不会允许删除或者重新命令该目录中的文件。
mode的八进制表示法
八进制表示:在数字前加0,如0777表示八进制777,printf标记为%o。
mode的12位根据上面的探讨,都是每三位分成一个组合,那么刚好可以使用4个八进制来表示这12位数字。
先不看特殊权限位,在9个用户访问权限位上,前面3位代表控制属主的访问权限,读、写、执行权限对应的八进制分别为400、200、100;第二个3位控
制组的访问权限,读、写、执行权限对应的八进制分别为40、20、10;第三个3位控制其他每个人的访问权限,读、写、执行权限对应的八进制分别为4、
2、1。
再看特殊权限位中的3位,由于setuid、setgid、sticky分别是高、中、低3位,那么其对应的八进制表示就是4000、2000、1000。
通过上面的介绍,举例来解释下。文件如果设置了4721权限,表示设置了setuid位,同时文件属主拥有读写执行权限,文件的属组成员拥有写权限,其他
人拥有执行权限。7542则表示设置了setuid、setgid、sticky位,同时文件属主拥有读和执行权限,文件属组成员拥有读权限,其他人拥有
写权限。
mode的助记表示法
更改文件的权限,使用chmod命令,查看用户权限可以使用ls -l命令,这2中命令都接受助记表示法。
助记表示法,简单的说就是,用 u 代表文件属主(user),用 g 代表属组(group),用字母 o
代表其他人(other),用a代表所有人(all)。用 r 代表读权限(read),用 w 代表写权限(write),用 x
代表执行权限(execute)。用加号 + 表示给文件增加权限,用减号 - 表示给文件减少权限,用等号 =
表示给文件直接赋予某些权限。如下面这些例子:
u+w 为文件的属主添加写入权限
ug=rw,o=r 赋予属主和属组读取写入权限,赋予其他人读取权限
a-x 删除全部3种类别用户的执行权限
g=u 让属组的权限跟属主的权限完全一样。
剩下3个特殊权限该怎么表示呢?
用s表示setuid和setgid位,用t表示sticky位。当给属主增加s权限的时候(即
u+s),就表示设置了setuid位,在展现时属主组的x权限会被s权限代替。当给属组增加s权限的时候(即
g+s),就表示设置了setgid位,在展现的时候属组组的x权限会被s权限代替。当增加t权限的时候(即 +t 或者
o+t),即设置了sticky位,在展现的时候其他人组的x权限会被t权限代替。
如果设置了setuid、setgid或sticky中的一个,但是又没有设置相应的执行权限,那么这些位显示为S或T。
在linux系统中,系统自动跟踪文件的修改时间戳、链接数目(可使用ls -i命令查看)和文件大小信息的变化。但是,文件的权限位、归属关系和属组权只有当它们分别采用chmod、chown、chgrp命令修改时才会改变。
umask:分配默认的权限
用户可以使用内建的shell命令umask来影响分配给新创建文件的默认权限。umask用一个三位数字八进制形式来指定,这个值代表要“剥夺”的权限。当创建文件的时候,它的权限就设置为创建程序请求的任何权限去掉umask禁止的权限。
额外的标志
Linux的ext2和ext3文件系统定义了一些补充属性,您可以打开它们来请求获得特殊的文件系统语义。但是这些标志不能用于ext*系列以外的其他文件系统,所以linux使用了特殊命令lsattr和chattr来查看或者改变它们。