4.3. 权限
上一页 | 第 4 章 UNIX 基础 | 下一页

## 4.3. 权限

FreeBSD，是 BSD UNIX® 的延续， 并基于几个关键的 UNIX® 观念。 从一开始就多处提到 FreeBSD 是一个多用户的操作系统， 它能分别处理几个同时工作的用户所分配的毫无关联任务。 并负责为每位用户的硬件设备、 外设、 内存和 CPU 处理时间作出合理安排。

因为系统有能力支持多用户， 在每一方面系统都会作出谁能读、 写和执行的资源权力限制。 这点权限以三个八位元的方式储存着， 一个是表示文件所属者， 一个是表示文件所属群组， 一个是表示其他人。 这些数字以下列方式表示：

数值 | 权限 | 目录列表
--- | --- | ---
0 | 不能读，不能写，不能执行 | `---`
1 | 不能读，不能写，可执行 | `--x`
2 | 不能读，可写，不能执行 | `-w-`
3 | 不能读，可写，可执行 | `-wx`
4 | 可读，不能写，不能执行 | `r--`
5 | 可读，不能写，可执行 | `r-x`
6 | 可读，可写，不能执行 | `rw-`
7 | 可读，可写，可执行 | `rwx`

使用命令的 `-l` (ls(1)) 参数可以显示出文件的所属者、 所属组和其他人等属性。 请看以下的例子：

`%` `ls -l` total 530 -rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile -rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile -rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt ...

使用 `ls -l` 在每行的开始出现了：

-rw-r--r--

从左边起的第一个字，告诉我们这个文件是一怎样的文件: 普通文件?目录?特殊设备?socket?或是设备文件? 在这个例子， `-` 表示一个普通文件。 接下来三个字是 `rw-` 是文件拥有者的权限。 再接下来的三个字是 `r--` 是文件所属群组的权限。 最後三个字是 `r--` 是其他人的权限。 以这一个文件为例，他的权限设定是拥有者可以读写这个文件、群组可以读取、 其他使用者也能读取这个文件。 根据上面的表格， 用数字表示这个文件其三部分的权限应该是 `644`。

这样很好，但系统怎样对设备进行权限控制的? 事实上 FreeBSD 将大部份硬件设备当作一个文件看待， 用程序能打开、读取、写入数据就如其他的文件一样。 而设备文件放在 `/dev` 目录。

目录也视为一种文件，也有读取、写入、执行的权限。 但目录的执行权限意义并不与普通文件相同， 实际上执行权限是进入权限。 当一个目录是被标示可以执行的时， 表示可以进入它， 或者换言之， 利用 “cd” (改变当前目录) 进入它。 此外， 这也表示有权进入目录的用户， 可以访问其下的已知名字的文件 (当然目录下的文件也受到访问限制)。

详细方面，想读取一个目录的列表就必须设为可读权限， 同时想删除一个已知的文件，就必须把目录下这个文件设为可写 和 执行权限。

还有更多权限设定， 但是他们大多用在特殊状况下如一个setuid的执行文件和粘贴性目录， 如果想要得知有关文件权限和如何设定的更多资讯，请看手册chmod(1)。

### 4.3.1. 权限的符号化表示

Contributed by Tom Rhodes.

权限符号，某些时候就是指符号表达式， 使用八进制的字符给目录或文件分配权限。 权限符号的使用语法是 (谁) (作用) (权限)。 看看下列数值的在那些地方所起什么样的作用:

选项 | 字母 | 介绍
--- | --- | ---
(谁) | u | 用户
(谁) | g | 所属群体
(谁) | o | 其他人
(谁) | a | 所有人 (“全部”)
(作用) | + | 增加权限
(作用) | - | 减少权限
(作用) | = | 确定权限
(权限) | r | 可读
(权限) | w | 可写
(权限) | x | 执行
(权限) | t | 粘贴位
(权限) | s | 设置 UID 或 GID

这些数值 chmod(1) 以习惯标定的。 举个例子，用以下命令阻止其他人访问 `FILE`文件:

`%` `chmod go= FILE`

如果需要对文件一次进行多项变动， 则可用逗号分开， 在下面的例子中， 将去掉 `FILE` 文件的群体和 “全体其他用户” 可写权限， 并为所有人增加可执行权限：

`%` `chmod go-w,a+x `FILE``

### 4.3.2. FreeBSD 文件标志

Contributed by Tom Rhodes.

在前面所介绍的文件权限的基础之上， FreeBSD 还支持使用 “文件标志”。 这些标志为文件提供了进一步的安全控制机制， 但这些控制并不适用于目录。

这些文件标志提供了针对文件的进一步控制， 帮助确保即使是 `root` 用户也无法删除或修改文件。

