APUE-文件和目录(二)函数access,mask,chmod和粘着位

小编 2026-06-24 阅读:568 评论:0
4.7 函数access和faccessat当一个进程使用了设置用户ID和设置组ID作为另一个用...

APUE-文件和目录(二)函数access,mask,chmod和粘着位

4.7 函数access和faccessat

当一个进程使用了设置用户ID和设置组ID作为另一个用户(或者组)运行时,这时候有效用户(组)ID和实际用户(组)ID不一样,但进程仍然希望测试实际用户(组)ID的访问能力。这时候就可以使用access和faccessat。测试步骤同4.5节一样,但将有效改为实际

#include <unistd.h>int access(const char *pathname,int mode);int faccessat(int fd,const char*pathname,int mode,int flag);//两个函数的返回值:若成功烦怒I0;若出错,返回-1

其中,如果测试文件是否已经存在,mode就为F_OK;否则mode是图4-7中所列常量的按位或。

APUE-文件和目录(二)函数access,mask,chmod和粘着位

flag参数可以用于改变faccessat的行为,如果flag设置为AT_EACCESS,访问检查用的是调用进程的有效用户ID和有效组ID,而不是实际用户ID和实际组ID。

4.8 函数umask

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

#include <sys/stat.h>mode_t umask(mode_t cmask);

其中,参数cmask是由图4-6中列出的9个常量中的若干个按位"或“构成的。
在文件模式创建屏蔽字中为1的位,在文件mode中的相应位一定被关闭。

看下面的例子:

首先将屏蔽位设为0,然后创建一个文件,发现默认创建的文件mode为u=rw,g=rw,o=rw(666)

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask 0harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -Su=rwx,g=rwx,o=rwxharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test.txtharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll test.txt-rw-rw-rw- 1 harlan harlan 0  6月  5 21:02 test.txt

下面更新文件模式屏蔽字,并创建文件:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask 027harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -Su=rwx,g=rx,o=harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test2.txtharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll test2.txt-rw-r----- 1 harlan harlan 0  6月  5 21:05 test2.txt

因为group的x和other的rwx被屏蔽掉了,因此得到上面的结果。

umask值表示为8进制数,一位代表一种要屏蔽的权限,见下图所示:

APUE-文件和目录(二)函数access,mask,chmod和粘着位
注意: 用数字和符号表示文件模式屏蔽字的不同,数字中的1表示的是要屏蔽的权限,而符号中显示的是支持的权限。

4.9 函数chmod

chmod使得我们可以更改现有文件的访问权限。

#include <sys/stat.h>int chmod(const char*pathname,mode_t name);成功返回0;出错返回-1

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

疑问:可读可写可执行权限和chmod有关系么?
答:没有任何关系。

看下面一个简单的例子,创建一个其他用户可读可写可执行的文件所有者为root的文件:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll chmod.txt-rw-r--rwx 1 root root 0  6月  5 21:16 chmod.txt

在harlan用户下创建下面的程序:

#include <fcntl.h>#include <stdio.h>int main(void){    struct stat statbuf;    if(stat("chmod.txt",&statbuf)<0)      printf("stat error!
");    int rv = chmod("chmod.txt",statbuf.st_mode & ~S_IRWXO);//remove the other's read write and execute    if(rv < 0)    {        printf("chmod error!
");    }    return 0;}

上面的程序尝试在harlan用户下来修改chmod.txt文件的权限位,harlan用户对chmod.txt是可读可写可执行的。但是它不能修改此文件的权限位,结果打印:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.outchmod error!

参数mode是图4-11中所示的常量的按位或:

APUE-文件和目录(二)函数access,mask,chmod和粘着位

注意:chmod函数修改的是i节点最近一次被更改的时间,而并不是最后修改文件内容的时间。

注意:如果新文件的组ID不等于进程的有效组ID或者进程附属组ID中的一个,并且进程没有超级用户权限,那么设置组ID位会被自动关闭。在linux3.2.0中,如果没有超级用户权限的进程写一个文件,则设置用户ID位和设置组ID位会被自动清除。看下面的例子:

对于文件chmod.txt,我们同时设置了设置用户ID和设置组ID,

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll chmod.txt-rwSr-srwx 1 root root 4  6月  5 22:16 chmod.txt

写一段代码来用普通用户权限写这个文件

