FreeBSD 使用手册
上一页 | 第3章 　UNIX 基础 | 下一页

# 3.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)。

## 3.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

## 3.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) 联机手册， 以对其加深理解。

## 3.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` 权限。

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

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

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