深入了解UNIX文件权限

Linux 同时被 2 个专栏收录
5 篇文章 0 订阅
3 篇文章 0 订阅

注:本文于在IT专家网发表,原文请参见:http://unix.ctocio.com.cn/349/8694349.shtml

简介

我曾看到过一些关于UNIX文件权限的错误信息,我将在本文对这些问题做一个澄清。请看如下例子中的ls命令的输出结果:
例一:

$ ls -ld /usr/bin /usr/bin/cat

drwxrwxr-x 3 root bin 8704 Sep 23 2004 /usr/bin

-r-xr-xr-x 1 bin bin 9388 Jul 16 1997 /usr/bin/cat

$

在ls命令输出的第一行中的root说明目录“/usr/bin”属于一个叫"root"的用户所有,而"bin"则代表该目录所属的组。你需要理解UNIX中users和groups含义(在此假设你已经理解了)。我们的目标是搞清楚"drwxrwxr-x" 和 "-r-xr-xr-x"中各部分的意思;ls -l命令输出的第一个字段是由文件类型及访问权限组成的。总的来说,这些信息有时被称为“文件模式”,而有时又被称为“权限”。要深入理解上述信息,让我们先快速浏览一下它们实际上是怎么保存在硬盘里的。它们的存储方式影响着很多数年前做出的决定。
文件模式是如何保存的呢?

在硬盘中,关于一个文件的信息是保存在一个叫“inode”的数据结构中的。每个文件都有它自己的inode。inode里面的第一组数据项叫模(mode),其结构如下所示例二:


我认为“mode”的真正含义仅仅是指文件访问权限,而文件内容本身则存放在数据空间,但是ls命令的作者把mode作为一个独立项处理。这也是为什么在“ls -l”输出的权限信息中第一个字母表示文件类型的原因。文件类型通常是上面例子列出的七种之一,一些其他的UNIX会有更多的类型。另一点需要注意的是,从上面显示的信息看到已经没有空间可以增加权限位了。


以八进制展示文件权限
ls程序会显示一个文件的权限信息,比如说象"rwxrwxrwx"。但也通常被表示成八进制形式。就象上面看到的,它们就是以这种方式保存的。你也许会听到人们说文件的权限是“777”,这实际上就是"rwxrwxrwx",但“777”用口头表达起来就容易多了。因此你需要懂得怎样去转换它们,3位二进制(或bits)对应一位八进制数:
示例三:

421

rwx

如上所示,读权限的值是4,写权限的值是2,而可执行权限的值是1。你只需要把它们加起来即可得到一个八进制数。因此,"-rwxrwxrwx" 是 777, "-rwxr-x---" 是 750,以此类推。如果你还不太清楚怎么从"r-x" 转换到 5,那么下表一定会对你有帮助的:
示例四:

--- = 0

--x = 1

-w- = 2

-wx = 3

r-- = 4

r-x = 5

rw- = 6

rwx = 7

要注意,我们其实有4位八进制数字表示权限位。前三位是特殊位而且通常是0。而我们几乎总是先了解后面的9位,然后有些人就到此为止而从未了解过最前面的3位。但必需记住是12位而不仅仅是9位。那好,让我们先看看后面的9位吧。

基本权限位

我们有3组分别由3个bit组成的二进制数组:一个user本身的,一个是user所属的group的,另一个是其他用户other的。有时"user"也被称为所有者,"other"被称为"world"。在此我将用"user"和"other",因为chmod命令是用字母u,g,o分别代表"user","group","other"的。

哪一组bits适用于你呢?

当UNIX确定你能做什么时,它并不是使用所有的9个位元。 UNIX会使用最前面的三位用于你的角色上,请先看看如下例子:
示例五:

----rwxrwx 1 joe users 29 Mar 22 19:39 somefile

尽管joe是该文件的所有者,但他不能访问该文件(由于joe是文件的所有者,他可以授予自己访问权限。后面我们再讨论)。root用户也是特殊情况,它被授予rwx权限访问所有目录及rw权限访问所有文件。对于某一个文件,如果3组的x位都设了,那么root就有执行权限。这种特殊的权限在网络文件系统上一般是被禁止的。

对一个文件,r w 和 x 真正的含义是什么呢?

