linux子程序标识符,linux过程标识符详解1

linux进程标识符详解1

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

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

有几个系统调用可以用来得到进程的用户标识符和组标识符,详见下列程序:/* 取进程的实际用户标识符 */

uid=getuid();

/* 取进程的有效用户标识符 */

euid=geteuid();

/* 取进程的实际组标识符 */

gid=getgid();

/* 取进程的有效组标识符 */

egid=getegid();

另外,还有两个系统调用可以用来设置进程的有效用户标识符和有效组标识符,它们的使用格式如下:/* 设定进程的有效用户标识符 */

status=setuid(newuid);

/* 设定进程的有效组标识符 */

status=setgid(newid)

通过这两个系统调用,进程可以改变自己的标识符,进而改变自己的权限(因为Linux中权限是通过标识符来判断的)。比如一个root 建立的进程可以用这种方法放弃一部分的root 权限而只保留工作所需的权限。这样可以提高系统的安全性。

#include

#include

#include

#include

#include

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;

}

在root权限下运行结果:

[root@embedclub 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。

#include

#include

#include

#include

#include

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;

}

root下运行结果:

[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

setuid to root: Operation not permitted

#include

#include

#include

#include

#include

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;

}

运行结果:

150508308.jpg

以上例子说明不是超级用户所引用的进程,只能把它的有效用户表示符和有效组标识符重新设置成其实际用户标识符和实际组标识符。超级用户所引用的进程就可以自由进行其有效用户标识符和有效组标识符的设置。

以上使用setuid()永久改变权限,现在使用seteuid()暂时改变用户权限:

#include

#include

#include

#include

#include

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

[root@embedclub file]# ./a.out

uid=0,euid=0

uid=0,euid=1000

uid=0,euid=0

150508309.jpg

150508310.jpg[root@embedclub

file]# ./a.out

uid=0,euid=0

uid=0,euid=1000

uid=0,euid=0

[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

uid=1000,euid=1000[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

uid=1000,euid=1000[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

uid=1000,euid=1000[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

uid=1000,euid=1000[root@embedclub file]# ./a.out

uid=0,euid=0

uid=1000,euid=1000

uid=1000,euid=1000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值