文件特殊权限与应用
inux中除了常见的读(r)、写(w)、执行(x)权限以外,还有3个特殊的权限,分别是setuid、setgid和stick bit。如下图:
图3-1
一、特殊权限设置
setuid:chmod u+s xxx ;表现形式:[-rwsr-xr-x];
setgid: chmod g+s xxx ;表现形式:[-rwxr-sr-x];
stick bit : chmod o+t xxx ;表现形式:[-rwxr-xr-t];
或者:
setuid:chmod 4755 xxx
setgid:chmod 2755 xxx
stick bit:chmod 1755 xxx
二、先来简单了解进程的一些知识点
特殊权限位是与控制进程运行有关的,linux的进程至少有7个与之相关的标识:
一个真实UID(real UID)、一个真实GID(read GID);
一个有效UID(effectiveUID)、一个有效GID(effective GID);
一个保存UID(saved UID)、一个保存GID(saved GID);
一个文件系统UID(filesystemUID)。
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。这个例子,请看下面的【例1】、【例2】、【例3】里面有/bin/touch命令的操作,可用来解释!
还有一个例子就是passwd命令,其程序命令的映像文件的UID/GID都是root,但是当一个普通用户运行这个命令时(因为passwd可执行文件设置了其他人的执行权限),则这个用户开启的passwd命令进程的EUID/EGID=root而非该普通用户。既然setuid和setgid设置后的进程的EUID/EGID不是进程启动者的UID/GID,而是进程映像文件所有者的UID/GID,故该程序“所产生的任何操作的身份都是这个虚拟”身份,即都是EUID/EGID。
三
Set UID
当 s 这个标志出现在文件拥有者的 x 权限上时,是为了让一般用户在执行某些程序的时候,能够暂时具有该程序拥有者的权限。
常见场景:该位是让普通用户可以以root用户的角色运行只有root帐号才能运行的程序或命令。如下,passwd命令普通用户运行也起效果!
[root@localhost ~]# ll /usr/bin/passwd //普通用修改密码的命令
-rwsr-xr-x 1 root root 23420 Aug 3 2010/usr/bin/passwd //s权限
例1:有s权限,使用命令(/usr/bin/passwd)时,普通用户(rabbit)可用该命令拥有者(root)的权限去执行(打开/etc/shadow文件,保存用户的修改后的密码)。
[root@localhost ~]# ll /etc/shadow //存储用户密码文件
-r-------- 1 root root 1037 Nov 16 15:52/etc/shadow //普通用户没rw权限
[rabbit@localhost ~]$ /usr/bin/passwd
Changing password for user rabbit.
Changing password for rabbit
(current) UNIX password:
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
注意:特殊权限setuid的标志s会出现在x的地方[-rwsr-xr-x],s权限只能应用在二进制的可执行文件上才有意义。
其次,有时你设置了s或t 权限,你会发现它变成了S或T,这是因为在那个位置上你没有给它x(可执行)的权限,这样的话这样的设置是不会有效的,你可以先给它赋上x的权限,然后再给s或t 的权限。
图3-2
例2:新增s权限,让普通用户能读取/etc/shadow文件
[root@localhost ~]# ll /bin/cat
-rwxr-xr-x 1 root root 23132 Feb 23 2010 /bin/cat //cat程序无s权限
[root@localhost ~]# su rabbit
[rabbit@localhost root]$ cd ~
[rabbit@localhost ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied //读取被拒绝
//用root账号给/bin/cat增加setuid位,如下:
[rabbit@localhost ~]$ su root
Password:
[root@localhost rabbit]# chmod u+s /bin/cat //新增s权限
[root@localhost rabbit]# ll /bin/cat
-rwsr-xr-x 1 root root 23132 Feb 23 2010 /bin/cat //有s权限了
[root@localhost rabbit]# su rabbit
[rabbit@localhost ~]$ cat /etc/shadow //读取文件成功
root:$1$rFRCj/Fd$yRqoBC20eKpCJzghKt7Wh/:16751:0:99999:7:::
bin:*:16751:0:99999:7:::
……
Set GID
当 s 这个标志出现在文件群组的 x 权限上时,与 SUID 不同的是,SGID 可以针对二进制可执行文件或目录来配置。
①Set GID对二进制可执行文件时,一般用户在执行某些程序的时候,能够暂时具有该程序群组的权限。看如下案例:
例3、默认touch是没有设置setuid和setgid的,那么用户执行touch后的文件的UID/GID都是touch发起者的UID/GID。如下:
[rabbit@localhost ~]$ ls -l /bin/touch
-rwxr-xr-x 1 root root 42284 Feb 23 2010 /bin/touch
[rabbit@localhost ~]$ touch a.txt
[rabbit@localhost ~]$ ls -l
total 4
-rw-r--r-- 1 rabbit rabbit 0 Nov 16 23:36a.txt
//用root账号给touch增加setgid位,如下:
[rabbit@localhost ~]$ su root
Password:
[root@localhost rabbit]# chmod g+s /bin/touch
[root@localhost rabbit]# ls -l /bin/touch
-rwxr-sr-x 1 root root 42284 Feb 23 2010 /bin/touch //有s权限
//然后,普通用户(rabbit)再次touch新文件,发现文件的属组也发生了变化,如下:
[root@localhost rabbit]# su rabbit
[rabbit@localhost ~]$ touch b.txt
[rabbit@localhost ~]$ ls -l
total 8
-rw-r--r-- 1 rabbit rabbit 0 Nov 16 23:36a.txt
-rw-r--r-- 1 rabbit root 0Nov 16 23:41 b.txt //root为touch执行程序的群属组,而非执行该程序的用户的群组(rabbit)
②Set GID对于目录时,在某个目录上设置了setgid权限位后,在这个目录下创建的文件具有与该目录的属组权限,而不是创建该文件的用户的属组。当然对目录设置setuid,是不起任何作用的。看下面这个例子:
例4、
[rabbit@localhost ~]$ mkdir a
[rabbit@localhost ~]$ mkdir b
[rabbit@localhost ~]$ mkdir c
[rabbit@localhost ~]$ ll -l
total 24
drwxr-xr-x 2 rabbit rabbit 4096 Nov 16 23:52a
drwxr-xr-x 2 rabbit rabbit 4096 Nov 16 23:52b
drwxr-xr-x 2 rabbit rabbit 4096 Nov 16 23:52c
//root用户给这三个目录分别加上权限
[root@localhost rabbit]# chmod u+s /home/rabbit/a //设置suid
[root@localhost rabbit]# chmod g+s /home/rabbit/b //设置sgid
[root@localhost rabbit]# chmod +s /home/rabbit/c //设置suid+sgid
[root@localhost rabbit]# ll
total 24
drwsr-xr-x 2 rabbit rabbit 4096 Nov 16 23:52 a //目录a有suid权限
drwxr-sr-x 2 rabbit rabbit 4096 Nov 16 23:52 b //目录b有sgid权限
drwsr-sr-x 2 rabbit rabbit 4096 Nov 16 23:52 c //目录c有suid、sgid权限
//利用root用户新建文件,只有setgid位起到了作用,如下:
[root@localhost rabbit]# ll -l /bin/touch
-rwxr-sr-x 1 root root 42284 Feb 23 2010 /bin/touch //文件uid/gid=root
[root@localhost rabbit]# touch a/s.txt
[root@localhost rabbit]# touch b/s.txt
[root@localhost rabbit]# touch c/s.txt
[root@localhost rabbit]# ls -l a/
-rw-r--r-- 1 root root 0 Nov 17 00:01 s.txt //suid权限无效
[root@localhost rabbit]# ls -l b/
-rw-r--r-- 1 root rabbit 0 Nov 17 00:01 s.txt // sgid权限有效
[root@localhost rabbit]# ls -l c/
-rw-r--r-- 1 root rabbit 0 Nov 17 00:01 s.txt // suid权限无效、sgid权限有效
SBIT:
SBIT 目前只对目录有效,对文件已没有效果。将给目录加上了SBIT权限时, 则用户只能够针对自己创建的文件或目录进行删除/更名/移动等动作(前提:该用户对目录具有 w, x 权限,即写入权限),而无法删除他人的文件。root用户除外!
例5:新建共享目录给rabbit和test用户使用,他们可以在里面新建文件与目录,但不能修改、删除他人的文件。
[root@localhost /]# mkdir /test
[root@localhost /]# chmod o+w,g+w,o+t test //给目录设置SBIT
[root@localhost /]# ll -d test
drwxrwxrwt 2 root root 4096 Nov 17 09:13 test
//rabbit用户登录 新建文件/test/a.txt,修改文件权限777
[root@localhost test]# su rabbit
bash-3.2$ touch /test/a.txt
bash-3.2$ ls -l /test/a.txt
-rw-r--r-- 1 rabbit rabbit 0 Nov 17 09:22/test/a.txt
bash-3.2$ chmod 777 /test/a.txt
bash-3.2$ ls -l /test/a.txt
-rwxrwxrwx 1 rabbit rabbit 0 Nov 17 09:22/test/a.txt //空文件a.txt已存在
//test用户登录,做查看、修改文件内容、删除文件等实验。
[root@localhost rabbit]# su test
[test@localhost ~]$ cd /test
[test@localhost test]$ vi a.txt //可编辑文件、保存文件内容
[test@localhost test]$ cat a.txt //可查看文件内容
this is test`
[test@localhost test]$ cp a.txt b.txt //可复制文件
[test@localhost test]$ ll
-rwxrwxrwx 1 rabbit rabbit 14 Nov 17 09:30a.txt
-rwxrwxr-x 1 test test 14 Nov 17 09:48 b.txt
[test@localhost test]$ rm a.txt
rm: cannot remove `a.txt': Operation notpermitted //不可删除文件
[test@localhost test]$ mv a.txt /home/test/
mv: cannot remove `a.txt': Operation notpermitted //不可移动文件
//root用户可以删除文件
图3-3