Linux中,用户的权限一般会根据用户的uid和gid来确定,但是在运行的时候,系统根据的是用户的有效uid和有效gid,本来的话,在执行文件前,用户的uid和gid是也就是用户的有效uid和有效gid,这也就决定了用户的权限,但是,当文档设置了suid和sgid后,用户的有效uid和gid将会改变,这也就是suid和sgid的功能。
其实在UNIX的实现中,文件权限用12个二进制位表示,如果该位置上的值是1,表示有相应的权限:1
2
311 10 9 8 7 6 5 4 3 2 1 0
S G T r w x r w x r w x
第11位为SUID位,第10位为SGID位,第9位为sticky位,第8-0位对应于上面的三组rwx位。
给文件加SUID和SUID的命令如下:1
2
3
4
5
6
7chmod u+s filename 设置SUID位
chmod u-s filename 去掉SUID设置
chmod g+s filename 设置SGID位
chmod g-s filename 去掉SGID设置
另外一种方法是chmod命令用八进制表示方法的设置。如果明白了前面的12位权限表示法也很简单。如 chmod 2770 filename
,将filename文件设置权限为rwxrws---
,此时的sgid位有效,如果为chmod 2760 filename
, 将filename文件设置权限为rwxrwS---
,此时sgid无效。
suid只对可执行文件有意义,sgid只对目录和可执行文件有意义。suid和sgid起作用的前提是,调用者对文件有执行权限,对目录有写以及执行权限,否则的话,即使设置了suid和sgid位,都会无效。
由于SUID和SGID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件和目录文件有意义,所以设置其他种类文件的SUID和SGID位是没有多大意义的。
当可执行文件设置了suid后,调用者在运行该文件的时候(前提是调用者有运行该文件的权限),将会暂时获得该文件拥有者的权限,此时调用者的有效uid就是文件拥有者的uid,例如,使用如下命令:1
ls -l /usr/bin/passwd
我们会得到如下的结果:1
-rwsr-xr-x 1 root root 42824 Sep 13 2012 /usr/bin/passwd
可以看到,在文件拥有者的执行位上出现为s而不是x,所以说passwd这个程序是具有SUID权限的。我们知道在修改用户密码的时候,用的就是passwd这个命令,而我们又知道在linux下面,用户密码是存储在/etc/shadow这个文件里面的。首先查看一下/etc/shadow这个文件的权限:1
ls -l /etc/shadow
返回的结果如下:1
-rw-r----- 1 root shadow 1138 Dec 13 20:00 /etc/shadow
由上面的结果,我们知道只有root可以往shadow文件中写入数据,其他用户连查看的权限都没有。那我们平时是怎么修改密码呢?没错,就是和SUID有关。当我们使用passwd命令时,就获得了passwd的所有者即root的权限,进而可以对shadow文件进行写入操作。
SGID即Set GID的缩写,它出现在文件所属组权限的执行位上面,它对普通二进制文件和目录都有效。当它作用于普通文件时,和SUID类似,在执行该文件时,用户将获得该文件所属组的权限。当SGID作用于目录时,意义就非常重大了。当用户对某一目录有写和执行权限时,该用户就可以在该目录下建立文件,如果该目录用SGID修饰,则该用户在这个目录下建立的文件都是属于这个目录所属的组。
SBIT即Sticky Bit,它出现在其他用户权限的执行位上,它只能用来修饰一个目录。当某一个目录拥有SBIT权限时,则任何一个能够在这个目录下建立文件的用户,该用户在这个目录下所建立的文件,只有该用户自己和root可以删除,其他用户均不可以。例如:1
ls -ld /tmp
可以得到以下结果:1
drwxrwxrwt 12 root root 12288 Dec 17 16:33 /tmp