在程序中使用 setuid()/setgid() 与使用 sudo -u xxx -g xxx 调用它之间有什么区别?

在程序中使用 setuid()/setgid() 与使用 sudo -u xxx -g xxx 调用它之间有什么区别?

考虑这个 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 讨论

我还没有研究过您的具体设备/手刹需求,但这应该会让您走上正确的轨道。

相关内容