UNIX环境编程学习笔记(7)——文件I/O之文件访问权限与进程访问控制

时间:2021-08-29 05:15:26

1 文件的设置用户 ID位 和设置组 ID位

与进程相关联的 ID 如下表所示,

表 1: 与进程相关联的用户 ID 和组 ID
实际用户 ID 我们实际上是谁
实际组 ID
有效用户 ID 用于文件访问权限检查
有效组 ID
附加组 ID
保存的设置用户 ID 由 exec 函数保存
保存的设置组 ID

 

保存的设置用户 ID 和保存的设置组 ID 在执行一个程序时包含了有效用户 ID 和有效组 ID 的副本,这个后面我们学习到进程时在详细学习。

此处,我们重点讲一下其他几个。一个进程的实际用户 ID 和实际组 ID 即为当前登录会话使用的用户ID 和该用户所在的组 ID。当执行一个程序文件时,有效用户 ID 通常就是实际用户 ID,有效组 ID 通常就是实际组 ID。但是,程序文件的文件模式字可以通过设置特殊标志(设置用户 ID 位或设置组 ID 位)来将进程的有效用户 ID 或有效组 ID 设置为程序文件的所有者 ID 或所有组 ID。设置用户 ID(set-user-ID)位的含义是“当执行此文件时,将进程的有效用户 ID设置为文件所有者的用户 ID”。与此相似,设置组(set-group-ID)位的含义是“当执行此文件时,将进程的有效组 ID 设置为文件所有组 ID”。

例如,若文件所有者是超级用户,而且设置了该文件的设置用户 ID 位,然后当该程序由一个进程执行时,则该进程将具有超级用户权限。例如,程序 passwd 允许任一用户改变其口令,该程序是一个设置用户 ID 程序。因为该程序应将用户的新口令写入只有超级用户才有写权限的口令文件中。

文件设置用户 ID 位及设置组 ID 位都包含在 stat 结构的st_mode 值中,这两位可用常量S_ISUID 和S_ISGID 进行测试。

2 文件访问权限

stat 结构的st_mode 值中包含了针对文件的访问权限位。所有文件类型都具有访问权限。每个文件有 9 个访问权限位,如表 2 所示。

表 2: 文件的 9 个访问权限位
st_mode 屏蔽 意义
S_IRUSR 用户 -读
S_IWUSR 用户 -写
S_IXUSR 用户 -执行
S_IRGRP 组 -读
S_IWGRP 组 -写
S_IXGRP 组 -执行
S_IROTH 其他 -读
S_IWOTH 其他 -写
S_IXOTH 其他 -执行

 关于文件访问权限位的使用方式如下:

• 用名字打开任一类型的文件时,对该名字中包含的每一个目录,包括它可能隐含的当前工作目录都应具有执行权限。例如,

为了打开文件/usr/include/stdio.h,需要对目录/、/usr 和/usr/include具有执行权限。然后,需要具有对该文件本身的适当权限。如果当前工作目录是/usr/include,那么为了打开文件 stdio.h,则需要有对该工作目录的执行权限。

注意:对于目录的读权限和执行权限的意义是不相同的。读权限允许我们读目录,获取在该目录中所有文件名的列表。当一个目录是我们要访问文件的路径名的一个组成部分时,对该目录的执行权限使我们可通过该目录(也就是搜索该目录,寻找一个特定的文件名。)

• 文件的读权限决定了我们是否能够打开该文件进行读操作。

• 文件的写权限决定了我们是否能够打开该文件进行写操作。

• 为了要在一个目录中创建一个新文件,必须对该目录具有写权限和执行权限。

• 为了删除一个现有的文件,必须对包含该文件的目录具有写权限和执行权限。对该文件本身则不需要有读、写权限。

• 如果用 6 个 exec 函数中的任何一个执行某个文件,都必须对该文件具有执行权限。该文件还必须是一个普通文件。

3 内核文件访问权限测试

进程每次打开、创建或删除一个文件时,内核就进行文件访问权限测试。这种测试可能涉及文件的所有者(st_uid 和st_gid)、进程的有效 ID(有效用户 ID 和有效组 ID)以及进程的附加组 ID。内核进行的测试按下面步骤依次进行:

1. 若进程的有效用户 ID 为 0(即超级用户),则允许访问。

2. 若进程的有效用户 ID 等于文件的所有者 ID,那么:若所有者适当的访问权限位被设置,则允许访问,否则拒绝访问。适当的访问权限位指的是,若进程为读而打开该文件,则用户读位应为 1;若进程为写而打开该文件爱你,则用户写位应为 1;若进程将执行该文件,则用户执行位应为 1.

3. 若进程有效组 ID 或进程附加组 ID 之一等于文件的组 ID,那么,若组适当的访问权限位被设置,则允许访问,否则拒绝访问。

4. 若其他用户适当的访问权限位被设置,则允许访问,否则拒绝访问。

4 新文件和目录的所有权

新文件的用户 ID 设置为进程的有效用户 ID。关于组 ID,POSIX.1 允许实现选择下列之一作为新文件的组 ID。

1. 新文件的组 ID 可以是进程有效组 ID。

2. 新文件的组 ID 可以是它所在目录的组 ID。

对于 Linux 2.4.22,新文件的组 ID 取决于它所在目录的设置组 ID 为是否被设置。如果该目录的这一位被设置,则新文件的组 ID 设置为目录的组 ID;否则,将新文件的组 ID 设置为进程的有效组 ID。

(done)