4.11 chown、fchown和lchown函数-文件用户与用户组

时间:2022-05-04 16:42:16

chown、fchown和lchown函数用于更改文件的用户ID(stat.st_uid)和组ID(stat.st_gid)。函数原型如下:

#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int filedes, uid_t owner, gid_t group);
int lchown(const char *pathname, uid_t owner, gid_t group);
返回值:若成功返回0,若出错则返回-1

参数:

pathname 文件路径

filedes 文件描述符

owner 新用户ID,不需要修改时用使用-1

group 新组ID,不需要修改时使用-1


一、三个函数作用是一样的,只是参数和操作对象不一样:

chown函数是在指定的文件上进行操作;

fchown函数是在已打开的文件进行操作;

lchown是更改符号链接本身的所有者,而不是符号链接所指向的实际文件。


二、函数的执行权限问题

这三个函数不复杂,意义也很明显,麻烦的是什么条件下才可以调用这三个函数。也就是什么人可以更改文件的用户和用户组问题。

不同的系统规定不一样:

1、BSD系统:规定只有超级用户才能更改一个文件的所有者。

2、系统V:允许任意用户更改他们所拥有的所有者。

3、POSIX.1标准:取决于具体文件系统,需要用_POSIX_CHOWN_RESTRICTED调用pathconf或fpathconf函数来判断具体要操作的文件是否有限制,也就是该文件只允许超级用户更改还是允许任意用户更改他们所拥有的文件的所有者。

即使是允许更改也有以下严格规定:

(1)只有超级用户进程才能更改该文件的用户ID。

(2)满足系列条件,一个非超级用户进程就可以更改该文件的组ID:

(a)进程拥有此文件(其有效用户ID等于该文件的用户ID)。

(b)参数owner等于-1或者文件的用户ID,并且参数group等于进程的有效组ID或者进程的附加组ID之一。也就是说,你不能更改其他用户的用户ID,只能更改你所拥有的文件的组ID,并且只能更改到你所属的组。

实例 x.4.11.1.c

#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char           pathname1[] = "/tmp/myfile1";
    char           pathname2[] = "/tmp/myfile2";

    int            filedes;

    if (chown(pathname1, 500, 500) == -1)
        printf("chown error for %s\n", pathname1);

    if ((filedes = open(pathname2, (O_RDONLY | O_CREAT))) == -1)
        printf("open error for %s\n", pathname2);
    else if (fchown(filedes, 500, -1) == -1)
        printf("fchown error for %s\n", pathname2);

    exit(0);

}

编译与执行:

[root@localhost unixc]# rm -f /tmp/file1 /tem/file2
[root@localhost unixc]# echo "This is file1" > /tmp/myfile1
[root@localhost unixc]# echo "This is file2" > /tmp/myfile2
[root@localhost unixc]# ls -l /tmp/myfile1 /tmp/myfile2
-rw-------. 1 root root 14 Nov  4 11:17 /tmp/myfile1
-rw-rw----. 1 root root 14 Nov  4 11:17 /tmp/myfile2
[root@localhost unixc]# cc x.4.11.1.c
[root@localhost unixc]# ./a.out
[root@localhost unixc]# ls -l /tmp/myfile1 /tmp/myfile2
-rw-------. 1 zlw zlw  14 Nov  4 11:17 /tmp/myfile1
-rw-rw----. 1 zlw root 14 Nov  4 11:17 /tmp/myfile2
[root@localhost unixc]#

分析:没时间去考究那么详解权限限制问题,本例是在超级用户下编译与执行,总是能成功执行的,目的在体会函数的具体使用方法。