# 14.5 用户分级

**/etc/login.conf** 是登录类能力数据库（最早引入自 FreeBSD 2.1.5），用于控制资源配额、计量配额及默认用户环境设置。本节介绍其文件结构、class 定义语法与用户本地覆盖方法。

## login.conf 的概念与文件结构

系统中的多种程序利用该数据库建立用户的登录环境，并执行策略、计数和管理限制。它还提供了用户认证以及可用认证类型的配置方式。

```sh
/
├── etc/
│   └── login.conf           # 系统级用户分级配置文件，定义各种 class 的资源限制、环境变量等
└── 用户家目录 (~)/
    └── .login_conf          # 用户本地覆盖文件，可覆盖 /etc/login.conf 的设置
```

普通用户可通过主目录下的 **\~/.login\_conf** 文件覆盖系统级配置，该文件仅包含一条记录 ID 为“me”的条目。但仅部分登录能力可覆盖，通常仅限于不涉及认证、资源限制和计费的环境设置；系统级配置文件 **/etc/login.conf** 的优先级低于用户本地配置。

`login.conf` 文件在 FreeBSD 源代码中的位置为 [usr.bin/login/login.conf](https://github.com/freebsd/freebsd-src/blob/main/usr.bin/login/login.conf)，该文件即为默认配置，默认设置禁用了资源配额。

> **注意**
>
> 每次修改该文件后，必须手动运行 `cap_mkdb /etc/login.conf` 以刷新数据库。`cap_mkdb` 将文本格式的 login.conf 编译为哈希数据库格式，以提高查询性能。只有将文件编译为数据库后，修改才会生效。该数据库文件的扩展名为 `.db`，可通过 cgetent(3) 等函数调用。用户级 `~/.login_conf` 同样需要 `cap_mkdb ~/.login_conf` 编译才能生效。

## 默认配置文件解读

```ini
# 请注意，像 “cputime” 这样的条目会同时设置 “cputime-cur” 和 “cputime-max”。
# “default” 登录类会自动（由 login(1) 实现）应用于所有在 /etc/master.passwd 中未设置有效登录类的非 root 用户。
# 请注意，由于冒号 ':' 用于分隔能力条目，因此在能力的值或名称中嵌入字面冒号时必须使用 \c 转义序列（有关更多转义序列，请参见 getcap(3) 的 “CGETNUM AND CGETSTR SYNTAX AND SEMANTICS” 部分）。
# UID 为 0 的用户（root）如果没有有效登录类，则使用 root 记录（如果有），否则使用 default。
# default 登录类

default:\
	:passwd_format=sha512:\ # 新建或更改密码将使用的加密格式。类型为字符串。有效值为 "des"、"md5"、"blf"、"sha256" 和 "sha512"；详细信息请参见 crypt(3)。使用非 FreeBSD NIS 服务器的 NIS 客户端通常应使用 "des"。
	:welcome=/var/run/motd:\  # 登录后会看到的信息
	:setenv=BLOCKSIZE=K:\  # 由逗号分隔的环境变量及其对应值的列表。包含逗号的值必须加引号。BLOCKSIZE=K 即让命令以 KB 大小格式显示
	:mail=/var/mail/$:\  # 将环境变量 $MAIL 设置为指定的值。
	:path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ~/bin:\  # 默认的 PATH 环境变量路径，会在其中查找可执行文件
	:nologin=/var/run/nologin:\  # 如果该文件存在，将打印该文件到屏幕上，并且对应用户的登录会话将被终止。
	:cputime=unlimited:\  # 限制进程可使用的 CPU 时间量。类型为时间，默认单位为秒。时间值可以使用不同单位表示：y 表示年（365 天）、w 表示周、d 表示天、h 表示小时、m 表示分钟、s 表示秒。单位可以连写，其值会累加。例如，2 小时 40 分钟可以写作 9600s、160m 或 2h40m。
	:datasize=unlimited:\  # 限制数据段（属于静态内存分配）的最大大小。类型为数值，默认单位为字节。常用单位包括 b、k、m、g、t，分别表示 512 字节、KB、MB、GB 和 TB，大小写不敏感。多个值可以连写，其数值会累加。例如 2g512M 表示总大小为 2.5 GB。
	:stacksize=unlimited:\  # 最大栈大小限制。类型为数值。
	:memorylocked=64K:\  # 最大核心锁定内存大小限制。类型为数值。
	:memoryuse=unlimited:\  # 最大核心内存使用量限制。类型为数值。
	:filesize=unlimited:\  # 限制进程可以创建的文件的最大大小。类型为数值。
	:coredumpsize=unlimited:\ # 最大 coredump 大小限制。类型为数值。
	:openfiles=unlimited:\  # 限制每个进程允许打开的最大文件数。类型为数字。数字类型可以是十六进制（0x 开头）或八进制（0 开头），每次只能指定一个值，也可以用字符串格式。数据库中所有记录必须统一使用同一表示方法。
	:maxproc=unlimited:\  # 限制最大进程数。类型为数字。
	:sbsize=unlimited:\  # 最大的套接字缓冲区大小。类型为数值。
	:vmemoryuse=unlimited:\  # 每个进程允许的最大虚拟存储器使用量。类型为数值。
	:swapuse=unlimited:\  # 最大交换空间大小限制。类型为数值。
	:pseudoterminals=unlimited:\  # 最大伪终端数量。类型为数字。
	:kqueues=unlimited:\  # 每个进程可创建的 kqueue 数量。类型为数字。
	:umtxp=unlimited:\  # 最大进程间共享的 pthread 锁数量。类型为数字。
	:pipebuf=unlimited:\  # 管道缓冲区的最大大小。类型为数字。
	:priority=0:\  # 初始进程优先级等级。类型为数字。用于设置进程的初始优先级：既可使用普通 nice 范围（-20 到 20），也可映射到实时或空闲优先级；如果设置特殊值 “inherit” 表示继承原有优先级，不进行重置。0 代表正常优先级。
	:umask=022:\  # 设置初始 umask。类型为数字，应以 0 开头以确保按八进制识别。特殊值 "inherit" 表示保持原有 umask 不变。022 表示文件默认权限为 644，目录默认权限为 755。
	:charset=UTF-8:\  # 指定环境变量 $MM_CHARSET（邮件相关程序会使用）的值。类型为字符串。
	:lang=C.UTF-8:  # 指定环境变量 $LANG 的值。类型为字符串。修改此处即可实现整个操作系统的全局 i18n 配置。

#
# 一组常见的类别名称，将它们全部转发到 'default'（login 通常也会这么做，但在这里有类别名称会抑制诊断信息）。
#
standard:\
	:tc=default:
xuser:\
	:tc=default:
staff:\
	:tc=default:

# 该 PATH 可能会被各个应用程序覆盖。特别是在默认情况下，rc(8)、service(8) 和 cron(8) 在启动服务或任务时会使用默认 PATH，而该 PATH 可能不包含 /usr/local/sbin 和 /usr/local/bin。
daemon:\
	:path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin:\
	:mail@:\
	:memorylocked=128M:\
	:tc=default:
news:\
	:tc=default:
dialer:\
	:tc=default:

#
# 让 Root 始终可以登录。
#
# 注意，对于 root 账户，login_getpwclass(3)（仅限该软件，不是全局设置）会应用此条目，而不是 'default' 中的参数。
root:\
	:ignorenologin:\  # 防止误操作，避免因 nologin 设置而阻止 root 登录
	:memorylocked=unlimited:\  # 防止误操作，避免内存配额限制导致 root 无法分配内存
	:tc=default:  # 继承或复用另一个登录类（此处是 default）的属性和能力，避免重复定义。如果子类中有与父类同名的能力条目，则子类中的值会覆盖父类的值。

#
# 为俄罗斯用户账户配置正确的环境变量
#
# russian 登录类。可使用命令 pw usermod XXX -L russian 指定用户 XXX 使用该登录类。
#
russian|Russian Users Accounts:\
	:charset=UTF-8:\
	:lang=ru_RU.UTF-8:\
	:tc=default: # 继承或复用另一个登录类（此处是 default）的属性和能力，避免重复定义。如果子类中有与父类同名的能力条目，则子类中的值会覆盖父类的值。


######################################################################
######################################################################
##
## 示例条目
##
######################################################################
######################################################################

## 示例默认值
## 这些设置默认由 login(1) 分配给无类别用户。请注意，像“cputime”这样的条目会同时设置“cputime-cur”和“cputime-max”。
#
#default:\
#	:cputime=infinity:\
#	:datasize-cur=22M:\
#	:stacksize-cur=8M:\
#	:memorylocked-cur=10M:\
#	:memoryuse-cur=30M:\
#	:filesize=infinity:\
#	:coredumpsize=infinity:\
#	:maxproc-cur=64:\
#	:openfiles-cur=64:\
#	:priority=0:\
#	:requirehome@:\
#	:umask=022:\
#	:tc=auth-defaults:
#
#
##
## standard - 标准用户默认值
##
#standard:\
#	:welcome=/var/run/motd:\
#	:setenv=BLOCKSIZE=K:\
#	:mail=/var/mail/$:\
#	:path=~/bin /bin /usr/bin /usr/local/bin:\
#	:manpath=/usr/share/man /usr/local/man:\
#	:nologin=/var/run/nologin:\
#	:cputime=1h30m:\
#	:datasize=8M:\
#	:vmemoryuse=100M:\
#	:stacksize=2M:\
#	:memorylocked=4M:\
#	:memoryuse=8M:\
#	:filesize=8M:\
#	:coredumpsize=8M:\
#	:openfiles=24:\
#	:maxproc=32:\
#	:priority=0:\
#	:requirehome:\
#	:passwordtime=90d:\
#	:umask=002:\
#	:tc=default:
#
#
##
## X 用户（需要更多资源！）
##
#xuser:\
#	:manpath=/usr/share/man /usr/local/man:\
#	:cputime=4h:\
#	:datasize=12M:\
#	:vmemoryuse=infinity:\
#	:stacksize=4M:\
#	:filesize=8M:\
#	:memoryuse=16M:\
#	:openfiles=32:\
#	:maxproc=48:\
#	:tc=standard:
#
#
##
## Staff（工作人员）用户，限制少，可随时登录
##
#staff:\
#	:ignorenologin:\
#	:requirehome@:\
#	:accounted@:\
#	:path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:umask=022:\
#	:tc=standard:
#
#
##
## root - root 登录的备选方案
##
#root:\
#	:path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:cputime=infinity:\
#	:datasize=infinity:\
#	:stacksize=infinity:\
#	:memorylocked=infinity:\
#	:memoryuse=infinity:\
#	:filesize=infinity:\
#	:coredumpsize=infinity:\
#	:openfiles=infinity:\
#	:maxproc=infinity:\
#	:memoryuse-cur=32M:\
#	:maxproc-cur=64:\
#	:openfiles-cur=1024:\
#	:priority=0:\
#	:requirehome@:\
#	:umask=022:\
#	:tc=auth-root-defaults:
#
#
##
## /etc/rc 使用的设置
##
#daemon:\
#	:coredumpsize@:\
#	:coredumpsize-cur=0:\
#	:datasize=infinity:\
#	:datasize-cur@:\
#	:maxproc=512:\
#	:maxproc-cur@:\
#	:memoryuse-cur=64M:\
#	:memorylocked-cur=64M:\
#	:openfiles=1024:\
#	:openfiles-cur@:\
#	:stacksize=16M:\
#	:stacksize-cur@:\
#	:tc=default:
#
#
##
## news 子系统使用的设置
##
#news:\
#	:path=/usr/local/news/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:cputime=infinity:\
#	:filesize=128M:\
#	:datasize-cur=64M:\
#	:stacksize-cur=32M:\
#	:coredumpsize-cur=0:\
#	:maxmemorysize-cur=128M:\
#	:memorylocked=32M:\
#	:maxproc=128:\
#	:openfiles=256:\
#	:tc=default:
#
#
##
## dialer 类应当用于拨号 PPP 账号
## 欢迎信息/新闻已被屏蔽
##
#dialer:\
#	:hushlogin:\
#	:requirehome@:\
#	:cputime=unlimited:\
#	:filesize=2M:\
#	:datasize=2M:\
#	:stacksize=4M:\
#	:coredumpsize=0:\
#	:memoryuse=4M:\
#	:memorylocked=1M:\
#	:maxproc=16:\
#	:openfiles=32:\
#	:tc=standard:
#
#
##
## dialer 类，应当用于拨号 PPP 账号
## 欢迎信息/新闻已被屏蔽
##
#site:\
#	:passwordtime@:\
#	:refreshtime@:\
#	:refreshperiod@:\
#	:sessionlimit@:\
#	:autodelete@:\
#	:expireperiod@:\
#	:graceexpire@:\
#	:gracetime@:\
#	:warnexpire@:\
#	:warnpassword@:\
#	:idletime@:\
#	:sessiontime@:\
#	:daytime@:\
#	:weektime@:\
#	:monthtime@:\
#	:warntime@:\
#	:accounted@:\
#	:tc=dialer:\
#	:tc=staff:
#
#
##
## 订阅等级的标准会计分录示例
##
#
#subscriber|Subscribers:\
#	:accounted:\
#	:refreshtime=180d:\
#	:refreshperiod@:\
#	:sessionlimit@:\
#	:autodelete=30d:\
#	:expireperiod=180d:\
#	:graceexpire=7d:\
#	:gracetime=10m:\
#	:warnexpire=7d:\
#	:warnpassword=7d:\
#	:idletime=30m:\
#	:sessiontime=4h:\
#	:daytime=6h:\
#	:weektime=40h:\
#	:monthtime=120h:\
#	:warntime=4h:\
#	:tc=standard:
#
#
##
## 订阅账号。这些账号的登录时间会被记录，并施加访问限制。
##
#subppp|PPP Subscriber Accounts:\
#	:tc=dialer:\
#	:tc=subscriber:
#
#
#subshell|Shell Subscriber Accounts:\
#	:tc=subscriber:
#
##
## 如果希望部分账号使用传统的 UNIX DES 加密密码哈希。
##
#des_users:\
#	:passwd_format=des:\
#	:tc=default:
```

## 参考文献

* FreeBSD Project. login.conf(5)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=login.conf&sektion=5>. 登录类别功能数据库手册页。
* FreeBSD Project. cgetent -- capability database access routines\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=cgetent&sektion=3>. 能力数据库访问例程手册页。

## 课后习题

1. 修改用户的 **\~/.login\_conf** 文件覆盖系统级 `login.conf` 的部分设置，记录两种配置的优先级关系，分析 `cgetent()` 函数的数据库检索顺序。
2. 修改 default 类的 `umask` 和 `passwd_format` 设置，对比修改前后新建文件权限和密码加密方式的变化。
3. 创建一个自定义登录类，设置特定的资源限制（如 `cputime` 和 `maxproc`），分配给测试用户并验证限制是否生效，分析资源限制在内核层面的实现机制。


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/di-14-zhang-xi-tong-guan-li/di-14.5-jie-yong-hu-fen-ji-wen-jian-login-conf.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
