Ich habe ein Python-Skript, das viele Dinge erledigt, für die Berechtigungen auf Stammebene erforderlich sind, z. B. das Verschieben von Dateien in / etc, das Installieren mit apt-get usw. Ich habe derzeit:
if os.geteuid() != 0:
exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.")
Ist dies der beste Weg, um die Prüfung durchzuführen? Gibt es andere Best Practices?
python
root
privileges
Paul Hoffman
quelle
quelle
os.geteuid
erhält die effektive Benutzer-ID, genau das, was Sie wollen, daher kann ich mir keinen besseren Weg vorstellen, um eine solche Prüfung durchzuführen. Das eine, was ungewiss ist, ist das "root-like" im Titel: Ihr Code prüft genauroot
, kein "like", und in der Tat würde ich nicht wissen, was "root-like, aber nicht root" bedeuten würde - also , wenn du etwas anderes meinst als "genau root", kannst du vielleicht klarstellen, danke!quelle
Sie können den Benutzer zum Sudo-Zugriff auffordern:
import os, subprocess def prompt_sudo(): ret = 0 if os.geteuid() != 0: msg = "[sudo] password for %u:" ret = subprocess.check_call("sudo -v -p '%s'" % msg, shell=True) return ret if prompt_sudo() != 0: # the user wasn't authenticated as a sudoer, exit?
Der
sudo -v
Switch aktualisiert die zwischengespeicherten Anmeldeinformationen des Benutzers (sieheman sudo
).quelle
Wenn Sie wirklich möchten, dass Ihr Code für eine Vielzahl von Linux-Konfigurationen robust ist, sollten Sie die Eckfälle berücksichtigen, in denen möglicherweise jemand SELinux oder Dateisystem-ACLs verwendet, oder die Funktionen des Linux-Kernels seit v. 2.2 oder so. Ihr Prozess wird möglicherweise unter einem Wrapper ausgeführt, der SELinux verwendet hat, oder unter einer Linux-Funktionsbibliothek wie libcap2 libcap-ng oder fscaps oder elfcap über etwas Exotischeres wie das wunderbare und leider unterschätzte Systrace- System von Niels Provos .
Auf all diese Arten wird Ihr Code möglicherweise als Nicht-Root ausgeführt, und Ihrem Prozess wurde möglicherweise der erforderliche Zugriff übertragen, um seine Arbeit ohne EUID == 0 auszuführen.
Daher würde ich vorschlagen, dass Sie erwägen, Ihren Code pythischer zu schreiben, indem Sie Vorgänge einschließen, die aufgrund von Berechtigungen oder anderen Problemen mit Ausnahmebehandlungscode fehlschlagen können. Wenn Sie verschiedene Vorgänge ausführen möchten (z. B. mithilfe des
subprocess
Moduls), können Sie allen solchen Aufrufensudo
ein Präfix voranstellen (z. B. als Befehlszeilen-, Umgebungs- oder RC-Dateioption). Wenn es interaktiv ausgeführt wird, können Sie anbieten, alle Befehle, die berechtigungsbezogene Ausnahmen auslösen , erneut auszuführensudo
(optional nur, wenn Sie siesudo
in der Datei os.environ ['PATH'] finden).Insgesamt ist es richtig, dass die meisten Linux- und UNIX-Systeme den größten Teil ihrer Verwaltung noch von einem Benutzer mit Root-Berechtigung durchführen lassen. Es ist jedoch alte Schule und wir als Programmierer sollten versuchen, neuere Modelle zu unterstützen. Wenn Sie versuchen, Ihre Vorgänge auszuführen und die Ausnahmebehandlung ihre Arbeit erledigen zu lassen, kann Ihr Code unter jedem System ausgeführt werden, das die von Ihnen benötigten Vorgänge transparent zulässt. Es
sudo
ist eine nette Geste , sich dessen bewusst und einsatzbereit zu sein (da dies bei weitem am weitesten verbreitet ist) Tool zur kontrollierten Delegierung von Systemberechtigungen).quelle
Ich suche gerne in den Umgebungsvariablen nach Sudo:
quelle
Für Linux:
def is_root(): return os.geteuid() == 0
quelle
Antwort auf den zweiten Teil der Frage
(Entschuldigung, das Kommentarfeld war zu klein)
Paul Hoffman, Sie haben Recht, ich habe nur einen Teil Ihrer Frage behandelt, der sich mit Intrinsics befasst, aber es wäre keine würdige Skriptsprache, wenn sie nicht behandelt werden könnte
apt-get
. Die bevorzugte Bibliothek ist ein bisschen ausführlich, aber sie macht den Job:>>> apt_get = ['/usr/bin/apt-get', 'install', 'python'] >>> p = subprocess.Popen(apt_get, stdout=subprocess.PIPE, stderr=subprocess.PIPE) >>> p.wait() 100 # Houston, we have a problem. >>> p.stderr.read() 'E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)' 'E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?\n'
Ist
Popen
aber ein verallgemeinertes Werkzeug und kann der Einfachheit halber verpackt werden:$ cat apt.py import errno import subprocess def get_install(package): cmd = '/usr/bin/apt-get install'.split() cmd.append(package) output_kw = {'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE} p = subprocess.Popen(cmd, **output_kw) status = p.wait() error = p.stderr.read().lower() if status and 'permission denied' in error: raise OSError(errno.EACCES, 'Permission denied running apt-get') # other conditions here as you require $ python >>> import apt >>> apt.get_install('python') Traceback ... OSError: [Errno 13] Permission denied running apt-get
Und jetzt kehren wir zur Ausnahmebehandlung zurück. Ich werde es ablehnen, die Java-ähnliche Überallgemeinheit des Unterprozessmoduls zu kommentieren.
quelle
Meine App funktioniert mit diesem Code:
import os user = os.getenv("SUDO_USER") if user is None: print "This program need 'sudo'" exit()
quelle
TypeError
, denn wenn Sie nicht als root ausgeführt wird ,os.getenv("SUDO_USER")
Rückkehr ,None
die vom Typ istNoneType
, und Sie können nicht verkettenstr
undNoneType
. Wenn Sie verwenden möchten,os.getenv("SUDO_USER")
um das Problem zu lösen, sollten Sie es wieif os.getenv("SUDO_USER") == None: print "This program need 'sudo'"; exit()
os.getenv('HOME')
zeigt Ihnen, ob der aktuelle Benutzer ein Benutzer istroot
odersudo
was Ihr Skript im Allgemeinen wissen muss.Es hängt alles davon ab, wie portabel Ihre App sein soll. Wenn Sie geschäftlich meinen, müssen wir davon ausgehen, dass das Administratorkonto nicht immer gleich 0 ist. Dies bedeutet, dass die Überprüfung auf euid 0 nicht ausreicht. Das Problem ist, dass es Situationen gibt, in denen sich ein Befehl so verhält, als wären Sie root, und der nächste mit fehlgeschlagener Berechtigung fehlschlägt (denken Sie an SELinux & Co.). Daher ist es wirklich besser, ordnungsgemäß zu versagen und nach EPERM-Fehlern zu suchen, wann immer dies angemessen ist.
quelle