《UNIX环境高级编程》学习之——更改用户ID组ID

来源:互联网 发布:linux virsh 命令 编辑:程序博客网 时间:2024/05/17 18:29

UNIX系统为了总是以最小特权去执行一个程序,给出了setuid和setgid函数原型如下:

#include<unistd.h>

int setuid(uid_t uid);

int setgid(gid_t gid);

用户ID和组ID的更改规则是相通的,大家可以举一反三,下面写的都是关于用户ID的,组ID一样的原理。


一个进程有自己的 

       实际用户ID(谁的程序)

       有效用户ID(执行其他程序时的权限)

       设置用户ID(由exec复制有效用户ID得来的)


谁能更改用户ID:

       exec函数

       setpid


修改ID(用户ID或者组ID)的一些规则:

1、如果进程拥有root,也就是超级用户权限,那牛掰了,只要该进程执行setuid函数就可以将自己的,实际用户ID、有效用户ID、以及稍后会提到的保存的设置用户ID更改为参数uid。

2、若进程只是普普通通的“老百姓”,UNIX的普通用户,那该进程只能改变自己的有效用户ID,而这个有效用户ID是会跟自己的实际用户ID或者设置用户ID一样。也就是说,普通用户进程执行setuid函数,参数跟自己的实际用户ID 或者 设置用户ID 一致。(可以了解到,普通用户只可以更改自己的有效用户ID,而且改也只能改成实际ID或者设置ID)

3、以上两种都不满足的,执行setuid函数就会出错。


三个用户ID的特点:

       1、只有超级用户的进程可以更改实际用户ID

       2、这里又引入了一个叫做 设置用户ID位 的概念,只有这一位设置了,exec才会设置用户ID

             但是setpid函数没有这个限制,任何时候都可以通过setpid函数来把有效用户ID设置成实际用户ID或者设置用户ID

       3、保存的设置用户ID 来自exec复制有效ID得来的,


关于设置用户ID:

       以我们的进程执行 man程序为例;

       man程序的实际用户ID是man,有效用户ID也是man,:1、我们要执行man命令   2、man也要执行命令;

                 1、首先我们的进程要执行man命令,所以exec把我们进程的有效用户ID给改了,改成man了,并且复制了man给设置用户ID,然后我们就可以顺利执行man命令了。

                                        此时我们进程的ID:

                                               实际用户ID = 我们的用户ID

                                               有效用户ID = man(为了执行man命令)

                                   保存的设置用户ID = man(exec设置的)

                 2、我们的进程要求man执行其他命令,但是现在我们的有效ID是man,所以需要更改有效ID为我们进程的实际ID,调用setuid(getuid())函数

                                               实际用户ID = 我们的用户ID

                                               有效用户ID = 我们的用户ID(setuid改的)

                                   保存的设置用户ID = man

                 3、man执行完我们的命令之后,会改变有效用户ID为man

                                               实际用户ID = 我们的用户ID

                                               有效用户ID = man

                                   保存的设置用户ID = man

这时我们发现了保存的设置用户ID在ID转换过程中的作用!实际用户ID是不变的,确保我们可以将有效用户ID改成实际用户ID。在exec新程序之后,会引入新程序的有效用户ID,保存为设置用户ID,这样进程的有效用户ID也可以改成新程序的有效用户ID。