Ausführen von Kind-Prozessen als anderer Benutzer aus einem lange Laufenden Python-Prozess
Habe ich eine lange laufen, daemonisierte Python-Prozess, der verwendet Teilprozess, um zu laichen neue Kind-Prozesse, wenn bestimmte Ereignisse auftreten. Der lange andauernde Prozess wird gestartet, indem ein Benutzer mit super-user-Privilegien. Ich brauche die Kind-Prozesse erzeugt, um als ein anderer Benutzer ausgeführt (z.B., "niemand") unter Beibehaltung der super-user-Berechtigungen für den übergeordneten Prozess.
Ich bin derzeit mit
su -m nobody -c <program to execute as a child>
aber das scheint Schwergewicht und nicht sterben sehr sauber.
Gibt es eine Möglichkeit, dies zu erreichen programmgesteuert anstelle von su? Ich freu mich auf die os.set*uid-Methoden, aber der doc in der Python-std-lib ist ziemlich spärlich in diesem Bereich.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da Sie erwähnt ein daemon, kann ich feststellen, dass Sie ein Unix-ähnliches Betriebssystem. Das ist wichtig, weil, wie Sie dies tun, hängt von der Art Betriebssystem. Diese Antwort gilt nur zu Unix, einschließlich Linux und Mac OS X.
Teilprozess.Popen benutzen die fork/exec-Modell zu verwenden, Ihre preexec_fn. Das ist äquivalent zum Aufruf von os.fork(), preexec_fn() (in der Kind-Prozess), und os.exec() (in der Kind-Prozess) in dieser Reihenfolge. Seit os.setuid-bit os.setgid, und preexec_fn sind alle nur auf unterstützten Unix -, diese Lösung ist nicht portabel auf andere Arten von Betriebssystemen.
Folgende code ist ein Skript (Python 2.4+), die veranschaulicht, wie dies zu tun:
Können Sie aufrufen, das Skript wie dieses:
Start als root...
Nicht-root-in einem Kind-Prozess...
Wenn der untergeordnete Prozess beendet wird, gehen wir zurück zur Wurzel in übergeordneten ...
Hinweis, dass der übergeordnete Prozess warten, um für das Kind-Prozess beenden ist für die demonstration nur. Ich Tat dies so, dass die Eltern und Kind teilen konnte ein terminal. Ein Dämon hätte kein terminal und würde nur selten warten, um für ein Kind-Prozess beenden.
gid
ersten wie im Beispiel gezeigt!Es ist ein
os.setuid()
Methode. Sie können es verwenden, um den aktuellen Benutzer ändern für dieses Skript.One-Lösung ist, irgendwo, wo das Kind beginnt, zu nennen
os.setuid()
undos.setgid()
zum ändern der Benutzer-und Gruppen-id, und danach rufen Sie eine der os.exec* Methoden erzeugen ein neues Kind. Das neu erzeugte Kind mit den weniger leistungsfähigen Benutzer ohne die Fähigkeit, sich in eine leistungsstärkere wieder.Andere ist, es zu tun, wenn der daemon (der master-Prozess) gestartet wird und dann alle neu gespawnt Prozesse laufen unter dem gleichen Benutzer.
Für Informationen schauen Sie auf die manpage für setuid.
os.setgroups()
wenn Sie den Wechsel zu einem Benutzer mit zusätzlichen gids. Andere als, dass, ja, es ist ziemlich einfach.Eigentlich, Beispiel mit preexec_fn nicht für mich arbeiten.
Meine Lösung, die wunderbar funktioniert, um einige shell-Befehl von einem anderen Benutzer erhalten Ihre Ausgabe ist:
Dann, wenn Sie Lesen müssen, aus dem Prozess stdout:
Hoffe, es ist nützlich, nicht nur in meinem Fall.
Dem Benutzer ermöglichen, die auf sudo brauchen kein Passwort
Rufen Sie dann die root-Funktion mit
sudo
, z.B.:sudo
Berechtigungen für alles; dies bietet keine Sicherheit gegen den Missbrauch des Prozesses und öffnet ein Loch für den Missbrauch auf der Konsole. Wennsudo
notwendig ist, sollten Sie zumindest es einzuschränken, um den lokalen host und die Befehle/binaries benötigt werden, e. g.<username> <hostname> = (root) NOPASSWD: /sbin/mkfs.ext4