设置用户 ID 和设置组 ID

    与每一个进程相关联的 ID 有 6 个或更多,如下表所示:
ID 类别 说明
实际用户ID和实际组ID 我们实际上是谁
有效用户ID、有效组ID和附属组ID 用于文件访问权限检查
保存的设置用户ID和保存的设置组ID 由 exec 函数保存

    其中:
    (1) 实际用户 ID 和实际组 ID 标识我们究竟是谁。这两个字段在登录时取自口令文件中的登录项。通常,在一个登录回话期间这些值并不改变,但是超级用户进程有方法改变它们。
    (2) 有效用户 ID、有效组 ID 和 附属组 ID 决定了我们的文件访问权限。通常,有效用户 ID 和有效组 ID 就等于实际用户 ID 和实际组 ID。
    (3) 保存的设置用户 ID 和保存的设置组 ID 在执行一个程序时包含了有效用户 ID 和有效组 ID 的副本。
    每个文件都有一个所有者和组所有者,分别由 stat 结构中的 st_uid 和 st_gid 来指定。通常,当执行一个程序文件时,有效用户 ID 和有效组 ID 就等于实际用户 ID 和实际组 ID。但可以在 stat 结构中的 st_mode 里设置一个特殊标志,表示“当执行此文件时,将进程的有效用户 ID 设置为文件所有者的用户 ID(st_uid)”。同理,可设置 st_mode 中的另一位将执行此文件的进程的有效组 ID 改为文件的组所有者 ID(st_gid)。在文件模式字(st_mode)中的这两位被称为设置用户 ID 位和设置组 ID 位,可分别用常量 S_ISUID 和 S_ISGID 来测试。
    例如,若文件所有者是超级用户,而且设置了该文件的的设置用户 ID 位,那么当一个进程执行该文件时,该进程就具有超级用户权限,而不管该进程的实际用户 ID 是什么。passwd 命令程序就是一个设置用户 ID 程序,因为它允许任意用户进程将新口令写入只有超级用户才具有写权限的 /etc/passwd 或 /etc/shadow 口令文件中。由于运行设置用户 ID 程序的进程通常会得到额外的权限,所以编写这种程序时要特别谨慎。
    st_mode 值也包含了对文件的访问权限位。所有文件类型都有访问权限,每个文件有 9 个访问权限位,可分成 3 类,如下表:

    表中的 3 类访问权限(即读、写及执行)以各种方式由不同的函数使用,现将这些方式汇总如下:
    1、当用某名字打开任意类型的文件时,对该名字中包含的每一级目录,包括它可能隐含的当前工作目录都应该具有执行权限。这就是为什么对于目录其执行权限位常被称为搜索位的原因。例如,为了打开文件 /usr/include/stdio.h,需要对目录 /、/usr 和 /usr/include 具有执行权限。然后,需要具有对文件本身的适当权限。如果当前目录是 /usr/include,那么需要对当前目录有执行权限,这是隐含当前目录的一个示例。引用隐含目录的另一个例子是,如果 PATH 环境变量指定了一个我们不具有执行权限的目录,那么 shell 绝不会在该目录下找到可执行文件。注意,目录的读权限和执行权限的意义是不同的。读权限允许我们读目录,获得在该目录中所有文件名的列表;而执行权限使我们可通过该目录(也就是搜索该目录,寻找一个特点的文件名)。
    2、对一个文件的读权限决定了我们能否打开该文件进行读操作,这与 open 函数的 O_RDONLY 和 O_RDWR 标志相关。
    3、对一个文件的写权限决定了我们能否打开该文件进行写操作,这与 open 函数的 O_WRONLY 和 O_RDWR 标志相关。
    4、只有对某文件具有写权限,才能在 open 函数中对它指定 O_TRUNC 标志。
    5、要在一个目录中创建新文件,必须对该目录具有写权限和执行权限。
    6、要删除一个文件,必须对包含该文件的目录具有写权限和执行权限,而跟对该文件本身是否具有读、写权限无关。
    7、如果要用 7 个 exec 函数中的任何一个执行某个文件,都必须对该文件具有执行权限,该文件还必须是一个普通文件。
    进程每次创建、打开或删除一个文件时,内核就进行文件访问权限测试,而这种测试可能涉及文件的所有者(st_uid 和 st_gid)、进程的有效 ID(有效用户 ID 和有效组 ID)以及进程的附属组 ID(若支持的话)。两个所有者 ID 是文件的性质,而两个有效 ID 和附属组 ID 则是进程的性质。内核进行的测试具体如下:
    1、若进程的有效用户 ID 是 0(超级用户),则允许访问。这给予了超级用户对整个文件系统进行处理的最充分的自由。
    2、若进程的有效用户 ID 等于文件的所有者 ID(即进程拥有此文件),那么如果所有者适当的访问权限位被设置,则允许访问;否则拒绝访问。适当的访问权限位指的是,若进程为读而打开该文件,则用户读位应为 1;若为写而打开,则用户写位应为 1;若进程将执行该文件,则用户执行位应为 1。
    3、若进程的有效组 ID 或进程的附属组 ID 之一等于文件的组 ID,那么如果组适当的访问权限位被设置,则允许访问;否则拒绝访问。
    4、若其他用户适当的访问权限位被设置,则允许访问;否则拒绝访问。
    对于新文件或新目录来说,它的用户 ID 被设置为进程的有效用户 ID,而组 ID 被设置为进程的有效组 ID 或它所在目录的组 ID(FreeBSD 8.0 和 Mac OS X 10.6.8 总是使用目录的组 ID作为新文件的组 ID。有些 Linux 文件系统允许使用 mount 命令选项来进行选择。对于 Linux 3.2.0 和 Solaris 10,默认情况下,新文件的组 ID 取决于它所在的目录的设置组 ID 位是否被设置。如果该位被设置,则新文件的组 ID 就被设置为目录的组 ID;否则设置为进程的有效组 ID)。

猜你喜欢

转载自aisxyz.iteye.com/blog/2381550
id