文件标志可以通过使用 chflags(1) 工具来修改， 其用户界面很简单。 例如， 要在文件 `file1` 上应用系统禁删标志， 应使用下述命令：

`#` `chflags sunlink `file1``

要禁用系统禁删标志， 只需在前述命令中的 `sunlink` 标志前加 “no”。 例如：

`#` `chflags nosunlink `file1``

要显示文件上的标志， 应使用命令 ls(1) 的 `-lo` 参数：

`#` `ls -lo `file1``

输出结果应类似于：

-rw-r--r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1

许多标志只可以由 `root` 用户来增加， 而另一些， 则可以由文件的所有者来增加。 建议管理员仔细阅读 chflags(1) 和 chflags(2) 联机手册， 以对其加深理解。

### 4.3.3. setuid、 setgid 和 sticky 权限

原作 Tom Rhodes.

除了前面已经讨论过的那些权限之外， 还有三个管理员应该知道的权限配置。 它们是 `setuid`、 `setgid` 和 `sticky`。

这些配置对于一些 UNIX® 操作而言很重要， 因为它们能提供一些一般情况下不会授予普通用户的功能。 为了便于理解， 我们首先介绍真实用户 ID (real user ID) 和生效用户 ID (effective user ID)。

真实用户 ID 是拥有或启动进程的用户 UID。 生效 UID 是进程以其身份运行的用户 ID。 举例来说， passwd(1) 工具通常是以发起修改密码的用户身份启动， 也就是说其进程的真实用户 ID 是那个用户的 ID； 但是， 由于需要修改密码数据库， 它会以 `root` 用户作为生效用户 ID 的身份运行。 这样， 普通的非特权用户就可以修改口令， 而不是看到 Permission Denied 错误了。

### 注意:

mount(8) 的 `nosuid` 选项可以令系统在不给出任何错误提示的情况下不执行这些程序。 另一方面， 这个选项并不是万无一失的， 正如 mount(8) 联机手册所提到的那样， 如果系统中安装了绕过 `nosuid` 的封装程序， 那么这种保护就可以被绕过了。

setuid 权限可以通过在普通权限前面加上一个数字四 (4) 来设置， 如下面的例子所示：

`#` `chmod 4755 suidexample.sh`

这样一来， ``suidexample.sh`` 的权限应该如下面这样：

-rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh

您会注意到， 在原先的属主执行权限的位置变成了 `s`。 这样， 需要提升特权的可执行文件， 例如 `passwd` 就可以正常运行了。

可以打开两个终端来观察这一情形。 在其中一个终端里面， 以普通用户身份启动 `passwd` 进程。 在它等待输入新口令时， 在另一个终端中查看进程表中关于 `passwd` 命令的信息。

在终端 A 中：

Changing local password for trhodes Old Password:

在终端 B 中：

`#` `ps aux | grep passwd`
trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd

正如前面所说的那样， `passwd` 是以普通用户的身份启动的， 但其生效 UID 是 `root`。

与此对应， `setgid` 权限的作用， 与 `setuid` 权限类似， 只是当应用程序配合这一设定运行时， 它会被授予拥有文件的那个组的权限。

如果需要在文件上配置 `setgid` 权限， 可以在权限数值前面增加数字二 (2) 来运行 `chmod` 命令， 如下面的例子所示：

`#` `chmod 2755 sgidexample.sh`

可以用与前面类似的方法来检视新设定的生效情况， 在组权限的地方的 `s` 表示这一配置已经生效：

-rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh

### 注意:

在这些例子中， 尽管 shell 脚本也属于可执行文件的一种， 但它们不会以您配置的 EUID 或生效用户 ID 的身份运行。 这是因为 shell 脚本可能无法直接呼叫 setuid(2) 调用。

我们已经讨论了两个特殊权限位 (`setuid` 和 `setgid` 权限位)， 它们让用户在使用程序时能够用到更高的权限， 有时这会削弱系统的安全性。 除了这两个之外， 还有第三个特殊权限位： `sticky bit`， 它能够增强安全性。

当在目录上设置了 `sticky bit` 之后， 其下的文件就只能由文件的所有者删除了。 这个权限设置能够防止用户删除类似 `/tmp` 这样的公共目录中不属于他们的文件。 要应用这种权限， 可以在权限设置前面加上数字一 (1)。 例如：

`#` `chmod 1777 /tmp`

现在， 可以用 `ls` 命令来查看效果：

`#` `ls -al / | grep tmp`
drwxrwxrwt 10 root wheel 512 Aug 31 01:49 tmp

这里的结尾的 `t` 表示了 `sticky bit` 权限。

上一页 | 上一级 | 下一页
4.2. 虚拟控制台和终端 | 起始页 | 4.4. 目录架构

本文档和其它文档可从这里下载： ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读 文档，如不能解决再联系 <questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.