分类: LINUX
2010-01-04 12:43:46
用户在 UNIX 系统下经常会遇到SUID、SGID的概念,而且SUID和SGID涉及到系统安全,所以用户也比较关心这个问题。
SUID 是 Set User ID, SGID 是 Set Group ID的意思。
UNIX 系统下可以用ls -l 命令来看到文件的权限。用 ls -l 命令所得到的表示法的格式是类似这样的:-rwxr-xr-x 。下面解析一下格式所表示的意思。这种表示方法一共有十位:
9 8 7 6 5 4 3 2 1 0 - r w x r - x r - x
第9位表示文件类型,可以为p、d、l、s、c、b和-:
p 表示命名管道文件 d 表示目录文件 l 表示符号连接文件 - 表示普通文件 s 表示socket文件 c 表示字符设备文件 b 表示块设备文件
第8-6位、5-3位、2-0位分别表示文件所有者的权限,同组用户的权限,其他用户的权限,其形式为 rwx:
r 表示可读,可以读出文件的内容 w 表示可写,可以修改文件的内容 x 表示可执行,可运行这个程序 没有权限的位置用 - 表示
例子,ls -l myfile 显示为:
-rwxr-x--- 1 foo staff 7734 Apr 05 17:07 myfile
表示文件 myfile 是普通文件,文件的所有者是 foo 用户,而 foo 用户属于 staff 组,文件只有 1 个硬连接,长度是 7734 个字节,最后修改时间4月5日17:07。
所有者 foo 对文件有读写执行权限,staff 组的成员对文件有读和执行权限,其他的用户对这个文件没有权限。
如果一个文件被设置了 SUID 或 SGID 位,会分别表现在所有者或同组用户的权限的可执行位上。例如:
1、-rwsr-xr-x 表示SUID和所有者权限中可执行位被设置 2、-rwSr--r-- 表示SUID被设置,但所有者权限中可执行位没有被设置 3、-rwxr-sr-x 表示SGID和同组用户权限中可执行位被设置 4、-rw-r-Sr-- 表示SGID被设置,但同组用户权限中可执行位没有被设置
那么原来的执行标志x到哪里去了呢? 系统是这样规定的, 如果本来在该位上有x, 则这些特殊标志显示为小写字母 (s, s, t). 否则, 显示为大写字母 (S, S, T)
其实在UNIX的实现中,文件权限用12个二进制位表示,如果该位置上的值是 1,表示有相应的权限:
11 10 9 8 7 6 5 4 3 2 1 0 U G T r w x r w x r w x
第11位为 SUID 位,第10位为 SGID 位,第9位为 sticky 位,第8-0位对应于上面的三组 rwx 位。
sticky bit: 粘帖位。对于”粘贴位”的一般了解, save-text-mode标志是一个文件权限的特殊类型. 如果文件设置了这个标志, 那么这个文件将会被保存到缓存中, 这样可以提高访问速度. (在当代UNIX系统中, 文件中已经不使用粘贴位了, 粘贴位只使用在目录中.) 粘贴位如果设置在目录中, 那么它将限制写权限. 对于设置了粘贴位的文件或目录, 在它们的权限标记列中将会显示t.
$ ls -dl /tmp/ drwxrwxrwt 15 root root 20480 2009-10-02 15:00 /tmp/
如果用户并不拥有这个设置了粘贴位的目录, 但是他在这个目录下具有写权限, 那么这个用户只能在这个目录下删除自己所拥有的文件. 这将有效的防止用户在一个公共目录中不慎覆盖或者删除别人的文件. 比如说/tmp目录. (当然, 目录的所有者或者root用户可以随意删除或重命名其中的文件.)
上面的 -rwsr-xr-x 的值为: 1 0 0 1 1 1 1 0 1 1 0 1
-rw-r-Sr– 的值为: 0 1 0 1 1 0 1 0 0 1 0 0
(可以用 4 位八进制数来表示,每 3 位二进制数组合成 1 位八进制数)
下面说一下如何操作这些标志:
操作这些标志与操作文件权限的命令是一样的, 都是 chmod. 有两种方法来操作,
chmod u+s filename 设置SUID位 chmod u-s filename 去掉SUID设置 chmod g+s filename 设置SGID位 chmod g-s filename 去掉SGID设置
采用八进制方式. 对一般文件通过三组八进制数字来置标志, 如 666, 777, 644等. 如果设置这些特殊标志, 则在这组数字之外外加一组八进制数字. 如 4666,2777等. 这一组八进制数字三位的意义如下:
abc a - setuid位, 如果该位为1, 则表示设置setuid b - setgid位, 如果该位为1, 则表示设置setgid c - sticky位, 如果该位为1, 则表示设置sticky
由于SUID和SGID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件和目录文件有意义,所以设置其他种类文件的SUID和SGID位是没有多大意义的。
首先讲普通文件的SUID和SGID的作用。例子:
如果普通文件 myfile 是属于 foo 用户的,是可执行的,现在没设SUID位,ls -l 命令显示如下:
-rwxr-xr-x 1 foo staff 7734 Apr 05 17:07 myfile
任何用户都可以执行这个程序。UNIX的内核是根据什么来确定一个进程对资源的访问权限的呢?是这个进程的运行用户的 ID(即实际用户 ID),包括 user id 和 group id。用户可以用 id 命令来查到自己的或其他用户的 user id 和 group id。
除了一般的 user id 和 group id 外,还有两个称之为 effective 的 ID(即有效用户 ID)。这四个 id 表示为:uid、gid,euid、egid。内核主要是根据 euid 和 egid 来确定进程对资源的访问权限。
一个进程如果没有SUID或SGID位,则 euid=uid、egid=gid,分别是运行这个程序的用户的 uid 和 gid。例如 kevin 用户的 uid 和 gid 分别为 204 和 202,foo 用户的 uid 和 gid 为 200,201,kevin运行myfile程序形成的进程的 euid=uid=204、egid=gid=202,内核根据这些值来判断进程对资源访问的限制,其实就是 kevin 用户对资源访问的权限,和 foo 没关系。
如果一个程序设置了SUID,则 euid 和 egid 变成被运行的程序的所有者的 uid 和 gid,例如kevin用户运行 myfile,则euid=200、egid=201,uid=204、gid=202,则这个进程具有它的属主 foo 的资源访问权限。
SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源。passwd 就是一个很鲜明的例子。SUID的优先级比SGID高,当一个可执行程序设置了SUID,则SGID会自动变成相应的 egid。
下面讨论一个例子:
UNIX系统有一个 /dev/kmem 的设备文件,是一个字符设备文件,里面存储了核心程序要访问的数据,包括用户的口令。所以这个文件不能给一般的用户读写,权限设为:
cr--r----- 1 root system 2, 1 May 25 1998 kmem
但 ps 等程序要读这个文件,而 ps 的权限设置如下:
-r-xr-sr-x 1 bin system 59346 Apr 05 1998 ps
这是一个设置了SGID的程序,而 ps 的用户是 bin,不是 root,所以不能设置SUID来访问 kmem,但大家注意了,bin 和 root 都属于 system 组,而且 ps 设置了SGID,一般用户执行 ps,就会获得 system 组用户的权限,而文件 kmem 的同组用户的权限是可读,所以一般用户执行ps就没问题了。但有些人说,为什么不把 ps 程序设置为 root 用户的程序,然后设置SUID位,不也行吗?这的确可以解决问题,但实际中为什么不这样做呢?因为SGID的风险比SUID小得多,所以出于系统安全的考虑,应该尽量用SGID代替SUID的程序,如果可能的话。
下面来说明一下SGID对目录的影响:SUID对目录没有影响。如果一个目录设置了SGID位,那么如果任何一个用户对这个目录有写权限(还得有执行的权限才能进入到该目录)的话,他在这个目录所建立的文件的组都会自动转为这个目录的属主所在的组,而文件所有者不变,还是属于建立这个文件的用户。