在 Unix-like 操作系统中,每个用户都被一个称为用户识别码的值所识别,通常简称为用户 ID(UID)。 UID,不仅与用户的权限有关,还与组识别码(GID)及其他存取控制标准共同决定了用户可以访问哪些系统资源。这一切都在一个关键的文件中进行映射,该文件将文本用户名映射到 UID。
UID 被存储在 Unix 文件系统的 inode、中运行的进程以及一些过时的网络信息服务中。
在 POSIX 相容环境中,使用 shell 命令 id 可以获取当前用户的 UID,以及用户名、主要用户组和 GID 等更多信息。
POSIX 标准在进程描述符表中引入了三个不同的 UID 字段,以便特权进程在动态增加权限的同时可以承担不同的角色。
进程的有效 UID(euid)用于大多数权限检查,也是该进程创建的文件的所有者。相应地,有效 GID(egid)也会影响存取控制,并可能影响文件的创建,具体取决于内核实现的语义。在 BSD Unix 语义中,新创建文件的群组所有权无条件地从所创建的目录的群组所有权继承。
Linux 还有一个文件系统用户 ID(fsuid),它显式用于文件系统的存取控制。这个 ID 在没有特别设定的情况下,通常与 euid 相等。只有在 ruid、suid 或 euid 为 root 时,fsuid 才可以是 root 的用户 ID。每当 euid 更改时,这种变化会被传播到 fsuid 上。
保存的用户ID 用于当一个运行着需要提升权限的程式需要暂时执行一些不需要特权的工作时;它将特权值(通常是0)变更为一些不需要特权的值,将特权值存储在suid 中,以后程序可以将其euid 设置回suid 中存储的值,从而恢复提升的权限。
真实 UID(ruid)和真实 GID(rgid)识别进程的真正拥有者,并影响发送信号的权限。没有超级用户权限的进程只可在发送者的 ruid 或 euid 与接收者的 ruid 或 suid 匹配时发送信号。
POSIX 要求 UID 为整数类型,大多数 Unix-like 操作系统将 UID 表示为无符号整数。 UID 值的大小在不同的系统之间有所不同,某些 UNIX 系统使用 15 位值,允许值高达 32767,而像 Linux 这样的系统(在 2.4 版之前)支持 16 位 UID,最多可达 65536。现在大多数现代 Unix-like 系统(例如 Solaris 2.0 和 Linux 2.4)都已转向使用 32 位 UID,这使得可用的 UID 数量达到了 4,294,967,296。
Linux 标准基础核心规范指定 UID 值范围 0 到 99 应由系统静态分配,并不应由应用程序创建,而 UID 100 到 499 的范围应由系统管理员和后安装脚本动态分配。
通常情况下,超级用户的 UID 为零(0)。 UID -1 被 POSIX 保留以识别省略的参数。无论如何,UID 65535 在 16 位时系统调用回传时,被保留作为 API 错误值。
NFSv4 旨在通过在协议包中使用文本形式的“user@domain”名称来避免数字标识符的碰撞。然而,只要操作系统内核和本地文件系统继续使用整数用户标识符,则需额外的转换步骤,这可能引入不必要的故障点。
这就引出了我们来探讨的问题:在数字环境中,UID 究竟是如何影响你的安全性的,你又是否真正了解它的作用呢?