#include <fcntl.h>#include <stdio.h>void PrintSetUserID(unsigned int st_mode){    if(st_mode&S_ISUID)    {        printf("set-user-ID is 1.
");    }    else    {        printf("set-user-ID is 0.
");    }}void PrintSetGroupID(unsigned int st_mode){    if(st_mode&S_ISGID)    {        printf("set-group-ID is 1.
");    }    else    {        printf("set-group-ID is 0.
");    }}void ClearSetUserID_SetGroupID(){    struct stat statbuf;    if(stat("chmod.txt",&statbuf)<0)      printf("stat error!-");    else    {        PrintSetUserID(statbuf.st_mode);        PrintSetGroupID(statbuf.st_mode);    }    int fd = open("chmod.txt",O_RDWR);    ssize_t num = write(fd,"test",4);    printf("write num:%d
",(int)num);    if(stat("chmod.txt",&statbuf)<0)      printf("stat error!--
");    else    {        PrintSetUserID(statbuf.st_mode);        PrintSetGroupID(statbuf.st_mode);    }}int main(void)                      {                                       ClearSetUserID_SetGroupID();        return 0;                       }                                   

运行结果:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.outset-user-ID is 1.set-group-ID is 1.write num:4set-user-ID is 0.set-group-ID is 0.

4.10 粘着位

  • 对于文件的粘着位,因为现今的UNIX系统大多都配置了虚拟存储系统以及快速文件系统,所以不再需要这个设置。
  • 对于目录的粘着位,如果你为一个目录设置了粘着位,只有对该目录具有写权限的用户并且满足下列条件之一,才能删除或重命名该目录下的文件:
  1. 拥有此文件;
  2. 拥有此目录;
  3. 是超级用户。

看下面的例子:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ mkdir dirharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod 777 dirharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll...drwxrwsrwx 2 harlan harlan    0  6月  5 22:47 dir...harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod o+t dirharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll...drwxrwsrwt 2 harlan harlan    0  6月  5 22:47 dir...

疑问:粘着位和其他写是否同时存在?见下面的代码:

#include <fcntl.h>                                  #include <stdio.h>                                                                                      void main()                                         {                                                       struct stat statbuf;                                if(stat("dir",&statbuf))                              printf("stat error!
");                                                                              if(statbuf.st_mode & S_ISVTX)                       {                                                       printf("sticky bit is set!
");                 }                                                                                                       if(statbuf.st_mode & S_IXOTH)                       {                                                       printf("other execute bit is set!
");         }                                               }                                                   

输出结果为:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.outsticky bit is set!other execute bit is set!

可见是可以同时存在的。同时存在和只存在黏着位的显示有什么区别呢?见下面的例子:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod 776 dirdrwxrwsrw- 2 harlan harlan    0  6月  5 22:47 dirharlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod o+t dirdrwxrwsrwT 2 harlan harlan    0  6月  5 22:47 dir

可见如果只有粘着位其它的第三位为大写的T,如果是小写表示粘着位+可执行。

/var/tmp 目录设置了粘着位+任意用户的可读可写可执行

harlan@DESKTOP-KU8C3K5:/var$ ll总用量 12drwxr-xr-x 2 root root   0  4月 11  2014 backupsdrwxr-xr-x 2 root root   0  3月 30 14:52 cachedrwxrwxrwt 2 root root   0  3月 30 14:52 crashdrwxr-xr-x 2 root root   0  4月 27 22:17 libdrwxrwsr-x 2 root staff  0  4月 11  2014 locallrwxrwxrwx 1 root root   9  3月 30 14:50 lock -> /run/lockdrwxrwxr-x 2 root syslog 0  5月  1 21:38 logdrwxrwsr-x 2 root mail   0  3月 30 14:50 maildrwxr-xr-x 2 root root   0  3月 30 14:50 optlrwxrwxrwx 1 root root   4  3月 30 14:50 run -> /rundrwxr-xr-x 2 root root   0  3月 30 14:50 spooldrwxrwxrwt 2 root root   0  6月  5 22:28 tmp

我们用root用户在tmp目录下面创建一个文件:

root@DESKTOP-KU8C3K5:/var/tmp# ll总用量 4drwxrwxrwt 2 root root 0  6月  5 22:28 ./drwxr-xr-x 2 root root 0  3月 30 14:53 ../-rw-r--r-- 1 root root 0  6月  5 22:28 test.txt

尝试在harlan用户下删除:

harlan@DESKTOP-KU8C3K5:/var/tmp$ rm test.txtrm:是否删除有写保护的普通空文件 "test.txt"? yrm: 无法删除"test.txt": 不允许的操作

虽然harlan用户对这个目录具有写权限,但因为所在目录设置了粘着位,并且不满足上述任意三个条件之一,因此不讷讷个删除文件。


作者:HarlanC

博客地址:http://www.cnblogs.com/harlanc/
个人博客: http://www.harlancn.me/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接

如果觉的博主写的可以,收到您的赞会是很大的动力,如果您觉的不好,您可以投反对票,但麻烦您留言写下问题在哪里,这样才能共同进步。谢谢!

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表