文件属主
每个文件都有一个与之关联的用户 ID(UID)和组 ID(GID),籍此可以判定文件的属主和属组
新建文件的属主
- UID和进程的有效用户ID相同
- GID和进程的有效组ID(等同于 System V 系统的默认行为),或者父目录的组ID(BSD 系统的行为)相同
当为项目创建目录时,需要该目录下的所有文件隶属于某一特定组,并且可为该组所有成员所访问。
改变文件属主:chown()、fchown()和 lchown()
系统调用 chown()、lchown()和 fchown()可用来改变文件的属主(用户 ID)和属组(组ID)
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
#include <unistd.h>
int lchown(const char *path, uid_t owner, gid_t group);
#include <unistd.h>
int fchown(int fildes, uid_t owner, gid_t group);
以上 3 个系统调用之间的区别类似于 stat()系统调用一族。
- chown()改变由 pathname 参数命名文件的所有权。
- lchown()用途与 chown()相同,不同之处在于若参数 pathname 为一符号链接,则将会
改变链接文件本身的所有权,而与该链接所指代的文件无干。 - fchown()也会改变文件的所有权,只是文件由打开文件描述符 fd 所引用。
参数 owner 和 group 分别为文件指定新的用户 ID 和组 ID。若只打算改变其中之一,只需将另一参数置为−1,即可令与之相关的 ID 保持不变。
只有特权级进程(CAP_CHOWN)才能使用 chown()改变文件的用户 ID。非特权级进程可使用 chown()将自己所拥有文件的组 ID 改为其所从属的任一属组的 ID,前提是进程的有效用户ID 与文件的用户 ID 相匹配。特权级进程则可将文件的组 ID 修改为任意值。
如果文件组的属主或属组发生了改变,那么 set-user-ID 和 set-group-ID 权限位也会随之关闭。这一安全举措是为了防止如下行为:普通用户若能打开某一可执行文件的 set-user-ID(或 set-group-ID)位,然后再设法令其为某些特权级用户(或组)所拥有,就能在执行该文件时获得特权用户身份。
改变文件的属主和属组时,如果已然屏蔽了属组的可执行权限位,或者要改变的是目录的所有权时,那么将不会屏蔽 set-group-ID 权限位。在上述两种情况下,set-group-ID 位的用途并非是去创建一个启用了 set-group-ID 的程序,因此将该位屏蔽并不可取。set-group-ID 的其他用途如下所示
- 若屏蔽了属组的可执行权限位,则可利用 set-group-ID 权限位来启用强制文件锁定
- 当作用于目录时,可利用 set-group-ID 位来控制在该目录下创建文件的所有权
gid_t /* Return GID corresponding to 'name', or -1 on error */
groupIdFromName(const char *name)
{
struct group *grp;
gid_t g;
char *endptr;
if (name == NULL || *name == '\0') /* On NULL or empty string */
return -1; /* return an error */
g = strtol(name, &endptr, 10); /* As a convenience to caller */
if (*endptr == '\0') /* allow a numeric string */
return g;
grp = getgrnam(name);
if (grp == NULL)
return -1;
return grp->gr_gid;
}