考虑这个 python 脚本,它调用 HandBrakeCLI,一个尝试从 DVD 驱动器读取的程序:
调用.py
#!/usr/bin/python
import sys
import os
import subprocess as subp
import pprint
#immediately switch users
os.setgid(1002) #gid of "media"
os.setuid(1005) #uid of "jack"
#verify the switch worked
print os.getuid(), os.geteuid()
print os.getgid(), os.getegid()
#clear up any possible env var diffs
os.environ['USER'] = 'jack'
os.environ['USERNAME'] = 'jack'
os.environ['LOGNAME'] = 'jack'
#output env variables to see if there's anything different:
ff = open('env_%s.log' % sys.argv[1], 'w')
ff.write(pprint.pformat(dict(os.environ)))
ff.write("\n")
ff.close()
#call the program
p = subp.Popen(["HandBrakeCLI", "-i", "/dev/sr0", "-t", "0"])
p.communicate()
sys.exit(p.returncode)
以下(“A”)成功:
sudo -u jack -g media HandBrakeCLI -i /dev/sr0 -t 0
如下内容也是如此(“B”):
sudo -u jack -g media ./invoke.py jack
但是这个(“C”)失败了:
sudo ./invoke.py root
并打印错误,表明 HandBrakeCLI 无法访问 CD 驱动器。但是,打印语句确认 UID/GID 已成功更改为 jack:media。如果我删除 setuid/setgid 并以 root 身份从invoke.py 调用 HandBrakeCLI,它会再次正常工作。
差异表明环境本质上是相同的:
$ diff env_root.log env_jack.log
8c8
< 'SUDO_COMMAND': './invoke.py root',
---
> 'SUDO_COMMAND': './invoke.py jack',
调用 setuid 和 setgid 后,是否还有原始调用用户的“记忆”?如果没有,HandBrake 可能会对“B”和“C”有何不同看法?
我在无头服务器上运行 10.04,通过 ssh 访问。
答案1
这确实有区别,因为可以检测到权限是否提升(suid 情况),这与通过 sudo 运行不同。这是因为整个进程在 sudo 情况下以 'jack' 身份运行(并且永远不会恢复 uid:进程只是终止),而 suid 情况会“记住”原始 uid,并且只更改有效 uid。
你的情况略有不同,但这里有一个检测 sudo/suid 的每个组合的测试脚本:测试权限 现在,X11 服务器中使用类似的代码来检测提升的权限:xorg-devel 讨论
我还没有研究过您的具体设备/手刹需求,但这应该会让您走上正确的轨道。