> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-yi-bu-fen-gai-lan/3.7.-yong-hu-yu-zu-biao-shi-fu.md).

# 3.7 用户与组标识符

UNIX 系统中有许多对象必须可标识，内核才能实施访问控制机制。其中最重要的对象是用户（user）。用户由一个 16 位数标识，称为用户标识符（UID）。UID 不由内核指派，而由外部的管理机构指派。UID 是记账、控制磁盘空间使用、访问文件系统以及限制各种特权内核操作（如重启正在运行的系统的请求）的基础。有一个称为超级用户（superuser，用户名通常为 `root`）的用户受到系统信任，获准做它请求的任何内核操作（有若干例外——连超级用户也不能写目录或给既有文件建硬链接）。超级用户的 UID 为零。

用户组织成组（group）。每个组指派一个 16 位数，称为组标识符（GID），大约也由指派 UID 的同一机构指派。GID 与 UID 一样用于文件系统提供的访问控制设施。UID 还用于判定信号可以发给哪些进程，并用于记账。GID 通常只用于确定文件系统的访问权限。

每个 UNIX 进程都关联一个用户。进程的状态包括一个 UID 和一组 GID。进程的文件系统访问特权完全由它的 UID 和 GID 决定（对从进程根目录开始的文件系统层次而言）。正常情况下，这些标识符在新进程创建时自动继承自父进程。只有超级用户获许更改进程的 UID 和 GID。仅此一套办法就实现了严格的特权分隔，确保超级用户之外谁也无法“取得”特权。

组可用于文件访问校验。每个文件有三套权限位，分别对用户、组和其他人规定读、写、执行权限。校验按顺序进行：

1. 若文件的 UID 与进程的 UID 相同，只用属主权限判定；组和其余权限不再检查。
2. 若 UID 不匹配，但文件的 GID 与进程的 GID 之一相同，则组权限必须允许所请求的操作；其余权限不再检查。
3. 只有进程的 UID 和 GID 都与文件的不匹配时，才检查对其他人的权限。这些权限必须允许所请求的操作。

进程的 UID 和 GID 继承自其父进程。用户登录时，登录程序（见 13.4 节）在执行 `exec` 系统调用运行用户的登录 shell 之前设好 UID 和 GID。从登录 shell 运行的所有进程因此都继承正确的标识符。UID 和 GID 维护在用户区中。

GID 实现为一个可区别的 GID 加一个补充 GID 数组。补充数组大小固定（4.3BSD 为 16），在系统编译时设定。分成两个数据结构是为了不必改动既有源代码；逻辑上它们被当作一组 GID 对待。

人们常常希望以受约束的方式授予用户某些特权。例如，想发邮件的用户必须能把邮件追加到别的用户的信箱。让目标信箱对所有用户可写，会让人（无论恶意还是无意）销毁其中的邮件。为解决这个问题，内核允许创建运行时被授予额外特权的程序。带额外组特权运行的程序称为设置组标识符（setgid）程序；以别的 UID 运行的程序称为设置用户标识符（setuid）程序 \[Ritchie, 1979]。setuid 程序执行时，进程的权限被扩充，纳入与该程序关联的 UID 的权限。程序的 UID 称为进程的有效（effective）UID，进程原来的 UID 称为实际（real）UID。类似地，执行 setgid 程序把程序 GID 的权限并入进程，并相应定义有效 GID 和实际 GID。

setuid 和 setgid 程序可用来提供对文件或服务的受控访问。例如，投递邮件的程序以超级用户的特权运行，能写系统中的任何文件。这样，用户不必被授予写别人信箱的特权，却仍能通过运行这个程序做到——它被小心翼翼地编写成只向信箱追加数据，不与其他邮件投递相撞，也不删除任何既有邮件。

setgid 能力的实现，是把文件的组加进执行了 setgid 程序的进程的补充组。之后权限校验与普通进程无异。由于多了一个组，setgid 程序通常能比不带此特权的用户进程访问更多文件。

setuid 能力的实现，是把进程的有效 UID 从用户的改为被执行程序的。与 setgid 一样，保护机制无须任何改动或对“程序在 setuid 下运行”的特别了解就会放行。由于一个进程同一时刻只能有一个 UID，运行 setuid 可能损失一些特权。安装新的有效 UID 时，先前的 UID 仍作为实际 UID 保留，但实际 UID 不用于任何校验检查。既要原来 UID 的特权又要 setuid 特权的进程，可以请求系统交换实际 UID 和有效 UID。保护机制用的是当前装作有效 UID 的那个标识符。

**主机标识符**

内核还为在网络环境中运行的机器定义了另外两个标识符：一个 32 位的主机标识符和一个指明主机名字的字符串，由内核维护。这两个值意在为网络中的每台机器唯一地定义。利用主机标识符，应用程序把对象的本地标识符与主机标识符拼接，就能轻易造出全网唯一的对象标识符（对象如进程、文件和用户）。生成全网唯一标识符的能力在构建分布式应用时很有用 \[Gifford, 1981]。机器的主机标识符和主机名定义在内核之外。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-yi-bu-fen-gai-lan/3.7.-yong-hu-yu-zu-biao-shi-fu.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
