我一直在谷歌上搜索试图找到这个问题的答案,并试图在心里解析初始化脚本以找到它完成的位置,但无济于事。
我刚刚做了ps
一个随机的例子。我有一个如下所示的过程:
polkitd 1230 1 0 May07 ? 00:00:00 /usr/lib/polkit-1/polkitd --no-debug
查看我的 /etc/passwd,我看到:
polkitd:x:87:87:PolicyKit daemon owner:/var/lib/polkit:/bin/false
作为测试,我以 root 身份运行一个命令:
# su - polkitd -c whoami
正如预期的那样,它没有返回任何输出,因为它具有 /bin/false 作为 shell。此外,# su - polkitd
不会将我切换到 polkitd。为了确保我正确地执行了此操作,我使用普通用户帐户测试了这两种方法,并且它们都按预期工作。
那么,当您似乎根本无法让它手动运行任何内容时,如何才能让专用帐户(例如我的示例中的 polkitd)来运行进程呢?
答案1
root
可以polkitd
通过适当的系统调用,例如seteuid(2)
可以证明
$ cat becomepolkit.c
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
// ID obtained via `id polkitd` on a Centos7 system
// other systems may vary
seteuid(999);
printf("look for %d in process list\n", getpid());
sleep(99999);
return 0;
}
$ make becomepolkit
cc becomepolkit.c -o becomepolkit
$ sudo ./becomepolkit &
[1] 10914
$ look for 10915 in process list
$ ps auwwx | grep '1091[5]'
polkitd 10915 0.0 0.0 4160 340 pts/0 S 22:46 0:00 ./becomepolkit
$
通常root
通过 init 系统(例如systemd
)或cron
将启动一个进程为root
,然后更改该进程的用户;发生这种情况不需要 shell 访问。您可以通过在strace
或其他一些跟踪工具下运行该进程来观察任意进程的情况:
sudo strace -o blah ./becomepolkit
look for 10968 in process list
^C$ grep 999 blah
setresuid(-1, 999, -1) = 0
nanosleep({99999, 0}, {99997, 670178798}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
$
所以这里Linux实际上使用的是setresuid(2)
调用但相同的区别,进程将显示polkitd
在进程表中。
答案2
用户的登录 shell 是大多数登录程序在用户经过身份验证(通常通过输入用户名和密码)时调用的程序。登录程序包括login
(用于文本控制台登录)、sshd
(用于通过网络登录)、su
(用于从其他帐户登录)等。
登录程序可以选择运行它们选择的任何内容。事实上,它们中的大多数运行用户的登录 shell,这是一个管理决策,而不是技术限制。一类不遵循此约定的登录程序是显示管理器,即以图形模式登录用户的程序:这些程序通常执行/bin/sh
诸如/etc/X11/Xsession
.
系统服务通常根本不被登录程序调用。它们由以管理权限运行的守护程序启动器自动调用;启动系统服务不需要任何身份验证。 (对于用户来说要求启动系统服务通常需要身份验证才能成为 root。)因此根本不涉及登录 shell,因此没有理由涉及它。
守护进程启动器(我用于此答案的术语)包括系统,启动-停止-守护进程,运行用户, ETC。