|
登录系统成功后,系统会给用户的 shell一个身份,包括一个真实用户标识( UID),一个或多个真实用户组标识( GID ),一个有效用户标识( EUID )和有效用户组标识( EGID )。开始时,EUID和 EGID分别与 UID和 GID相同。这些 ID号可以在文件 /etc/passwd中找到,它们被系统用来标识用户和用户组。EUID 和 EGID决定了进程读、写或执行文件的权限。如果进程的 EUID 与文件属主的真实 UID相同,则进程具有文件的属主访问权限。如果进程的 EGID和真实的 GID相同,则进程拥有属主的组特权。
EUID 和 EGID 可以被改变为另一个属主的 ID 号。可以通过把 EUID( 或 EGID )变成另一个属主而拥有其他用户的进程。
setgid 权限的作用和系统有关。有些系统上,如果目录被设置为 setgid,那么在该目录下创建的文件都属于目录所属的同一个组。而对另一些系统,进程的 EGID 决定了哪个用户组可以使用该文件。把 EUID 或 EGID 改变为另一个属主的程序被称为 setuid 或 setgid 程序。程序 /etc/passwd 就是一个 setuid 程序的例子,它让用户使用根用户的权限。
查看 /etc/shadow 文件的属性:beyes@linux-beyes:~/Desktop> ls -l /etc/shadow
-rw-r----- 1 root shadow 1030 04-29 02:23 /etc/shadow 由上可见,这个文件只有根用户才可以修改。但事实上,当我们用 passwd 命令为我们的普通用户修改密码时是可以修改成功的,也就是说我们修改密码的信息已经写入到 shadow 文件中去,如此一来,这不是矛盾了么?
实际上,这里起作用的是 setuid 位 --- 只要这个位置位了,那么当其他用户运行这个程序时,都会拥有这个程序的拥有者的权限,如 passwd 这个命令:beyes@linux-beyes:/usr/bin> ls -l passwd
-rwsr-xr-x 1 root shadow 80268 12-03 15:15 passwd 由上可见,s 被置位了!所以,当普通用户运行 passwd 命令为自己修改密码时,它实际上拥有了这部分的 root 权限。也就是说,此时运行程序的有效UID( EUID )是 root 的 ID 而非使用者自己的真实 UID。从以下试验中可以看到:
1、在一个终端窗口运行 passwd 程序
2、在另一个终端窗口里查看:
root 11180 0.0 0.0 6740 1780 pts/1 S+ 17:15 0:00 passwd 从上看到,真正运行这个程序的有效用户是 root !
下面构造一个测试程序,代码如下:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("运行此程序的用户UID为:%d\n",getuid());
printf("此程序对应的有效UID(EUID)为:%d\n",geteuid());
return 0;
}
编译生成可执行文件后:beyes@linux-beyes:~/C/base> ll getuid.exe
-rwxr-xr-x 1 beyes users 11328 05-03 17:25 getuid.exe
置位 setuid 位:beyes@linux-beyes:~/C/base> chmod u+s getuid.exe
beyes@linux-beyes:~/C/base> ll getuid.exe
-rwsr-xr-x 1 beyes users 11328 05-03 17:25 getuid.exe
在此程序的拥有者(普通用户)权限下运行这个程序:beyes@linux-beyes:~/C/base> ./getuid.exe
运行此程序的用户UID为:1000
此程序对应的有效UID(EUID)为:1000
su 切换到 root 下运行:linux-beyes:/home/beyes/C/base # ./getuid.exe
运行此程序的用户UID为:0
此程序对应的有效UID(EUID)为:1000 |
|