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中所列常量的按位或。

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 0
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -S
u=rwx,g=rwx,o=rwx
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test.txt
harlan@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 027
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -S
u=rwx,g=rx,o=
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test2.txt
harlan@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进制数,一位代表一种要屏蔽的权限,见下图所示:



注意: 用数字和符号表示文件模式屏蔽字的不同,数字中的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!\n");
int rv = chmod("chmod.txt",statbuf.st_mode & ~S_IRWXO);//remove the other's read write and execute
if(rv < 0)
{
printf("chmod error!\n");
}
return 0;
}

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

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

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

注意: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.\n");
}
else
{
printf("set-user-ID is 0.\n");
}
} void PrintSetGroupID(unsigned int st_mode)
{
if(st_mode&S_ISGID)
{
printf("set-group-ID is 1.\n");
}
else
{
printf("set-group-ID is 0.\n");
}
}
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\n",(int)num);
if(stat("chmod.txt",&statbuf)<0)
printf("stat error!--\n");
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.out
set-user-ID is 1.
set-group-ID is 1.
write num:4
set-user-ID is 0.
set-group-ID is 0.

4.10 粘着位

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

看下面的例子:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ mkdir dir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod 777 dir
harlan@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 dir
harlan@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!\n"); if(statbuf.st_mode & S_ISVTX)
{
printf("sticky bit is set!\n");
} if(statbuf.st_mode & S_IXOTH)
{
printf("other execute bit is set!\n");
}
}

输出结果为:

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

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

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

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

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

harlan@DESKTOP-KU8C3K5:/var$ ll
总用量 12
drwxr-xr-x 2 root root 0 4月 11 2014 backups
drwxr-xr-x 2 root root 0 3月 30 14:52 cache
drwxrwxrwt 2 root root 0 3月 30 14:52 crash
drwxr-xr-x 2 root root 0 4月 27 22:17 lib
drwxrwsr-x 2 root staff 0 4月 11 2014 local
lrwxrwxrwx 1 root root 9 3月 30 14:50 lock -> /run/lock
drwxrwxr-x 2 root syslog 0 5月 1 21:38 log
drwxrwsr-x 2 root mail 0 3月 30 14:50 mail
drwxr-xr-x 2 root root 0 3月 30 14:50 opt
lrwxrwxrwx 1 root root 4 3月 30 14:50 run -> /run
drwxr-xr-x 2 root root 0 3月 30 14:50 spool
drwxrwxrwt 2 root root 0 6月 5 22:28 tmp

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

root@DESKTOP-KU8C3K5:/var/tmp# ll
总用量 4
drwxrwxrwt 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.txt
rm:是否删除有写保护的普通空文件 "test.txt"? y
rm: 无法删除"test.txt": 不允许的操作

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

APUE-文件和目录(二)函数access,mask,chmod和粘着位的更多相关文章

  1. windows中操作文件和目录的函数

    1.文件操作函数       CreateFile();//创建或打开文件      ReadFile();//从文件读      WriteFile();//向文件写      SetFilePoi ...

  2. linux C之判断文件或目录是否存在 access函数

    http://blog.sina.com.cn/s/blog_6a1837e90100uh5d.html access():判断是否具有存取文件的权限 相关函数    stat,open,chmod, ...

  3. [APUE]文件和目录(中)

    一.link.unlink.remove和rename 一个文件可以有多个目录项指向其i节点.使用link函数可以创建一个指向现存文件连接 #include <unistd.h> int ...

  4. [APUE]文件和目录(上)

    一.文件权限 1. 各种ID 我在读这一章时遇到了各种ID,根据名字完全不清楚什么意思,幸好看到了这篇文章,http://blog.csdn.net/ccjjnn19890720/article/de ...

  5. PHP 文件与目录操作函数总结

    >>>文件操作 打开 fopen();    打开文件 读取内容 fread();    从文件指针 handle 读取最多 length 个字节 readfile();    读入 ...

  6. APUE 文件和目录

    文件和目录 Unix 所有的文件都对应一个 struct stat,包含了一个文件所有的信息. #include <sys/stat.h> struct stat { mode_t st_ ...

  7. Linux系统对文件及目录的权限管理(chmod、chown)

    本文命令: 4 5 6 ls -l chmod chown 1.身份介绍 在linux系统中,对文件或目录来说访问者的身份有三种: ①.属主用户,拥有者(owner)文件的创建者 ②.属组用户,和文件 ...

  8. [APUE]文件和目录(下)

    一.mkdir和rmdir函数 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *pathn ...

  9. php 文件、目录操作函数

    目录 opendir readdir closedir mkdir rmdir  : 只能删除空目录 文件 filetype filesize is_file basename dirname pat ...

随机推荐

  1. A New Function LightOJ - 1098()

    题意 求 1 - n的的所有数的因子(不包括自身和1)和 对于一个数 i  ,以i为因子的数的个数为 n/i  因为不能包括自身 所以 减一 即  n/i-1  这样遍历每一个数 累加即可 但复杂度较 ...

  2. win10远程连接

    提示凭证不工作问题 https://blog.csdn.net/sinat_25926481/article/details/50775616

  3. BZOJ 1283: 序列

    1283: 序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 272  Solved: 151[Submit][Status][Discuss] D ...

  4. Hive权限管理

    最近遇到一个hive权限的问题,先简单记录一下,目前自己的理解不一定对,后续根据自己的理解程度更新 一.hive用户的概念 hive本身没有创建用户的命令,hive的用户就是Linux用户,若当前是用 ...

  5. nodejs进程异常退出处理方法

    1. 捕获uncaughtException process.on('uncaughtException', function (err) { //打印出错误 console.log(err); // ...

  6. where EXISTS (子查询)多对多中通过中间表查对方列表

    用户表A,小组表B,小组和用户是多对多关系,中间有个中间表M 已知 小组 id 即teamId ,想知道这个小组中的用户列表信息,可以如下写sql: select * from A a where E ...

  7. 【Asp.net入门5-01】SportsStore:一个真实的应用程序

  8. 转:zookeeper中Watcher和Notifications

    转自:http://www.tuicool.com/articles/B7FRzm 传统polling远程service服务 传统远程的service往往是这样服务的,服务提供者在远程service注 ...

  9. CSS3实战之resize

    resize属性可以设置是否允许用户缩放网页中元素的大小 总共有4种取值 none vertical horizontal both 举个栗子 <!DOCTYPE html PUBLIC &qu ...

  10. [HAOI2006]旅行 题解(kruskal)

    [HAOI2006]旅行 Description Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N个景点(编号为1,2,3,-,N),这些景点被M条道路连接着,所有道路都 ...