#define _GNU_SOURCE
#include<unistd.h>
#include<sys/fsuid.h>
#include<limits.h>
#include<stdio.h>
#include<pwd.h>
#include<grp.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include"ugid_functions.h"
#define SG_SIZE (NGROUPS_MAX + 1)
/*
struct passwd
{
char *pw_name; //登录名
char *pw_passwd; //用户密码
uid_t pw_uid; //用户id
uid_t pw_gid; //用户组id
char *pw_gecos; //用户描述
char *pw_dir; //用户家目录
char *pw_shell; //用户登录shell
};
*/
/*
struct group
{
char *gr_name; 组名
char *gr_passwd; 密码
__gid_t gr_gid; 组ID
char **gr_mem; 组成员名单
}
*/
//userNameFromId 根据用户ID获取登录名
char *userNameFromId(__uid_t uid)
{
struct passwd *pwd;
//getpwuid 根据传入的用户ID返回指向passwd的结构体 该结构体初始化了里面的所有成员
pwd = getpwuid(uid);
return (pwd == NULL) ? NULL : pwd->pw_name;
}
//userIdFromName 根据登录名获取登录ID
__uid_t userIdFromName(const char *name)
{
struct passwd *pwd;
__uid_t u;
char *endptr;
if(name == NULL || *name == '\0')
return -1;
// strtol () 函数用来将 字符串 转换为 长整型数 (long)
u = strtol(name,&endptr,10);
if(*endptr == '\0')
return u;
pwd = getpwnam(name);
if(pwd == NULL)
return -1;
return pwd->pw_uid;
}
//通过组ID获取组名
char *groupNameFromId(__gid_t gid)
{
struct group *grp;
//getgrgid通过组名查找属组信息返回group结构
grp = getgrgid(gid);
return (grp == NULL) ? NULL : grp->gr_name;
}
//通过组名获取组ID
__gid_t grooupIdFromName(const char *name)
{
struct group *grp;
__gid_t g;
char *endptr;
if(name == NULL || *name == '\0')
return -1;
g = strtol(name,&endptr,10);
if(*endptr == '\0')
return g;
grp = getgrnam(name);
if(grp == NULL)
return -1;
return grp->gr_gid;
}
int main(int argc,char *argv[])
{
uid_t ruid,euid,suid,fsuid;
gid_t rgid,egid,sgid,fsgid;
gid_t suppGroups[SG_SIZE];
int numGroups,j;
char *p;
//getresuid()系统调用将调用进程的当前实际用户 ID、有效用户 ID 和保存
//set-user-ID 值返 回至给定 3 个参数所指定的位置
if(getresuid(&ruid,&euid,&suid) == -1)
{
printf("getresuid获取ID失败\n");
return -1;
}
//getresgid()系统调用针对相应的组 ID 实现了类似getresuid()功能。
if(getresgid(&rgid,&egid,&sgid) == -1)
{
printf("getresgid获取失败\n");
return -1;
}
//setfsuid()系统调用将进程文件系统用户 ID 修改为参数 fsuid 所指定的值
fsuid = setfsuid(0);
//setfsgid()系统调用将文件系统组 ID 修改为参数 fsgid 所指定的值
fsgid = setfsgid(0);
printf("UID:");
p = userNameFromId(ruid);
printf("real=%s(%ld);",(p == NULL) ? "???" : p,(long)ruid);
p = userNameFromId(euid);
printf("eff=%s(%ld);",(p == NULL) ? "???" : p,(long)euid);
p = userNameFromId(suid);
printf("saved=%s(%ld);",(p == NULL) ? "???" : p,(long)suid);
p = userNameFromId(fsuid);
printf("fs=%s(%ld);",(p == NULL) ? "???" : p,(long)fsuid);
printf("\n");
printf("GID:");
p = groupNameFromId(rgid);
printf("real=%s(%ld);",(p == NULL) ? "???" : p,(long) rgid);
p = groupNameFromId(egid);
printf("real=%s(%ld);",(p == NULL) ? "???" : p,(long) egid);
p = groupNameFromId(fsgid);
printf("real=%s(%ld);",(p == NULL) ? "???" : p,(long) fsgid);
printf("\n");
/*
getgroups()仅返回调用进程的辅助组 ID。然而,
SUSv3 规范还允许 UNIX 实现在返回的 grouplist 中包含调用进程的有效组 ID。
调用程序必须负责为 grouplist 数组分配存储空间,并在 gidsetsize 参数中指定其长度。若
调用成功,getgroups()会返回置于 grouplist 中的组 ID 数量。
若进程属组的数量超出 gidsetsize,则 getgroups()将返回错误(错误号为 EINVAL)。
*/
numGroups = getgroups(SG_SIZE,suppGroups);
if(numGroups == -1)
{
return -1;
}
printf("supplementary groups(%d):",numGroups);
for(j = 0;j < numGroups;j++)
{
p = groupNameFromId(suppGroups[j]);
printf("%s(%ld)",(p == NULL) ? "???" : p,(long)suppGroups[j]);
}
printf("\n");
return 0;
}
进 程 凭 证
最新推荐文章于 2024-06-12 15:58:20 发布