对一个文件,“read”和“write”是非常直观的。而代表“execute”的x则表示系统kernel可以运行该文件,而要运行文件,文件本身必须是可执行的(通过编译器编译出来的文件)或是一个第一行以#!开头的shell脚本。对于一个目录来说,事情就要复杂一点了。对目录,“write”权限意味着你可以在该目录中创建新文件和删除老文件。但有时令人惊讶的是:你可以删除一个你不可以读的文件。UNIX的rm命令会去尝试并发出警告,但是你可以用-f参数禁止警告。不管是否有警告信息,如果你想从一个可写的目录中删除一个不可读的文件,你完全可以做到。而rmdir命令会毫不厌烦地去检查所有的权限信息。

对一个目录,r w 和 x 真正的含义是什么呢?

一个目录其实也可以作为一个文件来看,而“read”权限的意思是你可以读取它,但如果没有x权限,你并不能有太多的作为。对于一个目录,你通常会同时拥有或同时不拥有读和执行的权限。在一个目录中,那个x正式被称为“搜索权限”。在一个长路径中的所有目录都需要有x权限。 因此如果你尝试“cat /etc/passwd”,那么/和/etc目录都要有x的权限。同样,如果你要cd到一个目录也需要有x权限。假设一个目录你只有读而没有可执行权限,你可以做什么操作呢?不多,你可以用ls命令查看目录中的文件名,甚至有的UNIX系统的“ls -l”不可以。没有“搜索权限”的“读”访问是没什么大用处的。当然这还是相比只有写权限的目录,单独的写权限对目录来说是完全没用处的。我从来没看到过对上述问题有明确说明的文章,因此让我们重复一次:一个目录只有写权限而没有可执行权限就等于什么权限也没授予。假设一个目录,你只有x权限但没有读权限,那么如果你刚好知道文件名,你就可以打开这文件。虽然你可以cd进入该目录,但仅此而己;不可以创建新文件(ls命令都不可以用)。增加写权限将会允许你创建文件并且可以删除一些你知道文件名的文件。

特殊的符号链接

设置在符号链接的权限也有一点特殊之处,它们完全被忽略了。很多版本的UNIX都没办法去改变它。

setuid和setgid位
请看如下示例:
示例六:

$ ls -l /etc/passwd /etc/shadow /usr/bin/passwd

-r--r--r-- 1 root sys 14006 Jan 14 11:17 /etc/passwd

-r-------- 1 root sys 8281 Jan 14 11:18 /etc/shadow

-r-sr-sr-x 3 root sys 96244 Sep 5 2001 /usr/bin/passwd

上述的passwd文件只有root用户有写权限(记住:root用户很特殊,它能够对没有设置写权限的文件读写)。shadow文件,它也是保存密码的地方,也不能给一般用户读写的。但是joe希望修改他的密码。他可以通过运行/usr/bin/passwd命令来达到他的目的。请留意那些r-s权限。passwd程序(/usr/bin/passwd)设置了suid和sgid权限位,这样会把x位转换成s位。用八进制表示应该是6555。passwd程序是root所有。当joe运行它时,实际上不是以它自己用户“joe”运行的,而是以程序的所有者root身份运行的。所有passwd程序可以为joe修改密码。sgid位也是一样的道理,只不过它令passwd程序以sys组而不是joe的组运行。suid和sgid在ls命令没有输出的位置。当设置了suid位时, ls命令将会在所有者的可执行权限出现s而不是x。那么,如果设置了suid而所有者的可执行权限是关闭的会是什么样的情况呢?这种情况ls会显示大写的S。 sgid也是类似的方式显示的,不过它只对组的可执行权限有影响。

更详细一点,当joe在运行suid-to-root的passwd程序时,joe是真正的uid, 而root则是有效uid。passwd程序可以获得它需要的两者的信息。这就是为什么passwd程序知道只允许joe修改他自己的密码。

sticky位

POSIX标准里说:如果目录设置了sticky位,仅仅是让目录的写权限不再有足够去轻易删除一个该目录下文件。你必须是文件或目录的所有者,不过root依然是特殊的,它可以删除任何权限设置的目录(或文件)。以前,sticky位可做为其它目的用途。在其他操作系统中现在还是那样,我将在下面的附录中详细说明。sticky位对”other”的可执行位在ls命令输出中也改变了,只不过它用了t和T而不是s和S。如下例:
示例七:

drwxrwxrwt 5 root root 1024 Feb 11 20:43 /tmp

目录中,任何人可以创建新文件。但由于设置了sticky位,一般用户(非root用户或目录所有者)不可以删除其他用户的文件。

用umask来限制文件权限

