分类: 系统运维
2012-03-28 13:15:27
st_mode值也包含了文件的访问权限位。当我们说一个文件时,意思是任何我们早先提到的文件类型。所有文件类型--目录、字符特殊文件等--都有权限。许多人认为只有普通文件有访问权限。
每个文件有9个权限位,分为三个类别。如下表所示:
|
|
st_mode 掩码 | 含义 |
S_ISUSR | 用户可读 |
S_IWUSR | 用户可写 |
S_IXUSR | 用户可执行 |
S_IRGRP | 组可读 |
S_IWGRP | 组可写 |
S_IXGRP | 组可执行 |
S_IROTH | 其他人可读 |
S_IWOTH | 其他人可写 |
S_IXOTH | 其他人可执行 |
前三行的术语“用户”表示文件的属主。chmod命令,通常用来修改这9个权限位,允许我们指定u(用户,属组)、g(组)或o(其他人)。一些把这三个
描述为owner、group和world,这是令人困惑的,因为chmod命令使用o表示other,而不是owner。我们将使用术语user、
group和other,来与chomd命令保持一致。
上表中的三个类别--读、写和执行--被不同的函数用各种方法使用。我们在这里概括总结一下,然后在我们讨论真实的函数时再回过来讨论它们:
1、第一条规则是,无论何时我们想要通过名字打开任何类型的文件,我们必须有这个名字提及的目录的执行权限,包括当前路径,如果它是隐含的。这也是为什么目录的执行权限经常被称为查找位(search bit)。
比如,为了打开文件/usr/include/stdio.h,我们需要目录“/”、/usr、/usr/include的执行权限。根据我们如何打开这个文件(只读、读写等),我们然后需要文件本身恰当的权限。
如果当前目录是/usr/include,我们则需要当前目录的执行权限来打开文件stdio。这是个当前路径被隐含而非显示提及的例子。它等同于我们打开文件./stdio.h。
注意目录的读权限和执行权限是两码事。读权限让我们读这个目录,等到这个目录的所有文件名列表。当目录是一个我们要访问的路径名的一部分时,执行权限让我们解析这个目录。(我们需要查找这个目录来得到指定的文件名。)
另一个隐含目录的例子是:PATH环境变量(8.10节)指定了一个没有执行权限的目录。这种情况下,shell不会找到那个目录下的可执行文件。
2、文件的读权限决定了我们是否能打开一个存在的文件来读:open函数里指定O_RDONLY和O_RDWR标志。
3、文件的写权限决定了我们是否能打开一个存在的文件来写:open函数里指定O_WRONLY和O_RDWR标志。
4、我们必须有一个文件的写权限才能在open函数里指定O_TRUNC标志。
5、除非我们有一个目录的写权限和执行权限,否则我们不能在它下面创建一个新的文件。
6、为了删除一个存在的文件,我们需要包含这个文件的目录的写权限和执行权限。我们不需要文件本身的读权限或写权限。
7、如果我们想用6个exec函数(8.10节)中的任一个执行某文件,该文件的执行权限必须开启。
每当一个进程打开,创建或删除一个文件时,内核执行的文件的访问测试依赖于文件的属主和所属组(st_uid和st_gid)、进程的有效ID(用效用户
ID和有效组ID)以及进程的补充组ID(如果支持的话)。属主ID和所属组ID是文件的属性,而两个有效ID和补充组ID是进程的属性。这些测试由内核
以如下方式执行:
1、如果进程的有效组ID为0(超级用户),访问被允许。这给予了超级用户整个文件系统的自由。
2、如果进程的有效组ID与文件的属主ID一样(即进程拥有这个文件),且恰当的用户访问权限位被设置的话,访问被允许。否则,访问被拒绝。恰当的访问权
限位,意思是进程打开文件来读时,用户读的位必须开启;如果进程打开文件来写,用户写的位必须开启;如果进程打开文件来执行,用户执行的位必须开启;等
等。
3、如果进程的有效组ID或它其中一个补充组ID与文件的组ID相同,且恰当的组访问权限位被设置,访问被允许。否则访问被拒绝。
4、如果恰当的其它访问权限位被设置,访问被允许。否则访问被拒绝。
这四个步骤是依次被尝试。注意如果进程拥有这个文件(第2步),访问的接受或拒绝取决于用户访问权限,而组权限不会被查看。类似的,如果进程没有拥有这个文件,但属于一个恰当的组,访问的接受或拒绝取决于组访问权限,其它权限不会被查看。