# 管理员重置命令限制验收 日期:2026-09-19。 ## 需求与任务状态 - [✓] 仅显式 `systemctl start smail-admin` 进入重置流程,`systemctl stop smail-admin` 终止流程。 - [✓] `restart`、`reload` 及相关变体不能开启新的重置交互。 - [✓] 交互绑定启动终端,取消后无系统共享密码请求残留。 - [✓] 保留邮箱、动态码、安全码验证及受保护本机 IPC,不调整账户密码或生产数据库。 - [✓] Windows 定向测试、Linux 测试、服务器实际命令验证和部署完成。 ## 原因与修改 systemd 会将 `restart` 的启动阶段转换成 `start` Job,因此只检查 `list-jobs` 无法识别原始动作。`Restart=no` 只禁止自动重启,不限制管理员手工重启。`reload` 本身已被拒绝,但 systemctl 创建的密码代理会显示已有的系统共享输入请求。 管理程序现在要求唯一、本机 root、前台终端的显式 `systemctl start smail-admin` 进程,同时校验可执行文件、参数、进程启动时间及终端设备,继续保留 systemd 上下文及本机 IPC 校验。非交互启动、多服务、通配符、并发启动及重启命令均不授权。 输入直接绑定启动终端,验证内容可见,新密码不回显。保留终端行编辑、信号和换行设置,避免停止过程中与 shell 的终端恢复竞争。监测原启动进程退出或 PID 复用,取消输入并关闭连接。服务使用 `KillMode=mixed`,主进程先处理取消,再由 systemd 兜底清理。 ## 实机验证 环境:部署服务器的 systemd 259,使用两个独立 SSH 终端;只进入菜单或输入无效选项,没有发送邮件或执行真实改密。 | 场景 | 实际结果 | | --- | --- | | `start` | 显示安全验证方式列表,仅启动终端可见 | | `stop` | 流程终止,`inactive`、`Result=success`,终端模式正常 | | Ctrl+C | systemctl 退出,管理程序随后结束,无遗留输入请求 | | 未运行时 `restart` | 拒绝启动,退出码 1,无验证菜单 | | 正在输入时 `restart` | systemd 先终止现有流程;新启动被拒绝,不重新显示菜单 | | `reload` | systemd 报不支持;另一终端现有输入不被接管,原流程可继续 | | `reload-or-restart` | 拒绝启动,退出码 1,无验证菜单 | | 未运行时 `try-restart`、`try-reload-or-restart` | systemd 返回成功但不执行动作,管理进程 PID 为 0 | | 无效选项及结果提示 | 显示失败原因,按回车结束 | | 系统密码请求目录 | 验证期间及结束后均无本次重置产生的 `ask.*` | ## 自动化验证 - 本机:`go test ./services/adminreset ./cmd/smail-admin` 通过。 - Linux:交叉编译后的 `adminreset` 完整测试在服务器隔离目录运行通过。 - 覆盖显式命令、危险参数变体、进程启动时间/PID 重用、root 身份、真实伪终端输入、密码无回显、输入取消和终端恢复。 - `go vet ./services/adminreset ./cmd/smail-admin`、`git diff --check` 通过。 - unit 校验通过;systemd 对现有其他服务的 `CPUAccounting` 弃用提示与本次修改无关。 ## systemd 行为边界 systemd 没有独立禁止手工 `restart`、同时允许 `start`/`stop` 的 unit 指令。因此不能删除 systemctl 自身的命令,也不能阻止它先执行重启的停止阶段。本次保证这些命令无法启动或重新进入重置流程。只读的 `status`、`show` 和日志查询继续可用。 原始命令检查约束正常部署操作,不构成对主机 root 的隔离;安全凭据验证和受保护本机 IPC 必须独立保留。验证二进制保存在 `/run/smail-command-validation-20260919/`,部署前备份保存在 `/var/backups/smail-admin-command-20260919/`。