UID、GID和权限

    在UNIX系统中,用户有权限、进程有权限、文件有权限,有点混乱,有必要做一个总结。

1、用户权限

2、文件访问权限

    《UNIX环境高级编程》p13中提到,对于磁盘上的每个文件,文件系统都存放文件所有者的用户ID和组ID。也就是说,文件只能拥有,每个文件都属于特定的用户和特定的组。使用ls -l可以查看文件的所有者的用户名和组名。下面是Ubuntu10.04下的截图。


    上图中Desktop的用户是root,组是liyihai。

3、进程权限

    《UNIX环境高级编程》P12中提到,如果一个进程具有超级用户权限,则大多数文件权限检查都不再进行。某些操作系统功能只限于向超级用户提供,超级用户最系统有自由的支配权。

    疑问一:一个进程的权限由程序的文件权限决定还是执行这个进程的用户权限决定呢?

   下面做一个测试。

#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
int main(void){
	printf("uid = %d, gid = %d\n", getuid(), getgid());
	exit(0);
}

    将上面的代码编译号,将生产的可执行文件的用户名改为liyihai,如下图

  

    然后使用root用户去执行这个程序,结果如下。


    由结果可见,虽然a.out的所有者为liyihai,但是root用户执行它后,其用户id是0,即root的用户id。

    可以得出结论:进程的权限是由用户权限决定的,而不是程序文件的权限。 然而,根据《UNIX环境高级编程》2ndP75的说法,这也是不绝对的!

    文中说,与一个进程相关的ID有6个:实际UID/GID,有效UID/GID,设置UID/GID。

    实际UID/GID在登陆时就确定,一般不改变。而有效UID/GID会根据执行的(比如打开、读、写等操作,并非指二进制可执行文件!)文件是否开启了设置UID/GID而变化。如果一个文件没有开启设置UID/GID,就是上面截图的结果,其有效UID/GID和实际UID/GID一样;

    如果一个文件开启了设置UID,那么对这个文件进行操作的进程的有效UID就会变成这个文件的UID!也就是说,如果一个文件的UID是root,一个普通进程打开它之后,这个进程的有效UID就变成了root!

    需要注意的是,改变的是有效UID/GID,而不是实际的UID/GID,有效UID/GID用于文件的访问。

    疑问二:进程是被拥有还是主动拥有?

     在2中提到过,文件只能拥有,其实,进程也一样。在《UNIX环境高级编程》p14中提到,当向一个进程发送信号时,我们必须是该进程的所有者或者是超级用户。

     因此,不管是文件还是进程,都是用户的财产,用户才是一切权利的中心!参考资料[1]P192也提到:“在UNIX系统中,特权是基于用户和组ID的。”这就更加印证了这个说法。

4、权限的变化

    在参考资料[1]P192中提到,当程序需要增加特权,或需要访问当前并不允许访问的资源是,需要更换自己的用户ID或者组ID,使得新ID具有适合的特权或访问权限;反过来,当程序需要降低其特权或者阻止对某些资源的访问时,也需要更换用户ID或组ID,从而使新ID不具有相应特权或访问这些资源的能力。

    参考资料[1]P192对于这个问题还给出了编程的提示:在设计应用程序时,总是试图使用最小特权模型。


参考资料

[1]《UNIX环境高级编程》2nd

[2]如何更改linux文件的拥有者及用户组(chown和chgrp)

你可能感兴趣的:(UID、GID和权限)