passwd命令是用来修改用户登陆密码的,用来记录用户登陆密码的文件为/etc/shadow,该文件只有root用户具有访问权限,如下所示:
gaolu@gaolu-desktop:~$
gaolu@gaolu-desktop:~$ cd /etc
gaolu@gaolu-desktop:/etc$ ls -l shadow
-rw-r----- 1 root shadow 978 2009-02-22 21:25 shadow
gaolu@gaolu-desktop:/etc$
这是出现了矛盾:出于安全考虑,不允许普通用户查看并修改shadow文件;但是如果这样普通用户就无法为自己修改密码。
Linux系统就是使用setuid来解决这个矛盾的问题:如果一个程序被设置了setuid位,那么它无论被哪个用户启用,都会具备程序所有者的权限。而passwd程序的所有者是root用户,passwd的权限如下所示,那么任何用户执行该程序,程序的EUID就会变成root用户的 EUID,而不是执行该程序的UID。
gaolu@gaolu-desktop:/etc$ cd /usr/bin
gaolu@gaolu-desktop:/usr/bin$ ls -l passwd
-rwsr-xr-x 1 root root 32988 2008-06-10 02:10 passwd
gaolu@gaolu-desktop:/usr/bin$
gaolu@gaolu-desktop:/usr/bin$
因此,普通用户可以通过passwd程序修改shadow文件内容,完成密码修改。
#include
#include
#include
{
printf("Current process UID: %ld\n",(long)getuid());
printf("Current process EUID: %ld\n",(long)geteuid());
return 1;
}
gaolu@gaolu-desktop:~$ gcc -o uid uid.c
gaolu@gaolu-desktop:~$
gaolu@gaolu-desktop:~$ chmod u+s uid //用户主增加权限setuid
gaolu@gaolu-desktop:~$ ls -l uid
-rwsr-xr-x 1 gaolu gaolu 9118 2009-03-08 22:26 uid
gaolu@gaolu-desktop:~$
gaolu@gaolu-desktop:~$ ./uid
Current process UID: 1000
Current process EUID: 1000
gaolu@gaolu-desktop:~$
gaolu@gaolu-desktop:~$ su //切换到root用户
Password:
root@gaolu-desktop:/home/gaolu# ls -l uid
-rwsr-xr-x 1 gaolu gaolu 9118 2009-03-08 22:26 uid
root@gaolu-desktop:/home/gaolu# ./uid
Current process UID: 0
Current process EUID: 1000 //有效用户ID为1000
root@gaolu-desktop:/home/gaolu#
root@gaolu-desktop:/home/gaolu#