使用runuser
util-linux ( 的一个不同入口点su
,仅在从根目录启动时才运行),人们会看到如下所示的进程树:
[root] runuser -u username sometool
\- [username] sometool
exec
保留这个父进程而不是简单地放弃特权并访问目标的目的是什么?
答案1
正如您在联机帮助页中看到的:
--session-command=command 与 -c 相同,但不创建新会话(不鼓励)。
所以默认的调用需要创建一个新的进程,因为新的会话需要新的PID。
此外,返回代码取决于退出状态或终止进程的信号。最后一点还需要一个进程监视子进程的状态。
我认为这是设计造成的。与 IMO不同的是su
,runuser
它是在脚本中使用的(因此永远不要询问密码,更好地处理错误状态,并且还将信号处理(新会话)与调用者分开。
答案2
保留这个父进程的目的是什么
我仔细阅读了create_watching_parent
源su-common.c
代码。看起来父级留在附近,以便它可以执行以下操作:
cleanup_pam
孩子退出后家长调用- 如果子进程因信号而退出,则父进程会像 shell 那样打印(到 stderr)子进程的处理情况。
- 如果父进程收到 SIGINT、SIGQUIT 或 SIGTERM 信号,父进程将捕获该信号并使用 SIGTERM 和 SIGKILL 杀死子进程,然后使用收到的相同信号杀死自己。我想这样做是为了让用户在子进程将自己置于不同会话或 pgrp 的情况下可以直接终止命令。
答案3
补充其他答案,util-linux 中不分叉的命令是设置权限:
# setpriv --reuid=django --regid=django --inh-caps=-all --reset-env --clear-groups ./run-server