web-dev-qa-db-fra.com

Y a-t-il une différence entre utiliser setuid () / setgid () dans un programme et l'invoquer avec Sudo -u xxx -g xxx?

Considérez ce script python, qui appelle HandBrakeCLI, un programme qui tente de lire à partir du lecteur de DVD:

invoke.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)

Ce qui suit ("A") réussit:

Sudo -u jack -g media HandBrakeCLI -i /dev/sr0 -t 0

comme cela ("B"):

Sudo -u jack -g media ./invoke.py jack

mais cela ("C") échoue:

Sudo ./invoke.py root

et imprime des erreurs suggérant que HandBrakeCLI n'a pas pu accéder au lecteur de CD. Les instructions d'impression confirment cependant que l'UID/GID a été correctement remplacé par jack: media. Si je supprime le setuid/setgid et que j'appelle HandBrakeCLI depuis invoke.py en tant que root, cela fonctionne à nouveau.

Un diff montre que les environnements sont essentiellement les mêmes:

$ diff env_root.log env_jack.log
8c8
<  'Sudo_COMMAND': './invoke.py root',
---
>  'Sudo_COMMAND': './invoke.py jack',

Après avoir invoqué setuid et setgid, y a-t-il de la "mémoire" de l'utilisateur d'origine? Sinon, qu'est-ce que HandBrake pourrait voir différemment entre "B" et "C"?

J'utilise 10.04 sur un serveur sans tête auquel j'accède via ssh.

3
trbabb

Cela fait une différence, car on peut détecter si les privilèges ont été élevés (cas suid), ce qui est différent de l'exécution via Sudo. En effet, tout le processus s'exécute en tant que 'jack' dans le cas Sudo (et ne retourne jamais l'uid: le processus se termine juste), tandis que le cas suid "se souvient" de l'uid d'origine et seul l'uid effectif est changé.

Votre situation est légèrement différente mais voici un script de test qui détecte chaque combinaison de Sudo/suid: test_privs.sh Un code similaire est maintenant utilisé sur le serveur X11 pour détecter des privilèges élevés: xorg- développer la discussion

Je n'ai pas examiné les besoins spécifiques de votre appareil/frein à main, mais cela devrait vous mettre sur la bonne voie.

2
totaam