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 setreuid和setregid函数
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 seteuid和setegid函数
在对P O I X . 1的建议更改中包含了两个函数seteuid和setegid。它们只更改有效用户ID和有效组ID。
#include <unistd.h>
int seteuid(uid_t uid) ;
int setegid(gid_t g i d) ;
//两个函数返回:若成功则为0,若出错则为-1