函数setuid、setgid
#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
改变用户/组ID的规则
1、若进程具有超级用户权限,则setuid将实际用户ID、有效用户ID、保存的设置用户ID设置为uid
2、若进程没有超级用户权限,但uid等于实际用户ID或保存的设置用户ID,则setuid只将有效用户ID设置为uid,不改变实际用户ID和保存的设置用户ID
3、若以上条件不满足,返回-1,errno设为EPERM
只有超级用户进程可以更改实际用户ID
实际用户ID是在用户登录时,由login程序设置的
login是一个超级用户进程,当它调用setuid时,会设置所有三个用户ID
仅当对程序文件设置了设置用户ID位时,exec才会设置有效用户ID。任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置用户ID
保存的设置用户ID是由exec复制有效用户ID而得来的
测试程序
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
void Show_Uid()
{
printf("The UID is [%d] \n",getuid());
}
int main(void)
{
int uid = 5000;
Show_Uid(); //调用setuid之前查看UID
if(setuid(uid) < 0)
perror("set UID error");
Show_Uid(); //设置UID之后
if(setuid(2000) < 0) //再次调用setuid设置UID
perror("set UID error");
Show_Uid(); //设置UID之后
return 0;
}
//因为上边将用户ID设置成5000,虽然以root权限运行,但是该进程的UID已经为5000,所以执行失败