`

文件权限 ID 修改函数介绍

阅读更多
    在前面“设置用户 ID 和设置组 ID”一节中,我们介绍了与每个文件相关的 9 个访问权限位,在此基础上我们可以说明与每个进程相关联的文件模式创建屏蔽字。
    umask 函数为进程设置文件模式创建屏蔽字,并返回之前的值。
#include <sys/stat.h>

mode_t umask(mode_t cmask);       // cmask 是 9 个文件访问权限位常量的按位或
              /* 返回值:之前的文件模式创建屏蔽字 */

    在进程创建一个新文件或新目录时,就一定会使用文件模式创建屏蔽字。在文件模式创建屏蔽字中为 1 的位,在文件 mode 中的相应位就会被关闭。
    下例程序创建了两个文件,创建第一个时,umask 值为 0,创建第二个时,umask 值禁止了所有组和其他用户的访问权限。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.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\n");
		exit(2);
	}
	umask(S_IRGRP |S_IWGRP |S_IROTH |S_IWOTH);
	if(creat("bar", RWRWRW) < 0){
		printf("creat error for bar\n");
		exit(2);
	}
	exit(0);
}

    执行结果如下(从中可看出更改子进程的文件模式创建屏蔽字不会影响父进程(常常为 shell )的屏蔽字):
$ umask                 # 先查看当前文件模式创建屏蔽字
0022
$ ./umaskDemo.out 
$ ls -l foo bar
-rw-------. 1 lei root 0 7月   2 23:55 bar
-rw-rw-rw-. 1 lei root 0 7月   2 23:55 foo
$ umask                 # 观察文件模式创建屏蔽字是否更改
0022

    尽管在登录时,shell 的启动文件会自行设置一次 umask 值,但当编写创建新文件的程序时,如果想确保指定的访问权限位已经激活,那么最好在进程运行时修改 umask 值,以免进程运行时有效的 umask 值关闭该权限位。

    更改 umask 值会影响所有随后的文件,如果想更改特定文件的访问权限,可使用 chmod 函数族。
#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, node_t mode, int flag);
                       /* 返回值:若成功,都返回 0;否则,都返回 -1 */

    chmod 函数在制定的文件上进行操作,而 fchmod 函数则对已打开的文件进行操作。fchmodat 函数与 chmod 函数在这两种情况下是相同的:一种是 pathname 参数为绝对路径,另一种是 fd 参数取值为 AT_FDCWD 而 pathname 为相对路径。否则,fchmodat 计算相对于打开目录(由 fd 指向)的 pathname。flag 参数可以改变 fchmodat 的行为,当设置了 AT_SYMLINK_NOFOLLOW 标志时,fchmodat 并不会跟随符号链接。
    要改变一个文件的权限位,进程的有效用户 ID 必须等于文件的所有者 ID,或者该进程必须具有超级用户权限。
    参数 mode 是下表中的常量(均位于头文件 <sys/stat.h> 中)的按位或:


    下面是使用 chmod 函数改变 umask 示例中生成的 foo 和 bar 文件的示例。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(void){
	struct stat statbuf;

	if(stat("foo", &statbuf) < 0){
		printf("stat error for foo\n");
		exit(2);
	}
	// turn on set-group-ID and turn off group-execute.
	if(chmod("foo",(statbuf.st_mode & ~S_IXGRP) |S_ISGID) < 0){
		printf("chmod error for foo\n");
		exit(2);
	}

	// set absolute mode to "rw-r--r--"
	if(chmod("bar", S_IRUSR |S_IWUSR |S_IRGRP |S_IROTH) < 0){
		printf("chmod error for bar\n");
		exit(2);
	}
	exit(0);
}

    执行结果:
$ ls -l foo bar        # 开始的文件权限位
-rw-------. 1 lei root 0 7月   3 23:39 bar
-rw-rw-rw-. 1 lei root 0 7月   3 23:39 foo
 
$ ./chmodDemo.out 
 
$ ls -l foo bar        # 改变后的文件权限位
-rw-r--r--. 1 lei root 0 7月   3 23:39 bar
-rw-rwSrw-. 1 lei root 0 7月   3 23:39 foo    # Solaris 中显示的是“l”而非“S”

    这里可看出,ls 命令列出的时间和日期并没有改变。这是因为 chmod 更新的只是 i 节点最近一次被更改的时间,而“ls -l”命令默认列出的是最后修改文件内容的时间。
    chmod 函数在下列条件下自动清除两个权限位。
    1、Solaris 等系统对用于普通文件的粘着位赋予了特殊含义(此时如果任何执行位都没有设置,那么操作系统就不会缓存文件内容),在这些系统上如果试图设置普通文件的粘着位(S_ISVTX),而又没有超级用户权限,那么 mode 中的粘着位会被自动关闭。
    2、新创建文件的组 ID 可能不是调用进程所属的组。特别地,当新文件的组 ID 不等于进程的有效组 ID 或者进程附属组 ID 中的一个,而且进程又没有超级用户权限,那么设置组 ID 位就被自动关闭。这就防止了用户创建一个设置组 ID 文件,而该文件是由并非该用户所属的组拥有的。
  
    下面再继续介绍用来更改文件的用户 ID 和组 ID 的 chown 函数族。
#include <unistd.h>

int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int fchownat(int fd, const char *pathname, uid_t owner, gid_t group, int flag);
int lchown(const char *pathname, uid_t, gid_t group);
                     /* 返回值:若成功,都返回 0;否则,都返回 -1 */

    其中,如果两个参数 owner 或 group 中的任意一个为 -1,则对应的 ID 不变。
    fchown 函数改变 fd 参数指向的打开文件的所有者,既然它在一个已打开的文件上操作,就不能用于改变符号链接的所有者。
    fchownat 函数与 chown 或者 lchown 函数在下面两种情况下是相同的:一种是 pathname 为绝对路径,另一种是 fd 参数取值为 AT_FDCWD 而 pathname 为相对路径。这两种情况下,如果 flag 设置了 AT_SYMLINK_NOFOLLOW 标志,fchownat 与 lchown 行为相同,如果 flag 清除了 AT_SYMLINK_NOFOLLOW 标志,则 fchownat 与 chown 行为相同。如果 fd 参数设置为打开目录的文件描述符,并且 pathname 是相对路径,fchownat 就计算相对于打开目录的 pathname。
    若 _POSIX_CHOWN_RESTRICTED 常量(它可选地定义在头文件 <unistd.h> 中,可以使用 pathconf 或 fpathconf 函数查询)对指定的文件生效,则 POSIX.1 规定:
    1、只有超级用户进程能更改该文件的用户 ID,以防用户改变其文件的所有者来摆脱磁盘空间限额的限制。
    2、如果进程拥有此文件(即其有效用户 ID 等于该文件的用户 ID),参数 owner 等于 -1 或文件的用户 ID,并且 group 参数等于进程的有效组 ID 或进程的附属组 ID 之一,则一个非超级用户进程可以更改该文件的组 ID。
    这意味着,当 _POSIX_CHOWN_RESTRICTED 有效时,不能更改其他用户文件的用户 ID,你可以更改你所拥有的文件的组 ID,但只能改到所属的组。如果这些函数由非超级用户进程调用,则在成功返回时,该文件的设置用户 ID 位和设置组 ID 位都将被清除。
  • 大小: 55.8 KB
分享到:
评论

相关推荐

    LINUX下文件操作函数的介绍.

    权限标志主要用于`creat()`或`open()`函数的`mode`参数中,用于指定文件权限。常见的权限标志包括但不限于: - `S_IRUSR`:用户可读。 - `S_IWUSR`:用户可写。 - `S_IXUSR`:用户可执行。 - `S_IRWXU`:用户可读、...

    perl获取文件修改时间

    在Perl中,`stat`函数用于获取文件的状态信息,包括但不限于文件大小、创建时间、最后访问时间和最后修改时间。这些信息通常存储在一个包含14个元素的数组中,每个元素对应不同的文件属性。 - **数组元素解释**: ...

    autoit3常见函数

    下面将详细介绍标题“AutoIt3常见函数”所涵盖的一些关键函数及其功能,这些函数是AutoIt编程中的常用工具,帮助开发者实现各种自动化操作。 ### 1. 环境变量操作 - `EnvUpdate()`:更新环境变量,使脚本中设置的...

    linux目录操作函数汇总 遍历,改变路径等

    mode参数是由多种权限组合而成,包括设置用户ID(S_ISUID)、设置组ID(S_ISGID)、粘滞位(S_ISVTX)以及普通权限标志(S_IRUSR、S_IWUSR、S_IXUSR等),它们共同决定了文件或目录的读、写、执行权限。 3. access...

    Python 查看文件的读写权限方法

    ##### 更改文件权限的模式 ```python os.chmod(path, mode) ``` - **功能**:更改文件或目录的权限。 - **参数**: - `path`:文件或目录的路径。 - `mode`:新的权限模式,通常由`stat`模块中的常量组合而成。 ...

    详细对比C语言中的chmod()函数和fchmod()函数

    C语言chmod()函数:修改文件权限 头文件: #include &lt;sys&gt; #include 定义函数: int chmod(const char * path, mode_t mode); 函数说明:chmod()会依参数mode 权限来更改参数path 指定文件的权限。 参数 mode ...

    C语言中获取文件状态的相关函数小结

    今天,我们将对stat()函数、fstat()函数和lstat()函数进行详细的介绍,了解它们的使用方法和参数说明。 一、stat()函数 stat()函数用来获取文件状态,函数原型为: int stat(const char *file_name, struct stat *...

    asp权限控制,asp+access,含数据库文件

    此压缩包文件包含的内容显然与ASP用户权限设置相关,特别是结合了Access数据库进行用户管理。 ASP中的权限控制主要涉及到以下几个方面: 1. **身份验证**:这是权限控制的第一步,通常通过登录表单实现。用户输入...

    Rockey4ND修改密码和ID源代码.zip

    其次,ID修改部分可能涉及到: 1. **ID生成**:源代码可能包含了生成和验证唯一用户ID的算法,这通常需要保证ID的全局唯一性,避免冲突。 2. **数据库操作**:修改用户ID可能涉及到与数据库交互的SQL语句,如更新...

    linux stat函数讲解(整理)

    它可以用来检查文件是否存在、判断文件类型、获取文件权限、确定文件大小等,广泛应用于各种系统级和应用级程序中。通过`stat`函数,程序员能够以安全和可靠的方式处理文件,避免因文件状态不符合预期而导致的错误。

    linux stata函数讲解

    下面我们将深入讲解`stat`函数的使用方法、结构体`struct stat`的成员以及相关的文件权限标志。 首先,`stat`函数的声明位于`&lt;sys/stat.h&gt;`和`&lt;unistd.h&gt;`头文件中。其函数原型如下: ```c int stat(const char *...

    stat函数讲解

    #### 一、函数介绍 `stat`函数是Linux系统中用于获取文件状态信息的一个重要接口。它能够提供关于文件的各种详细信息,包括但不限于文件的大小、创建时间、修改时间以及文件的权限等。对于进行文件管理、权限控制及...

    修改硬盘ID

    `hookDiskID.dll`是一个动态链接库文件,包含可重用的代码和资源,而`hookDiskID.exe`可能是执行文件,调用`hookDiskID.dll`中的函数实现硬盘ID的修改功能。使用这类工具时,需要确保来源可靠,避免安装含有病毒或...

    易语言修改进程自身ID失败

    对于"易语言修改进程自身ID失败源码",你可以查看提供的压缩包文件中的源代码,分析失败的原因。可能的问题包括但不限于:API调用语法错误、权限不足、指针操作不当等。通过调试和查阅相关文档,通常可以找出问题...

    VBA修改MP3的属性信息(包括专辑名、作家等)

    首先,我们需要一个特殊的DLL库,即CDDBControl.dll,这个文件包含了一些用于处理MP3文件元数据的函数和方法。通常,DLL(动态链接库)文件是一些可重复使用的代码集合,可以在多个程序中调用。在本例中,我们将...

    SAP ABAP函数集锦

    获取终端ID,常用于多用户环境下的身份识别和权限控制。 ### 15. DATE_CONVERT_TO_FACTORYDATE 日期格式转换函数,将系统日期转换为工厂标准日期格式,适用于跨系统数据交换。 ### 16. MESSAGE_TEXT_BUILD 构建...

    unix环境高级编程--第章 文件和目录.doc.doc

    本章将详细介绍文件和目录的属性、stat 函数、fstat 函数、lstat 函数等知识点,并且对目录进行操作的函数进行详细的解释。 文件类型 在 Unix 系统中,文件可以分为多种类型,包括普通文件、目录文件、符号连接...

    【2018hit计算机系统安全】实验一:文件权限管理及搭建虚拟环境

    在计算机系统安全领域,理解和管理文件权限以及构建安全的虚拟环境是至关重要的。本实验主要涵盖了两个核心主题:文件权限管理和虚拟环境的搭建,特别是针对Linux系统的实践。 首先,我们关注文件和目录的权限设置...

    C语言实现Linux文件系统模拟文档(内有程序)

    10. **更改文件权限**:调整文件的访问权限。 #### 七、关键数据结构和函数 - **数据结构**:如链表、数组等用于存储文件和目录的信息。 - **函数**:实现文件和目录的创建、删除、重命名等功能的函数。 #### 八、...

    读SAM文件三个方法(下载)

    本文介绍了三种读取SAM文件或其他被其他进程占用的文件的方法:通过内核API、利用命名管道以及共享内存机制。每种方法都有其独特的优势和应用场景。对于开发人员来说,了解这些技术不仅有助于解决实际开发中的难题,...

Global site tag (gtag.js) - Google Analytics