首页 > 代码库 > linux文件权限
linux文件权限
Linux文件权限
每个文件属于一个用户和一个组。这正是 Linux 中权限模型的核心。每个文件都有10元组表示文件的类型和文件所有者、文件所属组用户、其它用户对该文件的操作权限。
例如一个普通文件的10元组
-rwxr-xr-x 1 root wheel 430540 Dec 23 18:27 /bin/bash
该字段中的首字符(-)指定该文件的类型,本例中它是一个常规文件,字段的其余部分由三个三元组字符组成。第一个三元字符组代表文件所有者的权限(读、写、执行),第二个代表文件的组的权限(读、执行),第三个代表所有其他用户的权限(读、执行)
目录的权限
当从目录的角度看权限时,情况有一点不同。目录使用同样的权限标志,但是它们被解释为表示略微不同的含义。 对于一个目录,如果设置了“read”标志,您可以列出目录的内容;“write”表示您可以在目录中创建文件,“execute”表示您可以进入该目录并访问内部的任何子目录。没有“execute”标志,目录内的文件系统对象是不可访问的,目录的执行权限位被称为搜索位。没有“read”标志,目录内的文件系统对象是不可查看的,但是只要有人知道磁盘上对象的完整路径,就仍然可以访问目录内的对象。
进程操作权限
我们知道了不同用户对文件的操作权限不同?那么操作系统如何判断一个应用程序是否有相应的权限操作相应的文件呢?
实际上,每个进程会维护有如下6个ID:
真实身份: real UID, real GID
有效身份: effective UID, effective GID
存储身份:saved UID, saved GID
其中,真实身份是我们登录使用的身份,有效身份是当该进程真正去操作文件时所检查的身份
当进程fork的时候,真实身份和有效身份都会复制给子进程。大部分情况下,真实身份和有效身份都相同。当Linux完成开机启动之后,init进程会执行一个login的子进程。我们将用户名和密码传递给login子进程。login在查询了/etc/passwd和/etc/shadow,并确定了其合法性之后,运行(利用exec)一个shell进程,shell进程真实身份被设置成为该用户的身份。由于此后fork此shell进程的子进程都会继承真实身份,所以该真实身份会持续下去,直到我们登出并以其他身份再次登录(当我们使用su成为root的时候,实际上就是以root身份再次登录,此后真实身份成为root)。
存储身份就是真实身份之外的另一个身份。当我们将一个程序文件执行成为进程的时候,该程序文件的拥有者(owner)和拥有组(owner group)可以被,存储成为进程的存储身份。在随后进程的运行过程中,进程就将可以选择将真实身份或者存储身份复制到有效身份,以拥有真实身份或者存储身份的权限。并不是所有的程序文件在执行的过程都设置存储身份的。需要这么做的程序文件会在其九位(bit)权限的执行位的x改为s。这时,这一位(bit)叫做set UID bit或者set GID bit。
当设置了一个可执行程序的“suid”这一位时,它将代表可执行文件的所有者运行,而不是代表启动程序的人运行。将程序的有效用户ID,设置为文件的用户ID,而不是启动这个程序的用户ID,并将文件的用户ID保存到存储用户ID中。
例如,若文件的所有者是root用户,并且设置了该文件的设置用户ID位,那么无论任何用户启动这个程序是,程序的有效用户ID都可以root,就拥有root权限操作文件。
进程每次打开、创建删除一个文件,内核就对文件进行权限设置
1. 若进程的有效用户ID是0(超级用户),则允许访问。
2. 若进程的有效用户ID等文件的所有者ID,那么所有者适当的访问权限位被设置则允许访问,否则拒绝访问。(不会再去判断程序的组ID是否有相应的权限了,即使组用户或者其它用户有相应的访问权限)
3. 若进程的有效组ID等于文件的组ID,若组适当的访问权限位被设置,则允许访问,否则拒绝访问。 (不会再查看其它用户的访问权限了)
4. 查看其它用户的适当权限位
我们用名字打开任一类型的文件时,对该名字包含的每一个目录,都应具有执行权限
例如为了打开文件/home/ghbai/test.h,需要对目录/、/home、/home/ghbai具有执行权限
为了删除一个文件需要有该文件所在目录的写权限执行权限,对该文件本身则不需要有任何权限
为了在一个目录下创建一个新文件,必须对该目录具有写权限执行权限
新文件
当创建一个新文件时,文件的用户ID设置为进程的有效用户ID
在linux新创建用户的组ID取决于它所在的目录的设置组ID位是否设置(我们前面谈到对可执行文件的设置ID,设置组ID,可执行文件和目录的设置组ID位表示的意思不一样),如果目录的这一位已经设置,新文件的组ID设置为目录的组ID,否则新文件的组ID就是进程的有效组ID
umask
1. 进程创建一个文件或者新目录时,就会使用文件模式创建屏蔽字,umask函数为进程设置文件模式创建屏蔽字
Linux 系统上,umask 的缺省值一般为 0022,它允许其他人读您的新文件(如果他们可以
得到它们),但是不能进行修改。
为了在缺省的情况下使新文件更安全,您可以改变 umask 设置:
$ umask 0077
umask 将确保组和其他用户对于新创建的文件绝对没有任何权限。那么,umask 怎样工作呢?
与文件的“常规”权限不同,umask 指定应该关闭哪一个权限。
在程序使用umask函数
#include<sys/stat.h>
Mode_t umask(mode_t cmask);
2. 更改进程的文件模式创建屏蔽字并不影响父进程
3. 创建的新目录必须有执行权限
Chmod chown chgrp
1. Chmod可以改变文件的权限,但是只有文件所有者或者root用户才有权限对一个文件执行chmod
2. Chown可以改变文件所有者,只有root用户才有权限使用chown改变文件的所有者
3. Chgrp可以改变文件所属组,只有文件的拥有者才有权限改变文件的组ID,而且只能改变文件的组ID到文件拥有者所在的组
目录粘滞位
缺省情况下,Linux 目录以一种不是在所有情况下都很理想的方式表现。一般来说,只要对一个
目录有写访问权,任何人都可以重命名或删除该目录中的文件。对于个别用户使用的目录,这种行
为是很合理的。
但是,对于很多用户使用的目录来说,尤其是 /tmp 和 /var/tmp,这种行为可能会产生麻烦。
因为任何人都可以写这些目录,任何人都可以删除或重命名任何其他人的文件 — 即使是不属于
他们的!显然,当任何其他用户在任何时候都可以输入“rm -rf /tmp/*”并损坏每个人的文
件时,很难把 /tmp 用于任何有意义的文件。
所幸,Linux 有叫做“粘滞位”(sticky bit)的东西。当给 /tmp 设置了粘滞位(用
chmod +t),唯一能够删除或重命名 /tmp 中文件的是该目录的所有者(通常是 root用户)
、文件的所有者或 root用户。事实上,所有 Linux 分发包都缺省地启用了 /tmp 的粘滞位,
而您还可以发现粘滞位在其它情况下也很管用。
参考文献:
1. http://www.cnblogs.com/vamei/tag/Linux/
2. 《unix环境高级编程》
3. http://zhangfeikr.blog.51cto.com/1999170/396541