设置用户ID和设置组ID
与一个进程相关联的ID有6个或更多。
- 实际用户ID和实际组ID标识我们是谁。这两个字段在登陆时取自口令文件中的登陆项。
- 有效用户ID,有效组ID以及附属组ID决定了我们的文件访问权限。
- 保存的设置用户ID和保存的设置组ID在执行一个程序时包含了有效用户ID和有效组ID的副本。
通常,有效用户ID等于实际用户ID,有效组ID等于实际组ID。
当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID通常是实际组ID。但是可以在文件模式字(st_mode
)中设置一个特殊标志,其含义是“当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID”。与此类似,在文件模式字中可以设置另一位,它将执行此文件的进程的有效组ID设置为文件的组所有者ID。在文件模式字中这两位被称为设置用户ID位和设置组ID位。
例如,若文件所有者超级用户,而且设置了该文件的设置用户ID位,那么当该程序文件由一个进程执行时,该进程具有超级用户权限。不管执行此文件的进程的实际用户ID是什么,都会是这样。
文件访问权限
每个文件有9个访问权限位,可将它们分成3类。
st_mode屏蔽 | 含义 |
---|---|
S_IRUSR S_IWUSR S_IXUSR | 用户读 用户写 用户执行 |
S_IRGRP S_IWGRP S_IXGRP | 组读 组写 组执行 |
S_IROTH S_IWOTH S_IXOTH | 其他读 其他写 其他执行 |
- 第一个规则是,我们用名字打开任一类型的文件时,对该名字中包含的每一个目录,包括它可能隐含的当前工作目录都应具有执行权限。
- 对一个文件的读权限决定了我们是否能够打开现有文件进行读操作。这与
open
函数的O_RDONLY
和O_RDWR
标志相关。 - 对一个文件的写权限决定了我们是否能够打开现有文件进行写操作。这与
open
函数的O_WRONLY
和O_RDWR
标志相关。 - 为了在
open
函数中对一个文件指定O_TRUNC
标志,必须对该文件具有写权限。 - 为了在一个目录中创建一个新文件,必须对该目录具有写权限和执行权限。
- 为了删除一个现有文件,必须对包含该文件的目录具有写权限和执行权限。对该文件本身不需要有读,写权限。
- 如果用7个
exec
函数中的任何一个执行某个文件,都必须对该文件具有执行权限。该文件还必须是一个普通文件。
进程每次打开,创建或删除一个文件时,内核就进行文件访问权限测试,而这种测试可能涉及文件的所有者(st_uid
和st_gid
),进程的有效ID(有效用户ID和有效组ID)以及进程的附属组ID。两个所有者ID是文件的性质,而两个有效ID和附属组ID则是进程的性质。
内核进行的测试具体如下:
- 若进程的有效用户ID是0(超级用户),则允许访问。
- 若进程的有效用户ID等于文件的所有者ID(也就是进程拥有此文件),那么如果所有者适当的访问位置位被设置,则允许访问;否则拒绝访问。适当的访问位权限指的是,若进程为读而打开该文件,则用户读位应为1;若进程为写而打开该文件,则用户写位应为1;若进程将执行该文件,则用户执行位应为1。
- 若进程的有效组ID或进程的附属组ID之一等于文件的组ID,那么如果组适当的访问权限位被设置,则允许访问;否则拒绝访问。
- 若其他用户适当的访问权限位被设置,则允许访问;否则拒绝访问。
按顺序执行这4步。注意,如果进程拥有此文件,则按用户访问权限批准或拒绝该进程对文件的访问——不查看组访问权限。类似的,若进程并不拥有该文件。但进程属于某个适当的组,则按组访问权限批准或拒绝该进程对文件的访问——不查看其他用户的访问权限。
新文件和目录的所有权
新文件的用户ID设置为进程的有效用户ID。
关于组ID,POSIX.1允许选择下列之一作为新文件的组ID。
- 新文件的组ID可以是进程的有效组ID。
- 新文件的组ID可以是它所在目录的组ID。