Schreiben Sie eine Datei mit sudo-Rechten in Python

9

Der folgende Code gibt einen Fehler aus, wenn er von einem Nicht-Root-Benutzer für eine Datei im Besitz von root ausgeführt wird, auch wenn der Nicht-Root-Benutzer über sudo-Berechtigungen verfügt:

%Vor%

Gibt es eine Möglichkeit, open(filename, "w+") mit sudo-Rechten auszuführen, oder eine alternative Funktion, die das tut?

    
user2824889 14.09.2016, 20:34
quelle

5 Antworten

6

Sie haben ein paar Optionen:

  • Führen Sie Ihr Skript als root oder mit sudo
  • aus
  • Setze das setuid-Bit und habe root das Skript selbst (obwohl es auf vielen Systemen nicht mit Skripten funktioniert und das Skript dann von jedem aufgerufen werden kann)
  • Ermitteln Sie, dass Sie nicht als root ausgeführt werden ( os.geteuid() != 0 ), und rufen Sie sich dann mit sudo infront an (wodurch der Benutzer zur Eingabe seines Passworts aufgefordert wird) und beenden Sie:

%Vor%

Der Aufruf sieht so aus:

%Vor%     
L3viathan 14.09.2016 21:10
quelle
1

Die Möglichkeit, sudo zu verwenden, gibt Ihnen keine Privilegien, wenn Sie sie nicht benutzen. So wie andere Leute vorgeschlagen haben, solltest du dein Programm einfach mit sudo starten. Aber wenn Sie diese Idee nicht mögen (ich sehe keinen Grund dafür), können Sie einen anderen Trick machen.

Ihr Skript kann prüfen, ob es mit Root-Rechten oder nur mit Benutzerrechten ausgeführt wird. Als Skript kann sich tatsächlich mit höheren Rechten ausführen. Hier haben Sie ein Beispiel (bitte beachten Sie, dass das Speichern des Passworts im Quellcode keine gute Idee ist).

%Vor%

Ausgabe:

%Vor%     
Adam 14.09.2016 21:12
quelle
0

Ihr Skript ist auf die Berechtigungen beschränkt, mit denen es ausgeführt wird, da Sie Benutzer nicht ändern können, ohne bereits Root-Rechte zu besitzen.

Wie Rob sagte, ist die einzige Möglichkeit, dies zu tun, ohne Ihre Dateiberechtigungen zu ändern, die Ausführung mit sudo .

%Vor%     
Matt Olan 14.09.2016 20:41
quelle
0

Ich mag L3viathans Antwort. Ich würde eine vierte Option hinzufügen: Verwenden Sie subprocess.Popen (), um einen sh-Befehl auszuführen, um die Datei zu schreiben. So etwas wie subprocess.Popen('sudo echo \'{}\' > {}'.format(new_line, filename)) .

    
portusato 08.05.2017 13:14
quelle
0

TL; DR:

L3viathan's Antwort hat einen SynaxError -Editor: funktioniert gut mit Python 3.5+. Hier ist eine Version für Python 3.4.3 (standardmäßig auf Ubuntu 16.04 verteilt) und unten:

%Vor%

Ich ging jedoch mit einem anderen Ansatz vor, weil es den Code in meinem Anwendungsfall einfacher machte:

%Vor%

Erklärung

L3viathans Antwort hängt von PEP 448 , das in Python 3.5 enthalten war und zusätzliche Kontexte eingeführt hat, in denen die Erweiterung von Sternargumenten erlaubt ist. Für Python 3.4 und darunter kann Listenverkettung verwendet werden, um das Gleiche zu tun:

%Vor%

Aber Hinweis: subprocess.call() startet einen untergeordneten Prozess, dh nachdem root das Skript ausgeführt hat, wird der ursprüngliche Benutzer auch weiterhin sein Skript ausführen. Das bedeutet, dass Sie die erhöhte Logik auf eine Seite eines if/else -Blocks setzen müssen. Wenn das ursprüngliche Skript beendet ist, versucht es nicht, irgendeine Logik auszuführen, die eine Erhöhung erfordert (L3viathan's Beispiel tut dies).

Das ist nicht unbedingt eine schlechte Sache - es bedeutet, dass normale / erhöhte Logik im selben Skript geschrieben und schön getrennt werden kann - aber meine Aufgabe benötigte root für die gesamte Logik. Ich wollte keine Einrückungsebene verschwenden, wenn der andere Block leer sein würde, und ich hatte nicht bemerkt, wie die Verwendung eines Child-Prozesses die Dinge beeinflussen würde, also habe ich Folgendes versucht:

%Vor%

... und es ging natürlich kaputt, denn nachdem root fertig war, nahm der normale Benutzer die Ausführung seines Skripts wieder auf und versuchte, die Anweisungen auszuführen, die root erforderten.

Dann fand ich diesen Gist , der os.execvp() empfiehlt - was den laufenden Prozess ersetzt, anstatt ein Kind zu starten:

%Vor%

Dies verhält sich wie erwartet, speichert eine Einrückungsstufe und 3 Zeilen Code.

Vorbehalt: Ich wusste vor zehn Minuten noch nichts über os.execvp() und weiß noch nichts über mögliche Fallstricke oder Feinheiten um seine Verwendung herum. YMMV.

    
Peter Henry 28.08.2017 18:27
quelle

Tags und Links