好吧,确定了,我(bork)无法访问 panda-file.txt。这一点都不让人吃惊,我的命令解释器并没有将 panda 组作为补充组 ID,运行 adduser bork panda 并不会改变这一点。
那进程一开始是怎么得到用户的组的呢?这真是个非常令人困惑的问题,对吗?如果进程会将组的信息预置到进程的属性里面,进程在初始化的时候怎么取到组的呢?很明显你无法给你自己指定更多的组(否则就会和 Linux 访问控制的初衷相违背了……)
有一点还是很清楚的:一个新的进程是怎么从我的命令行解释器(/bash/fish)里被执行而得到它的组的。(新的)进程将拥有我的用户 ID(bork),并且进程属性里还有很多组 ID。从我的命令解释器里执行的所有进程是从这个命令解释器里 fork() 而来的,所以这个新进程得到了和命令解释器同样的组。
因此一定存在一个“第一个”进程来把你的组设置到进程属性里,而所有由此进程而衍生的进程将都设置这些组。而那个“第一个”进程就是你的登录程序login shell,在我的笔记本电脑上,它是由 login 程序(/bin/login)实例化而来。登录程序以 root 身份运行,然后调用了一个 C 的库函数 —— initgroups 来设置你的进程的组(具体来说是通过读取 /etc/group 文件),因为登录程序是以 root 运行的,所以它能设置你的进程的组。
让我们再登录一次好了!假如说我们正处于一个登录程序中,而我又想刷新我的进程的组设置,从我们前面所学到的进程是怎么初始化组 ID 的,我应该可以通过再次运行登录程序来刷新我的进程组并启动一个新的登录命令!
让我们试试下边的方法:
$ sudologin bork
$ groups
bork adm cdrom sudo dip plugdev lpadmin sambashare docker lxd panda
$ cat panda-file.txt # it works! I can access the file owned by `panda` now!
当然,成功了!现在由登录程序衍生的程序的用户是组 panda 的一部分了!太棒了!这并不会影响我其他的已经在运行的登录程序(及其子进程),如果我真的希望“所有的”进程都能对 panda 组有访问权限。我必须完全的重启我的登录会话,这意味着我必须退出我的窗口管理器然后再重新登录。(LCTT 译注:即更新进程树的树根进程,这里是窗口管理器进程。)
newgrp 命令在 Twitter 上有人告诉我如果只是想启动一个刷新了组信息的命令解释器的话,你可以使用 newgrp(LCTT 译注:不启动新的命令解释器),如下:
sudo addgroup panda
sudo adduser bork panda
newgrp panda # starts a new shell,and you don't have to be root to run it!
你也可以用 sg panda bash 来完成同样的效果,这个命令能启动一个bash 登录程序,而这个程序就有 panda 组。
seduid 将设置有效用户 ID其实我一直对一个进程如何以 setuid root 的权限来运行意味着什么有点似是而非。现在我知道了,事实上所发生的是:setuid 设置了
“有效用户 ID”! 如果我(julia)运行了一个 setuid root 的进程( 比如 passwd),那么进程的真实用户 ID 将为 julia,而有效用户 ID 将被设置为 root。
passwd 需要以 root 权限来运行,但是它能看到进程的真实用户 ID 是 julia ,是 julia 启动了这个进程,passwd 会阻止这个进程修改除了 julia 之外的用户密码。
就是这些了!在《Linux 编程接口》这本书里有很多 Linux 上一些功能的罕见使用方法以及 Linux 上所有的事物到底是怎么运行的详细解释,这里我就不一一展开了。那本书棒极了,我上面所说的都在该书的第九章,这章在 1300 页的书里只占了 17 页。
我最爱这本书的一点是我只用读 17 页关于用户和组是怎么工作的内容,而这区区 17 页就能做到内容完备、详实有用。我不用读完所有的 1300 页书就能得到有用的东西,太棒了!
相关资料可从以下信息得到下载:
点击这个 链接关注 Linux公社官方微信,关注后回复数字154515。即可得到网友的分享密码。
如果取消关注Linux公社公众号,即使再次关注,也将无法提供本服务!