4.11 函数chown、fchown、fchownat和lchown

本文介绍了chown、fchown、fchownat和lchown四个函数,它们用于更改文件的用户ID和组ID。文章详细解释了这些函数的参数、返回值及使用场景,并讨论了不同系统对文件所有者更改的限制。

    下面几个chown函数可用于更改文件的用户ID和组ID。如果两个参数owner或group中的任意一个是-1,则对应的ID不变。

#include <unistd.h>

int    chown(const char * pathname, uid_t owner, gid_t group);

int   fchown(int fd, uid_t owner, gid_t group);

int   fchownat(int fd, const char * pathname, uid_t owner, gid_t group, int flag);

int lchown(const char* pathname, unid_t owner, gid_t group);

                                                            4个函数的返回值:若成功,返回0;若出错,返回-1        

    除了所引用的文件时符号链接以外,这4个函数的操作类似。在符号链接情况下,lchown和fchownat(设置了AT_SYMLINK_NOFOLLOW标志)更改符号链接本身的所有者,而不是该符号链接所指向的文件所有者。

    fchown函数改变fd参数指向的打开文件的所有者,既然它在一个已打开的文件上操作,就不能用于改变符号链接的所有者。

    fchownat函数与chown或者lchown函数在下面两种情况是相同的:一种是pathname参数为绝对路径,另一种是fd参数取值为AT_FDCWD而pathname参数为相对路径。在这两种情况下,如果flag参数中设置了AT_SYMLINK_NOFOLLOW标志,fchownat与lchown行为相同,如果flag参数中清楚了AT_SYMLINK_NOFOLLOW标志,则fchownat与chown行为想听。如果fd参数设置为打开目录的文件描述符,并且pathname参数是一个相对路径名,fchownat函数计算相对于打开目录的pathname。

    基于BSD的系统一直规定只有超级用户才能更改一个文件的所有者。这样做的原因是防止用户改变其文件的所有者从而摆脱磁盘空间限额对他们的限制。System V则允许任一用户更改他们所拥有的文件的所有者。

    回忆2.6节,_POSIX_CHOWN_RESTRICTED常量可选地定义在头文件<unistd.h>中,而且总是可以用pathconf或fpathconf函数进行查询。此选项还与所选用的文件有关--可在每个文件系统基础上,使该选项其作用或不起作用。在下文中,如提及“若_POSIX_CHOWN_RESTRICTED生效”,则表示“这适用于我们正在谈及的文件”,而不管该实际常量是否在头文件中定义。

    若_POSIX_CHOWN_RESTRICTED对指定的文件生效,则

  • 只有超级用户进程能更改该文件的用户ID;
  • 如果进程拥有此文件(其有效用户ID等于该文件的用户ID),参数owner等于-1或文件的用户ID,并且参数group等于进程的有效组ID或进程的附属组ID之一,那么一个非超级用户进程可以更改该文件的组ID。

    这意味着,当_POSIX_CHOWN_RESTRICTED有效时,不能更改其他用户文件的用户ID。你可以更改你所用的文件的组ID,但只能改到你所属的组。

    如果这些函数由非超级用户进程调用,则在成功返回时,该文件的设置用户ID位和设置组ID位都被清除。


<think> 我们被要求解释chown函数的作用,并且最后必须提出3-5个相关问题。 首先,chown是一个在Unix/Linux系统中用于更改文件或目录的所有者所属组的函数。 然后,根据要求,在回答的最后以“§§相关问题§§”开头,然后列出3-5个相关问题。 注意:回答必须用中文,并且按照格式要求。 </think> `chown`函数是Unix/Linux系统中的核心文件系统操作函数,用于修改**文件或目录的所有权**。其名称来源于"change owner"的缩写,通过系统调用直接修改文件的元数据属性。 ### 核心功能解析 ```c #include <unistd.h> int chown(const char *path, uid_t owner, gid_t group); // 路径版 int fchown(int fd, uid_t owner, gid_t group); // 文件描述符版 int lchown(const char *path, uid_t owner, gid_t group); // 符号链接版 ``` | 参数 | 类型 | 说明 | |---------|------------|--------------------------| | `path` | `const char*` | 文件/目录路径 | | `fd` | `int` | 已打开文件的描述符 | | `owner` | `uid_t` | 新的用户ID (所有者UID) | | `group` | `gid_t` | 新的组ID (所属组GID) | **返回值**: - 成功时返回 `0` - 失败时返回 `-1` 并设置 `errno` --- ### 关键作用场景 1. **权限转移** 将web服务器日志文件所有权从`root`转移给专用用户`www-data`: ```bash chown www-data:www-data /var/log/nginx/access.log ``` 2. **安全隔离** 容器启动时修改挂载目录所有权,避免容器内进程以root运行: ```bash chown 1000:1000 /data # 映射到容器内UID=1000的用户 ``` 3. **跨用户协作** 共享目录设置公共组权限: ```bash chown :dev-team /project # 设置组所有权 chmod 770 /project # 组成员可读写 ``` 4. **修复权限错误** 解决"Permission denied"问题: ```bash sudo chown $USER download.zip # 获取被root误占用的文件 ``` --- ### 权限规则与限制 1. **特权要求**: - 只有**超级用户(root)** 可任意修改所有权 - 普通用户仅能修改自己拥有的文件,且: - 目标`owner`必须是当前用户 - 目标`group`必须是用户所属组之一 2. **特殊标识符**: - `-1` 参数表示保留原值(Linux特有) ```c chown("file.txt", -1, 1000); // 只修改组,保留原所有者 ``` 3. **符号链接处理**: - `chown()` 修改链接指向的文件 - `lchown()` 修改链接文件本身的所有权 --- ### 典型错误处理 | errno 值 | 常量 | 原因 | 解决方案 | |----------|-----------------|--------------------------|---------------------------| | `EPERM` | 权限不足 | 非root用户尝试更改UID | 使用sudo或修改组而非用户 | | `ENOENT` | 文件不存在 | 路径错误或文件被删除 | 检查路径拼写 | | `EFAULT` | 非法内存访问 | 路径指针越界 | 验证指针有效性 | | `EROFS` | 只读文件系统 | 目标位于CD-ROM等介质 | 重新挂载为可写 | --- ### 使用示例 ```c #include <stdio.h> #include <unistd.h> int main() { const char *file = "test.txt"; if (chown(file, 1001, 1002) == -1) { // UID=1001, GID=1002 perror("chown failed"); return 1; } printf("Ownership changed successfully\n"); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值