linux进程标识符具体解释1

Posted zsychanpin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux进程标识符具体解释1相关的知识,希望对你有一定的参考价值。

每一个进程都有一个实际用户标识符和一个实际组标识符,它们永远是启动该进程之用户的用户标识符和组标识符。

进程有效用户标识符有效组标识符或许更重要些,它们被用来确定一个用户是否能訪问某个确定的文件。在通常情况下,它们与实际用户标识符和实际组标识符是一致的

有几个系统调用能够用来得到进程的用户标识符和组标识符,详见下列程序:

/* 取进程的实际用户标识符 */
        uid=getuid();
/* 取进程的有效用户标识符 */
       euid=geteuid();
/* 取进程的实际组标识符 */
      gid=getgid();
/* 取进程的有效组标识符 */
      egid=getegid();

另外,还有两个系统调用能够用来设置进程的有效用户标识符和有效组标识符,它们的使用格式例如以下:
/* 设定进程的有效用户标识符 */
      status=setuid(newuid);
/* 设定进程的有效组标识符 */
      status=setgid(newid)

通过这两个系统调用。进程能够改变自己的标识符,进而改变自己的权限(由于Linux中权限是通过标识符来推断的)。

比方一个root 建立的进程能够用这样的方法放弃一部分的root 权限而仅仅保留工作所需的权限。

这样能够提高系统的安全性。

<span style="font-size:14px;">#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>

int main(int argc,char* argv[])
{
	int fd;
	fd = fork();
	switch(fd){
		case -1:{
			perror("fork"); 
			exit(-1);	
		} 
		break;
		case  0:
		{  //開始进程用户id和有效用户id
			printf("uid=%d,euid=%d\n",getuid(),geteuid());
			
			//设置用户id为1000。改变用户权限
			setuid(1000);
		
			//改变后的用户id和有效用户id
			printf("uid=%d,euid=%d\n",getuid(),geteuid());
			
			//root用户才干查看shadow文件,測试权限是否改变
			execlp("cat","cat","/etc/shadow",NULL);
		} 
		break;
		default:
		{ //開始进程用户id和有效用户id
			printf("uid=%d,euid=%d\n",getuid(),geteuid());
			//root用户才干查看shadow文件
			execlp("cat","cat","/etc/shadow",NULL);
		}
		break;
	}
	
	return 0;	
}
</span>

在root权限下执行结果:

        [[email protected] file]# ./a.out
        uid=0,euid=0
        uid=1000,euid=1000
        cat: /etc/shadow: 权限不够
        uid=0,euid=0
      root:$$MG0tTs8yWCPoKMrG$tVrZQKQ6IK52ucaSGfHIMKdVHB7zP.rpqD5GO/1w07eYQj0Jgue9S/UijUtyYYQa9Irm2vwj7r.DwaY.5IXIp0:15195:0:99999:7:::
        bin:*:14789:0:99999:7:::

可是须要注意的是,一旦root 进程通过这样的方式放弃了root 特权,将无法再通过setuid()调用的方式又一次获得root权,由于一个非root 标识符的进程是无法设定root 标识符的。这时能够使用Linux 的另外两个系统调用seteuid()和setegid()。其调用方式和前两个全然同样。可是它们是依据进程程序文件的标识符来推断设定的。因此,一个root 的程序文件在不论什么时候都能够将自己又一次seteuid()为root。

<span style="font-size:14px;">#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>

int main(int argc,char* argv[]){

	//開始进程用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());
			
	//设置用户id为1000。改变用户权限
	setuid(1000);
		
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	//设置用户id为0,改变用户权限为root
	if(-1 == setuid(0)){
		perror("setuid to root");
		exit(-1);
	}
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	return 0;
}
</span>

root下执行结果:

[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
setuid to root: Operation not permitted

<span style="font-size:14px;">#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>

int main(int argc,char* argv[]){

	//開始进程用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());
			
	//设置用户id为1000。改变用户权限
	setuid(1000);
		
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	//设置用户id为1000,改变用户权限为自己
	if(-1 == setuid(1000)){
		perror("setuid to root");
		exit(-1);
	}
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	return 0;
}</span>

执行结果:

技术分享

以上样例说明不是超级用户所引用的进程,仅仅能把它的有效用户表示符和有效组标识符又一次设置成事实上际用户标识符和实际组标识符。

超级用户所引用的进程就能够自由进行其有效用户标识符和有效组标识符的设置。

以上使用setuid()永久改变权限。如今使用seteuid()临时改变用户权限:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>

int main(int argc,char* argv[]){

	//開始进程用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());
			
	//设置有效用户id为1000。临时改变用户权限
	seteuid(1000);
		
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	//设置有效用户id为0,改变用户权限为自己
	if(-1 == setuid(0)){
		perror("setuid to root");
		exit(-1);
	}
	//改变后的用户id和有效用户id
	printf("uid=%d,euid=%d\n",getuid(),geteuid());

	return 0;
}

执行结果:

#./a.out

uid=0,euid=0

uid=0,euid=1000

uid=0,euid=0


[[email protected] file]# ./a.out
uid=0,euid=0
uid=0,euid=1000
uid=0,euid=0技术分享技术分享[[email protected] file]# ./a.out
uid=0,euid=0
uid=0,euid=1000
uid=0,euid=0

 

 


[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000[[email protected] file]# ./a.out
uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000

      

 
















































以上是关于linux进程标识符具体解释1的主要内容,如果未能解决你的问题,请参考以下文章

linux的fork()函数具体解释 子进程复制父进程什么

有人可以解释以下 R 代码片段吗? [关闭]

LINUX PID 1和SYSTEMD PID 0 是内核的一部分,主要用于内进换页,内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程(代码片段

Linux进程管理(鸟哥)

Linux标识进程

Linux-进程的观察