当一个文件被创建时,创建文件的程序可以指定初始的权限设置,你可以用umask覆盖它,umask是一组权限禁止位。UNIX系统有一个umask命令允许你查看以及修改umask的值。例如,执行“umask 022”会禁止一个新创建文件的group和other的写权限。而“umask 027”则会禁止group的写和other的读、写及可执行权限。你也可以执行“umask 0”来使得一个程序开放所有的权限给它创建的文件。这也是所有umask能做的了,你不能用umask去打开一个已禁止的权限。umask的设置只影响文件、目录、管道(又称:fifos)和特殊文件。它对符号链接可能有也可能没有影响。同时它也影响某些类型的IPC(Inter Process Communication),但这些内容已经超出本文的讨论范围了。另外,不管你信不信,sockets是不受umask影响的。这个免除是POSIX要求的。

用chmod来修改文件的访问权限

只有文件的所有者或root才可以修改该文件的权限。这个操作完全不受umask设置的影响。如果你修改一个符号链接的权限,这会跟着那个链接走并把目标文件的权限作相应的修改。对于一个文件,有可能只有root才有权力设置sticky位。例如,“chmod 700 somefile”会允许所有者有读、写和执行权限,而不允许任何其它用户有任何访问权限。

使用 chmod umask的符号模式

POSIX引入了一套新的chmod命令句法。他们的想法是在chmod命令中用新的句法去替代用八进制常数。当然原来的八进制可以继续使用,而不再继续发展了。但是符号句法让你可以在不知道其他位设置的情况下修改某些位,而不影响它们的值。比如说:我想不让other访问一个文件但又不想改动user和group的权限。那我要做如下操作:
ls -l file
搞明白文件当前的权限设置。
chmod 750 file ←执行此命令来修改权限,前提是原有的user和group权限是rwxr-x
在运行chmod命令前,我必须确定前面两位数字是7和5。使用新的句法,我只须简单的做如下操作去关闭最后三位权限位:
chmod o= file
正如另一例子,“chmod u+x file”会允许user执行该文件。也就是说,如下命令是一样的:
chmod 750 file
chmod u=rwx,g=rx,o= file
而我更喜欢第一种句法。

符号模式可以用逗号来分开一系列的参数,每组参数包含三部分:<who><operatoin><bitlist>
示例八:

who这部分有下面几种选项:

u (user - 所有者)

g (group - 组)

o (other - 其他用户)

a (all - 所有用户)

(umask设置的所有权限(也就all的子集))


操作符可以是=或-或+:

= (设置权限位到权限列表中)

-(从现有的权限位列表中去除权限位)

+(增加权限位到当前权限列表中)


权限列表可以是下面字母中的任何一个:

r(读权限)

w(写权限)

x(可执行权限)

X(条件可执行权限)

u(user的当前权限)

g(group的当前权限)

o(other的当前权限)

s(设置uid或gid)

t (sticky位)

除非文件不是目录并且目前没设置可执行权限x,否则X和x是没区别的(ls的输出中不会显示X的)。s(设置uid或gid)只能用于user或group的权限设置。t只能用于用户的权限设置(“t”在ls命令输出的权限串中出现在最后一位)。一些例子以助理解,上面我们看到/usr/bin/passwd的权限是6555(-r-sr-sr-x in ls)。以下几种方法均可完成这个设置:
chmod 6555 /usr/bin/passwd
chmod u=rxs,g=rxs,o=rx /usr/bin/passwd
chmod ug=rxs,o=rx /usr/bin/passwd
chmod a=rx,ug+s /usr/bin/passwd

另外还有很多其他方法可以完成上述的设置。

对于大部分chmod的功能,umask对它们都不会有影响,因此chmod设置的任何位都不会被umask改变。然而,有一种情况chmod会先检查当前umask的设置然后确定设置哪些位,那就是当chmod命令中“who”域是空的时候。如下例所示:
chmod =w somefile
“a=w”和“=w”的差别很小,下面例子可以帮我们更好地理解其中的含义。很多程序以666的默认权限创建新文件的,假设你想设置一个文件的权限为666,但被当前umask改动过;我们可以先关闭所有的权限,然后打开当前umask允许的读和写权限:

chmod a=,=rw somefile

说到umask,你也可以在umask命令中使用符号参数。然而POSIX聪明的在这件事上决定使用逻辑上刚好相反的方式。所以如果使用八进制数作为umask的参数,指的是禁止某些位;而用符号参数的话则允许你指定的位。如下两个命令是一样的:
umask 022
umask u=rwx,go=rx

总结

到此你已经有足够的信息搞明白那12位权限位了。这些信息都是相当通用的,符合POSIX标准的操作系统都必须支持这些内容。这包括过去十年几乎所有版本的UNIX发行版。后面有机会我们还将讨论那些可能不太通用的情况。

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值