用户权限究竟决定了什么

2020-03-11  本文已影响0人  醉看红尘这场梦

说起文件的权限,这绝对是个值的单独开个系列好好说的话题。不过,好在我们并不是在讲操作系统的内核,本着恰到好处的原则,这一节,我们和大家分享一些最重要的和权限有关的话题。

围绕着文件权限,系统中有两个对象和它有关系,分别是:账号和进程。其中,它决定了前者可以进行的操作;也决定了后者在执行时的角色。我们先从大家熟悉的部分开始。

决定账号可以进行的操作

无论是iOS还是Mac的终端,在任意一个目录中,当我们执行ls -l的时候,就可以看到类似这样的结果。其中,前4列是我们主要关心的内容:

image

第一列形如drwxr-xr-x的部分,就是这个文件的权限,它分成四部分,分别是:d rwx r-x r-x。这里,从左到右:第一位表示文件的类型:

在上面的截图中,这三种类型我们都展示出来了。

接下来的三组:rwx r-x r-x,表示系统中三类不同角色的人可以对这个文件进行的操作。这三类角色,分别是:

通常,我们会用U / G / O来表示这三类角色。注意,这里,我们使用了单词User和字母U表示属主,而没有使用Owner,这主要是为了和Other这类角色区分开,否则开头字母都是O就容易混淆了。并且,在C API中,用于描述文件属主权限的一些宏,例如:S_IRUSR / S_IWUSR / S_IXUSR也同样使用了User来表示属主,大家要注意这个事情。

了解完角色之后,我们再来看它们可以进行的操作。这部分很简单,分别是:

于是,把三类角色和三种不同的操作组合起来,这里我们一共有九种不同的情况,具体到上面的例子:

和目录有关的权限

接下来,我们着重说说目录权限的话题。rwx对普通文件来说很好理解,但是,对于一个目录来说,读、写和执行都意味着什么呢?我们知道,本质上,目录其实也是一个文件,只不过这个文件的内容,是目录中包含的文件和子目录而已。例如,假设我们有下面这样的目录结构:

image

如果我们用vi直接打开parent目录,就会看到下面的内容:

image

看到了吧,parent这个目录文件里记录了4个内容,分别是:上级目录、当前目录、subdir和subfile。于是,目录的读权限就很好理解了,它允许我们读取目录文件的内容,也就是说可以使用ls命令查看目录内容。

接下来,我们执行:chmod 300 parent把属主的读权限去掉,当我们再查看这个目录内容的时候,就会拒绝访问了。而这,这就是目录读权限的含义。

image

但是要注意的是,不能读取目录的文件列表,不等于不能访问其中的文件。如果你知道这个目录下的确切文件名,可以直接访问它。例如,我们执行vi parent/subfile就可以编辑文件了。这个操作的权限,是属于subfile自身控制的。

了解了目录的读权限之后,我们来看可执行权限。如果我们要真正访问一个文件,那么我们必须在这个文件的每一个路径上,具备可执行权限。例如,我们把parent的可执行权限去掉,就无法访问subfile了:

image

另外,对于我们刚才提到的文件的每一个路径,这里还要多说一句。所谓的每一个路径,只是基于路径字面值的,而不是实际的路径。

例如:如果我们要访问/home/bx11/a.conf,那么,就需要在//home/home/bx11这三个目录上都有可执行权限。但是,如果当前目录是/home/bx11,我们写成../a.conf来访问,那么只要在/home/bx11目录有可执行权限就好了,而不要求//home有可执行权限。

最后,我们来看写权限。所谓写,就是修改目录文件的内容。也就是说,只要有目录写权限,我们就可以添加或删除目录中的内容,而不需要我们对目录内的文件有任何权限。例如下面,尽管parent目录自身不可读,我们还是可以创建parent/subfile1。并且,去掉了subfile1的写权限之后,我们还是可以正常删掉它:

image

但要注意的是,实际上,在目录中添加删除文件,是要w搭配x才可以,没有可执行权限,我们是无法添加和删除文件的。

以上,就是我们在一开始提到的,文件权限对账号行为的影响。除此之外,它还决定了一个进程执行起来的角色。

决定进程在执行时的角色

当我们执行一个具有可执行权限的文件时,系统中就会多出来一个对应的进程。在终端里,我们执行ps au就会看到类似下面的结果:

image

在其中的USER列中可以看到,有的进程,就是我当前登录的账号puretears,有的进程则是root。而这个角色的约定,也和文件的权限相关。为了理解这个问题,我们要先普及一些概念。

Real User ID & Real Group ID

首先,是Real User ID和Real Group ID,这两个值决定了我们在系统中的真实身份。我们可以在/etc/passwd中的第三列和第四列内容中找到它们:

image

这个文件中记录了系统中所有账号的信息。可以看到,root的Real User ID和Real Group ID都是0,这个是固定的,而其它账号的这两个ID,则由系统在创建账号的时候生成。

Effective User ID & Effective Group ID

其次,是Effective User ID和Effective Group ID,这两个ID是进程的两个属性,决定了进程可以在系统中完成的操作(例如:是否可以调用某些API,访问某些系统资源等等)。通常情况下,这两个值和Real User ID以及Real Group ID是相等的。简单说,谁启动了进程,进程就代表谁工作

Set-UID-program & Set-GID-program

但在有些时候,进程启动之后,是可以不代表当前用户的,而是代表应用程序文件的属主以及用户组。其中,最经典的例子,就是我们经常使用的sudo。如果我们查看一下它的权限,就会发现是这样的:

image

看到了么?这次,文件属主的权限是r-s,这里的s也表示可执行,但是它表示这是一个Set-UID-program。也就是说,无论谁执行sudosudo进程的USER都是root,也就是一个特权进程。这也就是为什么我们可以通过sudo完成一些系统级别操作的原因。

看到这,你可能会觉得,这是一个有点儿危险的举动。为了避免权限被滥用,非特权账号只能修改属主是自己的文件的Set-User-ID属性,也就是说,让别人以我们自己的身份运行某个程序。而修改的方法,就是使用chmod命令,例如:

chmod u+s your_file

这样,your_file的x权限,就变成s了。

iOS中的两个账号

了解了这些和权限有关的知识之后,我们来看下iOS中的两个账号。一个是mobile,所有通过AppStore安装的程序,都是以这个身份运行的,因此它们都会受到iOS沙箱机制的约束。例如,iOS中的Podcasts:

image image

另一个,就是我们越狱之后使用的root了,之前我们通过Cydia安装的iFile,就是以root执行的,因此,它可以访问到iOS完整的文件系统:

image
上一篇 下一篇

猜你喜欢

热点阅读