1,背景知识:
与一个进程相关联的ID有6个或更多。这里涉及到的有:
表征现在正在执行进程的是哪个人、组:
- 实际用户ID
- 实际组ID
表征以谁的名义来执行这个进程(判断进程的访问权限时,以这个ID为准):
- 有效用户ID
- 有效组ID
通常来说有效用户ID就是实际用户ID,有效组ID就是实际组ID,即默认总是以进程的实际执行者的名义来执行程序,判断程序的系统资源的访问权限。但是如果可执行文件的“设置用户ID位”或者“设置组ID位”被置为1,则有效用户ID就变成可执行文件的所有者ID,有效组ID就变成可执行文件的所有组ID,即不是以当前用户的名义去执行文件而是以可执行文件的所有者的名义去执行文件、询问系统资源的占用权限。
2,如何用命令设置“设置用户ID位”
- chmod u+s file_name 将“设置用户ID位”设为有效
- chmod g+s file_name 将“设置组ID位”设为有效
- chmod u-s file_name 将“设置用户ID位”设为无效
- chmod g-s file_name 将“设置组ID位”设为无效
3,“设置用户ID位”与st_mode
上一节提到的文件属性结构体struct stat中的st_mode中包含了“设置用户ID位”和“设置组ID位”信息。st_mode的第11位和第12位分别代表的就是“设置组ID位”和“设置用户ID位”
常量S_ISUID(2048)和S_ISGID(1024)可用于在C代码中设置和获取这两个位.其用法如下:
struct stat file_info;
if((lstat(file_name, &file_info)) < 0)
{
printf("lstat error!\n");
return 1;
}
//"设置用户ID"和"设置组ID"设为有效
file_info.st_mode |= S_ISUID;
file_info.st_mode |= S_ISGID;
//"设置用户ID"和"设置组ID"设为无效
file_info.st_mode &= ~S_ISUID;
file_info.st_mode &= ~S_ISGID;
//"获取用户ID"和"获取组ID"
if(file_info.st_mode & S_ISUID)
printf("set-usr-ID valid");
else
printf("set-usr-ID invalid");
if(file_info.st_mode & S_ISGID)
printf("set-group-ID valid");
else
printf("set-group-ID invalid");
4,例子
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char* argv[])
{
struct stat file_info;
if((lstat(argv[0], &file_info)) < 0)
{
printf("lstat error!\n");
return 1;
}
printf("s_uid = %d, s_gid = %d\n", S_ISUID & file_info.st_mode, S_ISGID & file_info.st_mode);
printf("uid = %d,gid=%d, euid = %d, egid = %d\n",getuid(),getgid(),geteuid(),getegid());
}
执行结果:
注:我们不能在进程中修改进程本身的可执行文件的“设置用户ID位”和“设置组ID位”