1、实际用户ID与有效用户ID(相对于进程而言)
用户ID也即USR ID,即进程的当前登录用户ID。
- 实际用户ID
实际用户 ID 和实际组 ID 确定了进程所属的用户和组,shell 从/etc/passwd 文件中读取相应用户密码记录的第三字段和第四字段,置为其实际用户 ID和实际组 ID。 - 有效用户ID
有效用户ID决定着进程的权限,一般有效用户ID等于实际用户ID,但有两种方法使二者不同,一是系统调用,二是进程运行set-user-ID程序。
2.Set-User-ID程序(相对于程序而言)
可执行文件拥有两个特别的权限位 set-user-ID 位和 set-group-ID 位,可使用 chmod 命令来设置这些权限位:
#ls -l prog
-rwxr-xr-x 1 root root ...
#chmod u+s prog //开启set-ust-ID位
#chmod g+s prog //开启set-group-ID位
开启后可执行权限的 x 标识会被 s 标识所替换:
#ls -l prog
-rwsr-sr-x 1 root root ...
当运行 set-user-ID 程序(即通过调用 exec()将 set-user-ID 程序载入进程的内存中)时,内核会将进程的有效用户 ID 设置为可执行文件的用户 ID。
例如:如果一个可执行文件的属主为 root(超级用户),且为此程序设置了 set-user-ID 权限位,那么当运行该程序时,进程会取得超级用户权限。
3.保存 set-user-ID
保存set-user-ID用于将进程的有效用户 ID 在实际用户 ID 和保存 set-user-ID之间切换。
例如:
假设某进程的实际用户 ID、有效用户 ID 和保存 set-user-ID 均 为 1000,当其执行了 root 用户(用户 ID 为 0)拥有的 set-user-ID 程序后,实际ID为1000,有效ID和保存set-user-ID都为0,那么就可以使用系统调用使进程的有效用户 ID 在实际用户 ID 和保存 set-user-ID之间切换。
4.获取实际ID与有效ID系统调用
uid_t getuid(void); //获取实际ID
uid_t geteuid(void); //获取有效ID
5.修改有效ID、实际ID、保存设置ID
- 修改有效ID
int seteuid(uid_t euid);
说明:
A.非特权级进程仅能将其有效 ID 修改为相应的实际 ID 或者保存设置 ID。
B.特权级进程能够将其有效 ID 修改为任意值。若特权进程使用 seteuid()将其有效用户 ID 修
改为非 0 值,那么此进程将不再具有特权(但可以根据规则 1 来恢复特权,还有一种不可恢复的调用,暂不给出)。
例如:
一个进程在执行了一个set-usr-ID程序后,有效ID与实际ID已经不同,可以用下面的例子将有效ID在实际ID和保存ID间切换:
euid = geteuid(); //获取有效ID,保存在euid中,euid就是保存ID,因为此时保存ID=有效ID
if(seteuid(getuid()) == -1) //将有效ID设置为实际ID
errexit("...");
if(seteuid(euid) == -1) //将有效ID恢复为保存ID
errexit("...");
- 修改实际ID和有效ID
int setreuid(uid_t ruid,uid_t euid); //第一参数为实际ID,第二个为有效ID
修改规则与前述类似。
- 获取与设置实际、有效、保存ID
获取:
int getresuid(uid_t *ruid,uid_t *euid, uid_t *suid);
第一个参数为实际ID,第二个有效ID,第三个保存ID,一次调用获取三个ID。
设置:
int setresuid(uid_t ruid,uid_t euid,uid_t suid);