一、获取用户ID/组ID
#include <unistd.h>
uid_t getuid(void);     //返回:调用进程的实际用户ID
uid_t geteuid(void);    //返回:调用进程的有效用户ID
uid_t getresuid(void);  //返回:调用进程的设置用户ID
gid_t getgid(void);     //返回:调用进程的实际组ID
gid_t getegid(void);    //返回:调用进程的有效组ID
gid_t getresgid(void);  //返回:调用进程的有效组ID

//这些函数都没有出错返回
二、更改用户ID和更改组ID(setuid、setgid)
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_ gid);

//返回值:若成功返回0;失败返回-1
  • 功能:用来更改用户ID/组ID
  • 注意:实际用户ID只能由root权限修改 

更改ID的规则如下:

下面我们以更改用户ID为例(关于用户ID我们所说明的一切也适用于组ID):

  • ①若进程具有超级用户特权,则setuid函数将实际用户ID、有效用户ID、保存的设置用户ID设置为uid
  • ②若进程没有超级用户特权,则uid等于实际用户ID或保存的设置用户ID,则setuid只将有效用户ID设置为uid不更改实际用户ID和保存的设置用户ID
  • ③如果上面两个条件都不满足,则errno设置为EPERM,并返回-1

_POSIX_SAVED_IDS常量

  • 如果没有定义_POSIX_SAVED_IDS常量,则上面那些设置规则都无效
  • 可以在编译时测试该常量,或者在运行时通过sysconf函数来判断是否定义该常量,见文章:javascript:void(0)

实际用户ID、有效用户ID、保存的设置用户ID介绍

下面我们以用户ID为例(关于用户ID我们所说明的一切也适用于组ID):

  • 实际用户ID:
    • 只有超级用户进程可以更改实际用户ID
    • 通常,实际用户ID是在用户登录时,由login程序设置的。而且绝不会改变它。因为login是一个超级用户进程,当它调用setuid时,设置所有3个用户ID
  • 有效用户ID:
    • 仅当对程序文件设置了设置用户ID位时,exec函数才设置有效用户ID;如果设置用户ID位没有设置,exec函数不会改变有效用户ID,而谁维持其现有值
    • 任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置用户ID
    • 自然地,不能将有效用户ID设置为任意随机值
  • 保存的设置用户ID:
    • 保存的设置用户ID是由exec复制有效用户ID而得到的
    • 如果设置了文件的设置用户ID位,则在exec根据文件的用户ID设置了进程的有效用户ID以后,这个副本就被保存起来了

获取ID值

  •  
  • 总结:

Linux(程序设计):21---更改用户/组ID(setuid、setgid、setreuid、setregid、seteuid、setegid)_更改用户/组ID

三、交换实际用户/组ID和有效用户组/ID(setreuid、setregid)
#include <unistd.h>
int setreuid(uid_t ruid,uid_t euid);
int setregid(gid_t rgid,gid_t egid);

//返回值:若成功,返回0;失败,返回-1
  • 功能:用户交换实际用户ID和有效用户ID
  • 参数:
    • 参数1:实际用户/组ID
    • 参数2:有效用户/组ID
    • 如果任一一个参数的值为-1,则表示相应的ID应当保持不变
  • 这两个函数设计的目的:非特权用户也可以交换实际用户ID和有效用户ID。于是就允许一个设置用户ID的程序交换成用户的普通权限,以后又可再次交换回设置用户ID权限
  • POSIX.1引进了保存的设置用户ID特性后,其规则也相应的加强,它允许一个非特权用户将其有效用户ID设置为保存的设置用户ID
四、更改有效用户ID和有效组ID(seteuid、setegid)
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_ gid);

//返回值:若成功返回0;失败返回-1
  • POSIX.1包含了这两个函数,它们类似于setuid和setgig,但是这两个函数只更改有效用户ID/有效组ID
  • 一个非特权用户可将其有效用户ID设置为其实际用户ID或其保存的设置用户ID,对于一个特权用户则可将有效用户ID设置为uid
五、总结

Linux(程序设计):21---更改用户/组ID(setuid、setgid、setreuid、setregid、seteuid、setegid)_#include_02

六、附属组ID
  • 上面的函数我们都是以用户ID为例,其实上面的方式都适用于组ID,但是附属组ID不受setgid、setregid、setegid