(2.8)文件和目录操作——Linux文件权限管理

时间:2022-03-16 00:52:36


文章目录

  • ​​1.用户和组ID​​
  • ​​2.文件权限:读,写,执行​​
  • ​​3.目录权限:读,写,执行​​
  • ​​4.文件权限检查​​
  • ​​5.新文件和新目录的所有权​​
  • ​​6.access函数​​
  • ​​7.chmod、 fchmod函数​​
  • ​​8.更改文件所有者​​
  • ​​9.link函数​​
  • ​​10.unlink和remove函数​​
  • ​​11.更改文件和目录​​
  • ​​12.文件的时间​​
  • ​​13.utime函数​​
  • ​​14.mkdir函数​​
  • ​​15.rmdir函数​​

1.用户和组ID

  • Linux系统通过进程的有效用户ID和有效用户组ID来决定进程对系统资源的访问权限
  • 与一个进程相关联的用户ID和用户组ID有如下几种
  • 通常情况下, 有效用户ID等于实际用户ID, 有效组ID等于实际组ID;
  • 可执行文件的权限中有一个特殊标志, 定义为“当执行此文件时,将进程的有效用户ID设置为文件的所有者” , 与此类似, 组ID也有类似的情况。 这两个标志位称为: “设置用户ID” 和 “ 设 置 组 ID” , 这 两 位 都 包 含 在 stat 信 息 中 的 st_mode 中 , 可 用S_ISUID,S_ISGID测试。
    S_ISUID:有效用户id等于文件所有者的uiD,而不是实际用户ID
    S_ISGID:有效用户组id等于文件所有者的gid,而不是用户组gid

2.文件权限:读,写,执行

  • 对于一个文件的读权限决定了我们是否能够打开该文件进行读操作
  • 对一个文件的写权限决定了我们是否能够打开该文件进行写操作
  • 为了在open函数中对一个文件指定O_TRUNC标志(会将文件内容的长度清0,要与O_READ结合使用), 必须对该文件具有写权限
  • 执行某个可执行文件, 都必须对该文件具有执行权限

3.目录权限:读,写,执行

  • 目录文件的执行权限也表示可以进入该目录
  • 通过文件名打开一个任意类型的文件时, 对该文件路径名中包含的每一个目录都应具有执行权限
  • 为了在一个目录中创建一个新文件, 必须对该目录具有写权限和执行权限
  • 为了删除一个文件, 必须对包含该文件的目录具有写权限和执行权限,对该文件本身则不需要有读、 写权限

4.文件权限检查

  • 进程访问文件时, 内核就进行文件权限检查。 这种检查涉及到文件的所有者、 文件的所有者所在组、 进程有效用户、 进程的有效组及进程的附加组。
    两个所有者是文件的性质,而有效用户与有效组是进程的性质
  • 当进程对某个文件进行操作时, 内核按顺序执行下列4步来检查文件权限
    1、 若进程的有效用户为root(ID等于0) , 则允许任何操作;
    2、 若进程的有效用户等于文件的所有者(ID相同) (即该进程拥有文件) ,按照文件所有者具有的权限判定操作是否合法
    3、 若进程的有效组或进程的附加组之一等于文件所有者所在组,按照文件所有者所在组具有的权限判定操作是否合法
    4、 按照其他用户具有权限判定操作是否合法
  • 一般情况下
    ➢ 若进程有效用户拥有此文件, 则按用户权限批准或拒绝该进程对文件的操作;
    ➢ 若进程有效用户并不拥有该文件, 但进程有效用户属于某个适当的组, 则按组权限批准或拒绝该进程对文件的操作
    ➢ 若进程有效用户并不拥有该文件, 也不属于某个适当的组, 则按照其他其他用户权限批准或拒绝该进程对文件的操作

5.新文件和新目录的所有权

  • 新文件的所有者设置为进程的有效用户
  • 新文件所有者所在的组, POSIX允许选择下列之一:
    ➢ 新文件所有者所在的组可以是进程的有效组
    ➢ 新文件所有者所在的组可以是它所在目录的组
  • 新文件所有者所在的组取决于它所在目录的设置组ID位是否设置, 若设置, 则为目录组, 否则则为进程有效组
  • BSD总是用目录组作为新文件所有者所在组

6.access函数

函数功能: 按照前述文件权限检查的4个步骤测试存取文件是否具有相应权限
函数原型: int access( const char *pathname, int mode)

pathname:所要操作的文件路径名
  • mode可以取

7.chmod、 fchmod函数

函数原型
int chmod(const char * pathname, mode_t mode);
int fchmod( int fd, mode_t mode);

函数用途: 改变指定文件的权限位。

函数说明:
chmod要求给出的是文件或目录所在的位置, 而fchmod主要针对的是文件, 要求调用是相应的文件描述符。
修改时, 进程的有效用户ID必须等于文件的所有者ID, 或是root运行的此进程
  • 文件存取许可权mode
  • (2.8)文件和目录操作——Linux文件权限管理

  • Chmode函数出错信息
  • (2.8)文件和目录操作——Linux文件权限管理

  • fchmode函数出错信息
  • (2.8)文件和目录操作——Linux文件权限管理

