Linux下C代码中修改文件访问权限

转自:http://blog.chinaunix.net/uid-25940216-id-3207480.html

【Yasi注】:注意,不能想当然的认为,调用chmod("/opt/*", S_IRUSR),就可以把/opt 目录下的所有文件和子文件夹都置成了 r-------- (400),事实上没那么简单!这样做只会把/opt目录下的第一个文件或子文件夹置成 r-------- (400),如果想把 /opt 下面所有文件和子文件都设置了,只调用一次chmod是办不到的,只有自己写个循环,做遍历才行!


这两个函数允许我们改变一个已存在的文件的访问权限。


  1. #include <sys/stat.h>

  2. int chmod(const char *pathname, mode_t mode);

  3. int fchmode(int filedes, mode_t mode);

  4. 两者成功都返回0,失败返回-1。


chmod操作一个指定的文件,而fchmod操作一个已打开的文件。 


为了改变一个文件的权限位,进程的有效用户ID必须与文件的属主ID相同,或者进程必须有超级用户权限。 


mode有下表的常量的位或值指定:

<sys/stat.h>是chmod函数的模式常量
模式描述
S_ISUID执行时的set-user-ID
S_ISGID执行时的set-group-ID
S_ISVTXsaved-text(粘滞位)
S_IRWXU用户读、写、执行
S_IRUSR用户读
S_IWUSR用户写
S_IXUSR用户执行
S_IRWXG组读、写、执行
S_IRGRP组读
S_IWGRP组写
S_IXGRP组执行
S_IRWXO其他人读、写、执行
S_IROTH其他人读
S_IWOTH其他人写
S_IXOTH其他人执行

注意上表中有9个访问权限位与4.5节的表一样。我们加入了两个设置ID常量(S_ISUID和S_ISGID)、saved-text常量(S_ISVTX)、以及三个联合常量(S_IRWXU、S_IRWXG和S_IRWXO)。

saved-text位(S_ISVTX)不是POSIX.1的一部分。这作为SUS的一个XSI扩展被定义。我们会在下节讲述它的用途。 


看下面的代码:


  1. #include <sys/stat.h>

  2. int
  3. main(void)
  4. {
  5.         struct stat statbuf;

  6.         /* turn on set-group-ID and turn off group-execute */

  7.         if (stat("foo", &statbuf) < 0)
  8.                 exit(1);
  9.         if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
  10.                 exit(1);

  11.         /* set absolute mode to "rw-r--r--" */

  12.         if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
  13.                 exit(1);
  14.         exit(0);
  15. }

仍然用前面umask所使用的两个文件:
$ ls -l foo bar
-rw------- 1 tommy tommy 0 2012-02-22 11:37 bar
-rw-rw-rw- 1 tommy tommy 0 2012-02-22 11:37 foo
$ ./a.out 
$ ls -l foo bar
-rw-r--r-- 1 tommy tommy 0 2012-02-22 11:37 bar
-rw-rwSrw- 1 tommy tommy 0 2012-02-22 11:37 foo

在这个例子里,我们把文件bar的权限设置为一个绝对值,而不管它之前的权限位是什么。对于文件foo,我们设置它的权限位为一个相对值。为了完成这件 事,我们首先调用stat来得到当前的权限然后修改它们。我们显示地打开设置组ID位并关闭组执行位。注意ls命令把组执行位设置为“S”来表示设置组 ID位被设置,而组执行位没有被设置。(“s”表示两者都被设置。) 


在Solaris,ls命令显示一个“1”而非“S”来表示受委托的文件和记录锁在这个文件上开启了。这只能应用在普通文件上,但我们会在14.3节讨论更多细节。 


最后,注意ls命令列出的时间和日期并有在程序运行后改变。我们将在4.18节看到chmod函数只更新i-node上次改变的时间。默认情况下,ls -l会列出文件内容的最后修改时间。 


chmod函数在下面的条件下会自动清除两个权限位: 


1、一些系统,比如Solaris,当普通文件使用粘滞位时会赋予其特殊的意义。如果在这种系统上,我们尝试在普通文件上设置粘滞位(S_ISVTX)而 没有超级用户的权限的话,模式里的粘滞位会被自动关闭。(我们在下节讨论粘滞位。)这意味着只有超级用户可以为普通文件设置粘滞位。原因是为了避免恶意用 户设置粘滞位从而影响系统的性能。

在FreeBSD 5.2.1、Mac OS X 10.3和Solaris 9上,只有超级用户可以在普通文件上设置粘滞位。Linux 2.4.22没有这样的限制,因为在Linux上普通文件上的粘滞位没有任何意义。尽管FreeBSD和Mac OS X上当应用到普通文件时这个位也没有意义,但这些系统阻止除了用户外的任何人为普通文件设置这个位。 


2、一个新建文件的组ID可能并不包含创建该文件的进程。回想下4.6节,有可能新建文件的组ID是父目录的组ID。特别地,如果新建文件的组ID不等于 进程的有效组ID或进程的一个补充组ID,且进程没有超级用户权限,那么设置组ID位会被自动关闭。这避免了用户创建一个属于一个该用户不属于的组的设置 组ID文件,

FreeBSD 5.2.1、Linux 2.4.22、Mac OS X 10.3和Solaris 9加入另一个安全特性,试图避免一些保护位的误用。如果一个没有超级用户权限的进程写一个文件时,设置用户ID和设置组ID位会自动关闭。如果恶意用户找 到一个他们能写的设置组ID或设置用户ID文件,尽管他们能修改这个文件,但他们也失去了这个文件的特殊权限。


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值