8.11 更改用户ID和组ID

8.11 更改用户ID和组ID

      UNIX系统中,特权是基于用户和组ID的,当程序需要增加特权,或需要访问当前并不允许访问的资源时,我们就需要更换自己的用户ID或组ID

      一般而言,在设计应用程序的时候,我们总是试图使用最小特权(lease privilege)模型。

可以用setuid函数设置实际用户ID和有效用户ID。与此类似,可以用s e t g i d函数设置实际组ID和有效组ID

#include <unistd.h>

int setuid(uid_t uid) ;

int setgid(gid_t g i d) ;

//两个函数返回:若成功则为0,若出错则为-1

关于谁能更改ID有若干规则。现在先考虑有关改变用户ID的规则(在这里关于用户ID所说明的一切都适用于组ID)。

l  若进程具有超级用户特权,则setuid函数将实际用户ID、有效用户ID,以及保存的设置用户ID设置为uid

l  若进程没有超级用户特权,但是uid等于实际用户ID或保存的设置用户– ID,则setuid只将有效用户ID设置为uid。不改变实际用户ID和保存的设置用户– ID

l  如果上面两个条件都不满足,则e r r n o设置为E P E R M,并返回出错。

关于内核所维护的三个用户ID,还要注意下列几点:

l  只有超级用户进程可以更改实际用户ID。通常,实际用户ID是在用户登录时,由login ( 1 )程序设置的,而且决不会改变它。因为login是一个超级用户进程,当它调用setuid时,设置所有三个用户ID

l  仅当对程序文件设置了设置用户ID位时, exec函数设置有效用户ID。如果设置用户– ID位没有设置,则exec函数不会改变有效用户ID,而将其维持为原先值。任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置用户– ID。自然,不能将有效用户ID设置为任一随机值。

l  保存的设置用户– ID是由exec从有效用户ID复制的。在exec按文件用户ID设置了有效用户ID后,即进行这种复制,并将此副本保存起来。

8.10.1 setreuidsetregid函数

4 . 3 + BSD支持setregid函数,其功能是交换实际用户ID和有效用户ID的值。

#include <unistd.h>

int setreuid(uid_t ruid, uid_t e uid) ;

int setregid(gid_t rg i d, gid_t e g i d) ;

//两个函数返回:若成功则为0,若出错则为-1

8.10.2 seteuidsetegid函数

在对P O I X . 1的建议更改中包含了两个函数seteuidsetegid。它们只更改有效用户ID和有效组ID

#include <unistd.h>

int seteuid(uid_t uid) ;

int setegid(gid_t g i d) ;

//两个函数返回:若成功则为0,若出错则为-1