工学1号馆

home

« | 返回首页 | »

Unix文件访问权限的屏蔽和更改

By Wu Yudong on March 08, 2016

本文主要介绍Unix文件访问权限的屏蔽和更改

文件访问权限

文件的 9 个访问权限位

 st_mode 屏蔽  意义
 S_IRUSR  用户读
 S_IWUSR  用户写
 S_IXUSR  用户执行
 S_IRGRP  组读
 S_IWGRP  组写
 S_IXGRP  组执行
 S_IROTH  其他读
 S_IWOTH  其他写
 S_IXOTH  其他执行

新文件访问权限的屏蔽

umask函数为进程设置文件模式创建屏蔽字,并返回之前的值

#include <sys/stat.h>
mode_t umask(mode_t cmask);
//Returns: previous file mode creation mask

下面程序创建两个文件,创建第一个文件 foo 时将进程的文件模式创建屏蔽字清空,而创建第二个文件之前,则屏蔽了所有组和其他用户的读写权限。

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

#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
int
main(void)
{
    umask(0);
    if (creat("foo", RWRWRW) < 0) {
	    printf("creat error for foo");
        exit(-1);
    }
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if (creat("bar", RWRWRW) < 0) {
	printf("creat error for bar");
        exit(-1);
    }
    exit(0);
}

运行如下:

wu@ubuntu:~/opt/Cproject/apue/cp1$ gcc umasktest.c -o a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ umask
0002
wu@ubuntu:~/opt/Cproject/apue/cp1$ ./a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ ls -l foo bar
-rw------- 1 wu wu 0 Mar 8 01:48 bar
-rw-rw-rw- 1 wu wu 0 Mar 8 01:48 foo
wu@ubuntu:~/opt/Cproject/apue/cp1$ umask
0002

首先使用shell的umask命令在运行程序的前、后打印文件模式创建屏蔽字。由此可见,更改进程的文件模式创建屏蔽字并不影响其父进程(通常是shell)的屏蔽字

文件访问权限的更改

UNIX 提供了3个函数 chmod 、fchmod 、fchmodat实现对现有文件访问权限的更改。

#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int fd, const char *pathname, mode_t mode, int flag);
//All three return: 0 if OK, −1 on error

chmod 函数在指定的文件上进行操作,而 fchmod 函数则对已打开的文件进行操作。

要改变一个文件的访问权限,进程的有效用户 ID 必须等于文件的所有者 ID,或者该进程必须具有超级用户权限。

参数 mode 是表中所示常量的某种按位或运算构成的。

mode 说明
S_ISUID 执行时设置用户 ID
S_ISGID 执行时设置组 ID
S_IRWXU 用户读、写和执行
  S_IRUSR 用户 -读
  S_IWUSR 用户 -写
  S_IXUSR 用户 -执行
S_IRWXG 组读、写和执行
  S_IRGRP 组 -读
  S_IWGRP 组 -写
  S_IXGRP 组 -执行
S_IRWXO 其他读、写和执行
  S_IROTH 其他 -读
  S_IWOTH 其他 -写
  S_IXOTH 其他 -执行

下面程序打开了文件 foo 的设置组 ID 位、关闭了组执行位。而对于文件 bar 则强制设置为某个指定的访问权限。

#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
int
main(void)
{
    struct stat statbuf;
    if (stat("foo", &statbuf) < 0) {
        printf("stat error for foo");
        exit(-1);
    }
    if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0) {
        printf("chmod error for foo");
        exit(-1);
    }
    if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
        printf("chmod error for bar");
        exit(-1);
    }
    exit(0);
}

编译运行上面的程序:

wu@ubuntu:~/opt/Cproject/apue/cp1$ gcc chmodtest.c -o a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ ls -l foo bar
-rw------- 1 wu wu 0 Mar 8 01:48 bar
-rw-rw-rw- 1 wu wu 0 Mar 8 01:48 foo
wu@ubuntu:~/opt/Cproject/apue/cp1$ ./a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ ls -l foo bar
-rw-r--r-- 1 wu wu 0 Mar 8 01:48 bar
-rw-rwSrw- 1 wu wu 0 Mar 8 01:48 foo

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)