Linux 文件权限
原文链接 https://hsfzxjy.github.io/2017-07-03-linux-file-permissions/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
概念
Linux 中的每一个文件都有其 所属用户 及 所属用户组,根据这两个属性可将文件访问者分为三类:所属用户自己、所属用户组中的用户 和 其他用户,我们可以针对不同的访问者设置不同的用户权限。
“访问”可分为三类:读、写 与 执行。我们可以用 ls -l
命令查看一个文件的权限:
$ touch test
$ ls -l test
-rw-rw-r-- 1 hsfzxjy hsfzxjy 0 Jul 3 23:44 test
首部的 -rw-rw-r--
即为文件的权限位。权限应该分为四部分来看:-/rw-/rw-/r--
。第一部分标志文件的类型,如 普通文件(-
)、目录(d
)、UNIX 套接字(s
)、符号链接(l
)、块设备(b
)等等。接下来的三个部分依次代表 所属用户、所属用户组、其他用户 的权限,每部分由三个标志位组成:读标志位、写标志位、执行标志位。
目录的权限
目录是一种特殊的文件,因此也拥有文件权限的概念,但权限的语义与普通文件稍有差异:
- 读:读取目录下文件列表,相关命令如
ls
- 写:创建、删除目录下的文件,相关命令如
touch
(当文件不存在时)、rm
等 - 执行:进入目录,相关命令如
cd
特殊权限
出于某些特殊目的,Linux 中存在两个特殊的权限位:粘滞位(t
)、Set Id(s
)。这两个权限可以 叠加 在执行权限位上,其中 Set Id 可以置于 所属用户 和 所属用户组 的权限组上,而 粘滞位 只能置于 其他用户 权限组上。当特殊权限被设置时,执行权限位上即会显示 s/t
(已有 x
权限)或 S/T
(尚未有 x
权限)。
粘滞位
粘滞位的作用是 防止他人误删自己的文件。当某个目录的其他用户权限组有 w
权限时,系统中的其他用户即可随意删除目录中的文件。而一旦叠加上 t
权限,只有文件的所有者方能删除文件。一个经典的例子是 /tmp
:
$ ls -l /
drwxrwxrwt 13 root root 12288 Jul 4 00:15 tmp/
Set Id
Linux 中的进程也有自己所属用户与用户组。一般而言,进程的所属用户即为其发起者,但这会引起一些麻烦。一个例子是 passwd
命令,该命令需要修改属于 root
用户的系统文件以保存密码,倘若进程所属用户即为所属者,此功能则无法实现。
Set Id 权限的作用是:在文件被执行时,将其有效用户/用户组设置为文件的用户/用户组,而不是当前执行者。下面是一个演示:
设当前用户为 hsfzxjy
,我们在 /tmp
下创建一个 test
文件,并删去其他用户的 r
权限:
$ cd /tmp
$ echo test text > test
$ chmod o-r test
$ ll test
-rw-rw---- 1 hsfzxjy hsfzxjy 0 Jul 4 00:28 test
由于 test
文件的所属用户是 hsfzxjy
,其他用户没有权限读取其中的内容:
$ sudo -u mysql cat test
cat: test: Permission denied
现在我们修改一下 cat
命令的权限,为了不影响系统文件,我们拷贝一份 cat
副本至当前目录:
$ cp /bin/cat .
$ chmod u+s cat
$ ll cat
-rwsr-xr-x 1 hsfzxjy hsfzxjy 52080 Jul 4 00:34 cat*
再以 mysql
的身份执行命令:
$ sudo -u mysql ./cat test
test text
可见 ./cat
在执行时所属用户是 hsfzxjy
。我们可以使用 ps
命令更清楚地看到这点:
$ sudo -u mysql cat
# 在另一个终端中
$ ps -eo euser,ruser,comm | grep cat
mysql mysql cat
# -----------
$ sudo -u mysql ./cat
# 在另一个终端中
$ ps -eo euser,ruser,comm | grep cat
hsfzxjy mysql cat