0%

进程用户身份

本文所指“进程”是指在Linux操作系统下运行的进程。需要注意的是,执行“ls,cd,vim”等命令,都会创建运行进程。

一、进程用户身份的概念

1.1、进程用户身份——用户

分为“进程创建用户”和“进程有效用户”。

1.1.1、进程创建用户

指代创建进程的用户。一般来讲,该值在被初始赋值(值为“创建进程的用户”)之后不可被改变。

1.1.2、进程有效用户

指代代表进程与外界通信的用户。一般来讲,该值在被初始赋值(值为“创建进程的用户”)之后仍可被改变。该值常见的赋值模型有3种。
1、保持不变
在被初始赋值后保持不变。即“进程有效用户”跟“进程创建用户”一致。
比如当前用户为“dsl”,执行top命令,假定得到的进程ID为“13377”,再执行/bin/ps -o euser -p 13377命令,可得如下结果,从而得知进程有效用户一直为“dsl”。

1
2
EUSER
dsl

2、改变一次
在被初始赋值后改变一次。比如有一个可执行文件,它设置了SUID特殊权限,执行该可执行文件创建运行一个进程,该进程有效用户“在被初始赋值后,改变一次被赋值为该可执行文件的拥有者”。
比如有以下C源代码文件(文件名为“geteuid.c”):

1
2
3
4
5
6
7
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
//geteuid()方法能够得到进程有效用户的UID
printf("euser uid is:%d\n", geteuid());
return 0;
}

执行gcc -o geteuid geteuid.c命令,编译得到一个二进制文件“geteuid”,将该二进制文件的拥有者设为“root”,权限配置为“4777”。当前用户为“dsl”,执行./geteuid命令,得到的打印结果如下,“0”UID对应的用户名为“root”,从而得知进程有效用户为“root”(进程有效用户变化路径:“dsl”——“root”)。

1
euser uid is:0

3、改变一次,恢复到初始值
在被初始赋值后改变一次,最后再恢复到初始值。比如有一个可执行文件,它设置了SUID特殊权限,执行该可执行文件创建运行一个进程,该进程有效用户“在被初始赋值后,改变一次被赋值为该可执行文件的拥有者,最后再改变被恢复到初始值”。
“/bin/ping”命令的拥有者为“root”,权限配置信息为“4755”,执行ping www.google.com命令,假定得到的进程ID为“15216”,再执行/bin/ps -o euser -p 15216命令,可得如下结果,从而得知进程有效用户为“dsl”(进程有效用户变化路径:“dsl”——“root”——“dsl”)。

1
2
EUSER
dsl

上述内容参考以下引用:

1
2
3
4
ping needs root so it can open a socket in raw mode. That's literally the first thing it does when it starts up:
icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
socket_errno = errno;
That's the only thing it needs root for, so like many programs, it immediately drops its privilege level back to your normal user account.

1.2、进程用户身份——用户组

分为“进程创建用户组”和“进程有效用户组”。

1.2.1、进程创建用户组

指代创建进程用户的对应用户组。一般来讲,该值在被初始赋值(值为“创建进程的用户对应的用户组”)之后不可被改变。

1.2.2、进程有效用户组

指代代表进程与外界通信的用户组。一般来讲,该值在被初始赋值(值为“创建进程的用户对应的用户组”)之后仍可被改变。该值常见的赋值模型有3种。
1、保持不变
在被初始赋值后保持不变。即“进程有效用户组”跟“进程创建用户组”一致。
2、改变一次
在被初始赋值后改变一次。比如有一个可执行文件,它设置了SGID特殊权限,执行该可执行文件创建运行一个进程,该进程有效用户组“在被初始赋值后,改变一次被赋值为该可执行文件的组拥有者”。
比如有以下C源代码文件(文件名为“getegid.c”):

1
2
3
4
5
6
7
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
//getegid()方法能够得到进程有效用户组的GID
printf("egroup gid is:%d\n", getegid());
return 0;
}

执行gcc -o getegid getegid.c命令,编译得到一个二进制文件“getegid”,将该二进制文件的组拥有者设为“root”,权限配置为“2777”。当前用户为“dsl”(对应的用户组为“dsl”),执行./getegid命令,得到的打印结果如下,“0”GID对应的用户组为“root”,从而得知进程有效用户组为“root”(进程有效用户组变化路径:“dsl”——“root”)。

1
egroup gid is:0

3、改变一次,恢复到初始值
在被初始赋值后改变一次,最后再恢复到初始值。比如有一个可执行文件,它设置了SGID特殊权限,执行该可执行文件创建运行一个进程,该进程有效用户组“在被初始赋值后,改变一次被赋值为该可执行文件的组拥有者,最后再改变被恢复到初始值”。

二、进程用户身份的意义

在Linux操作系统中,进程用户身份非常重要,尤其是在进程通信中用于代表本进程的“<进程有效用户,进程有效用户组>”,比如在判定一个进程是否拥有对文件的“读取,修改,执行”权限时,使用的进程用户身份就是“<进程有效用户,进程有效用户组>”。


参考文献: [1]http://www.lst.de/~okir/blackhats/node23.html [2]http://www.makelinux.net/alp/083 [3]http://en.wikipedia.org/wiki/User_identifier [4]http://stackoverflow.com/questions/8499296/realuid-saved-uid-effective-uid-whats-going-on [5]http://stackoverflow.com/questions/205070/whats-the-deal-with-all-the-different-uids-a-process-can-have [6]http://unix.stackexchange.com/questions/51874/root-owned-program-with-setuid-bit-on
您的支持将鼓励我继续分享!