用户权限以及组权限
这三个UID分别是RUID(Real UID,实际用户ID)、EUID(Effective UID,有效用户ID)、
SUID(Saved Set-user-ID,保存的设置用户ID)。
gid同样的有三个
可以没有SUID
鉴定权限的时候看的是effective uid
passwd的执行
一个文件有u+s权限的时候表示,当别的用户在调用这个可执行文件的时候,它的身份会切换到当前二进制文件的user的身份来执行。如果是g+s权限的话,意味着不管任何用户来调用这个可执行的二进制文件,就会切换到这个二进制文件的同组用户的身份来执行,
exec来鉴定权限,发现当前的passwd是一个u+s权限,所以到此为止,身份就不再是之前的r、e、s,一般情况下会变成r、0、0.鉴定权限的时候查看的是e,所以当我们在执行passwd的时候,是在以root权限在运行。
关键在于passwd这个文件是有u+s权限的(g+s差不多原理)
不用切换身份回去,结束这个passwd这个进程就会消亡了,所以不需要
那么shell的身份是从哪里来的?
当前机器环境中产生的第一个进程是init进程
,当init进程产生的时候是root权限
然后fork+exec产生一个进程叫做getey进程
getey进程产生以后,会告诉你,请输入login name
输入名字,然后在exec,getey进程就不存在了,就会变成一个叫做login进程
login进程阶段提示你,输入password,然后输入密码,在此之前所有进程的权限都是root
在root下,可以拿到passwd下的所有信息,然后就可以进行校验,成功以后就会fork+exec产生一个子进程
shell,这个时候shell的身份就是r、e、s
相关函数;
getuid();
geteuid();
#include <unistd.h>
#include <sys/types.h>
uid_t getuid(void);
uid_t geteuid(void);
DESCRIPTION
getuid() returns the real user ID of the calling process.
geteuid() returns the effective user ID of the calling process.
getgid();
getegid();
#include <unistd.h>
#include <sys/types.h>
gid_t getgid(void);
gid_t getegid(void);
DESCRIPTION
getgid() returns the real group ID of the calling process.
getegid() returns the effective group ID of the calling process.
setuid();
---------- setuid - set user identity
#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
setgid();
------------------------- set group identity
#include <sys/types.h>
#include <unistd.h>
int setgid(gid_t gid);
setreuid();
setregid();//这两个函数是一个原子化的一个东西
---------setreuid, setregid - set real and/or effective user or group ID
#include <sys/types.h>
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
seteuid();
setegid();
seteuid, setegid - set effective user or group ID
#include <sys/types.h>
#include <unistd.h>
int seteuid(uid_t euid);
int setegid(gid_t egid);
例子:以某个uid来执行一个命令
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
pid_t pid;
if(argc < 3)
{
fprintf(stderr,"Usage.......\n");
}
pid=fork();
if(pid<0)
{
perror("fork()");
exit(1);
}
if(pid==0)
{
setuid(atoi(argv[1]));
execvp(argv[2],argv+2);
perror("execvp");
exit(1);
}
wait(NULL);
exit(0)