8.更改文件所有者

函数原型
➢ int chown( const char *pathname, uid_t owner, gid_t group);
➢ int fchown( int filedes, uid_t owner, gid_t group);
➢ int lchown( const char *pathname, uid_t owner, gid_t group);

函数用途: 更改文件的用户ID和组ID。 成功返回0, 若出错则返回-1

函数说明:
➢ 如果两个参数owner或group中的任意一个是-1, 则不改变文件所有者或文件所属用户组
➢ lchown是改变符号链接本身的所有者, 而不是该符号链接所指向的文件
➢ 基于BSD的系统中, 只有超级用户才能更改一个文件的所有者
➢ 非超级用户进程调用,则在成功返回时, 该文件的设置用户ID位和设置组ID位会被清除

9.link函数

函数原型: int link ( const char *pathname, const char *newpath);

函数用途: 任何一个文件可以有多个目录项指向其索引节点, 创建一个指向现有文件的新目录项

函数说明
➢ 此函数创建一个新目录项newpath, 它指向pathname指向的文件。 如果newpath已经存在, 则返回出错(可以使用新名字
对文件进行操作,这些名字都指向同一个文件,都具有相同的权限和拥有者)
➢ 创建新目录项以及增加连接计数是一个原子操作(不会被OS打断)。
➢ 大多数的系统规定, 只有超级用户可以创建指向一个目录的新连接, 目的是在文件系统中形成循环。

10.unlink和remove函数

函数原型及头文件
➢ int unlink ( const char *pathname); (unistd.h)
➢ int remove( const char *pathname); ( stdio.h)

函数用途:
➢ unlink删除目录项, 并将由pathname所引用文件的链接计数减1, 清空这个文件使用的可用的系统资源(若pathname是一个符号链接,
他只会删除符号链接,而不会删除符号链接所引用的文件)
➢ remove删除一个目录中的一个或多个文件或目录, 也可以将某个目录及其下的所有文件及子目录均删除

共同点及差异
➢ unlink是系统调用, 而remove是库函数
➢ remove的参数为普通文件时等价于unlink

11.更改文件和目录

  • 空目录指的是:只有.和…这两项
函数原型: int rename ( const char * oldname, const char * newname);

函数用途: 更名文件或目录

函数说明
➢ 如果oldname是一个文件而不是目录, 那么为该文件更名
➢ 如果oldname是一个目录, 那么为该目录更名
➢ 如果oldname和newname引用同一文件, 则函数不做任何更改而成功返回
➢ 应对包含两个文件的目录具有写和执行许可权

12.文件的时间

  • 每个文件有三个时间字段
  • 对文件进行一次读操作, 它的访问时间就会改变
  • 修改时间是文件内容最后一次被修改的时间
  • 状态时间是该文件索引节点最后一次被修改的时间, 影响索引节点的操作:
    ➢ 更改文件访问权限
    ➢ 更改文件用户ID
    ➢ 更改文件链接数

13.utime函数

函数原型: int utime( const char *pathname, const struct utimbuf *times);

函数用途: 设置存取和修改文件的时间

函数说明: 此函数的操作以及执行它所要求的优先权取决于time参数是否是NULL
➢ 如果times是一个NULL, 则存取时间和修改时间两者都设置为当前时间, 但必须满足下面二者之一: (1)
进程的有效用户ID必须等于该文件的所有者(2) 进程对该文件有写许可权
➢ 如果times是非空指针, 则存取时间和修改时间被设置为times所指向的时间, 此时进程的有效用户ID必须等
于该文件的所有者ID, 或者进程必须是超级用户的进程。

14.mkdir函数

函数原型: int mkdir(const char *pathname, mode_t mode);

函数用途: 创建一个新的空目录, 其中的. 和 .. 两个目录项由系统自动创建。

函数说明:
➢ 如果在目录名的前面没有加任何路径名, 则在当前目录下创建由pathname指定的目录
➢ 如果给出了一个已经存在的路径, 将会在该目录下创建一个指定的目录
➢ 在创建目录时, 应保证新建的目录与它所在目录下的文件没有重名
➢ 在创建文件时, 不要把所有的文件都存放在主目录中, 可以创建子目录, 来更有效地组织文件

15.rmdir函数

函数原型: int rmdir( const char *pathname);

函数用途: 删除一个空目录

函数说明:
➢ 如果此调用使目录的连接计数成为0, 并且也没有其他进程打开此目录, 则释放由此目录占用的空间
➢ 如果连接计数为0, 但有进程打开了此目录, 则在此函数返回前, 删除. 和 .. 项。 在此目录中不能再创建新文
件。 但是在最后一个进程关闭之前并不释放此目录