linux权限

1. 更改用户ID和组ID

1.1. 设置用户ID和设置组ID

与进程相关联的ID有6个或更多,如下:

 

实际用户ID

我们实际上是谁

实际组ID

有效用户ID

用于文件访问权限检查

有效组ID

附加组ID

保存的设置用户ID

由exec函数保存

保存的设置组ID

 

实际用户ID和实际组ID标识我们是谁。这两个字段在登录时取自口令文件中的登录项。

有效用户ID、有效组ID和附加组ID决定了我们的文件访问权限。

保存的设置用户ID和保存的设置组ID在执行一个程序时包含了有效用户ID和有效组ID的副本。

当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID就是实际组ID。但是如果在文件模式字(st_mode)中设置一个特殊标志,其含义是"当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID(se_uid)"。与此类似,如果在文件模式字(st_mode)中设置另一位,它使得将执行此文件的进程的有效组ID设置为文件组所有者ID(se_gid)。在文件模式字中的这两位被称为设置用户ID位(set-user-ID)和设置用户组位(set-group-ID)。

1.2. 文件访问权限

st_mode值也包含了针对文件的访问权限位。9个权限位,取自<sys/stat.h>

 

st_mode屏蔽字

意义

S_IRUSR

用户-读

S_IWUSR

用户-写

S_IXUSR

用户-执行

S_IRGRP

组-读

S_IWGRP

组-写

S_IXGRP

组-执行

S_IROTH

其他-读

S_IWOTH

其他-写

S_IXOTH

其他-执行

 

命令chmod用于修改这9个权限位。该命令允许用u表示用户(所有者),用g表示组,用o表示其他。进程每次打开、创建或删除一个文件时,内核就进行文件访问权限测试,而这种涉及文件的所有者(st_ui和st_gid)、进程的有效ID(有效用户ID和有效组ID)以及进程的附加组ID(若支持的话)。两个所有者ID是文件的性质,而两个有效ID和附加组ID是进程的性质。内核顺序进行的测试是:

1). 如果进程的有效用户ID是0(超级用户),则允许访问。

2). 如果进程的有效用户ID等于文件的所有者ID(也就是该进程拥有此文件),那么:若所有者适当的访问权限位被设置,则允许访问。

3). 如果进程的有效组ID或进程的附加组ID之一等于文件的组ID,那么:若组适当的权限位被设置,则允许访问。

4). 如果其他用户适当的访问权限位被设置,则允许访问。

 

1.3. setuid和setgid函数

在UNIX系统中,特权是基于用户和组ID的。当程序需要增加特权,或需要访问当前并不允许访问的资源时,我们需要更换自己的用户ID或组ID,使得新ID具有合适的特权或访问权限。与此类似,当程序需要降低其特权或阻止对某些资源的访问时,也需要更换用户ID或组ID,从而使新ID不再具有相应的特权或访问这些资源的能力。

一般而言,在设计应用程序时,我们总是试图使用最小特权(least privilege)模型。函数setuid设置实际用户ID和有效用户ID;函数setgid设置实际组ID和有效组ID。

#include <unistd.h>

int setuid(uid_t uid);

int setgid(gid_t gid);

 

关于改变用户ID的规则:

1). 如果进程具有超级用户特权,则setuid函数将实际用户ID、有效用户ID、以及保存的设置用户ID设置为uid。

2). 如果进程没有超级用户特权,但是uid等于实际用户ID或保存的设置用户ID,则setuid只将有效用户ID设置为uid。不改变实际用户ID和保存的设置用户ID。

3). 如果上面两个条件都不满足,则将errno设置为EPERM,并返回-1。

 

关于内核所维护的三个用户ID,还要注意以下几点:

1). 只有超级用户进程可以更改实际用户ID。实际用户ID实是用户登录时,由login程序设置的,而且永远不会改变它。因为login是一个超级用户进程,当它调用setuid时,会设置所有三个用户ID。

2). 仅仅当对程序文件设置了设置用户ID位时,exec函数才会设置有效用户ID。任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置用户ID。

3). 保存的设置用户ID是由exec复制有效ID而得到的。如果设置了程序文件的设置用户ID位,则在exec根据文件的用户ID设置了进程的有效用户ID以后,就将这个副本保存起来。

注意:getuid和geteuid函数只能获得实际用户ID和有效用户ID的当前值。改变三个用户ID的不同方法:

 

ID

exec

setuid(uid)

设置用户ID位关闭

设置用户ID位打开

超级用户

非特权用户

实际用户ID

不变

不变

设为uid

不变

有效用户ID

不变

程序文件的用户ID

设为uid

设为uid

保存的设置用户ID

从有效用户ID复制

从有效用户ID复制

设为uid

不变

 

 

POIX.1包含了两个函数setuid和setegid。它们类似setuid和setgid,但只更改有效用户ID和有效组ID。

#include <unistd.h>

int seteuid(uid_t uid);

int setegid(gid_t gid);

转自:http://blog.csdn.net/youkuxiaobin/article/details/6876820

posted on 2012-08-24 21:58  追寻前人的脚步  阅读(329)  评论(0编辑  收藏  举报

导航