2009-06-26 8 views
11

Ich musste einen schmutzigen Linux-Hack für jemanden machen, damit sie einen Drucker mit dem Shell-Befehl cupsenable printername starten konnten, während sie kein Root-Benutzer waren. Ich wollte nicht, dass sie die gesamte cupsenable-Syntax als root verwenden können, also schrieb ich gerade einen C-Wrapper, der die Eingabe in argv[1] bereinigt und system("cupsenable sanitizedprintername") aufruft.Warum brauche ich setuid (0) innerhalb eines setuid-root C-Programms, das ein Administrationsprogramm mit system() aufruft?

Ich machte das Programm setuid root, aber selbst so, cupsenable schlug mit "Berechtigung verweigert". Dann habe ich einen setuid(0) Anruf vor system() eingefügt und, siehe da, es funktionierte.

Das Problem, dass es eine bessere Möglichkeit gibt, den Benutzern die Kontrolle über den Drucker zu geben, wird ignoriert. Es gibt wahrscheinlich einen besseren Weg. Was mich interessiert, sind die Feinheiten von chmod u+s vs setuid(0) vs system(). Warum hat es sich so verhalten?

Antwort

17

Von man system:

nicht system() aus einem Programm mit Set-User-ID oder Set-Gruppen-ID Privilegien Verwenden Sie, weil seltsame Werte für einige Umgebungsvariablen verwendet werden könnten, die Systemintegrität zu untergraben. Verwenden Sie stattdessen die Funktionsfamilie exec(3), aber nicht execlp(3) oder execvp(3). system() wird tatsächlich nicht ordnungsgemäß von Programmen mit Set-Benutzer-ID oder Set-Gruppen-ID-Berechtigungen auf Systemen, auf denen /bin/sh ist Bash-Version 2, da Bash 2 Privilegien beim Start ablegt.

Und von man bash:

Wenn die Shell keinen Start mit der effektiven Benutzer (Gruppe) id nicht gleich den realen Benutzer (Gruppe) id und die -p Option nicht angegeben wird, gestartet wird, Dateien werden gelesen, Shell-Funktionen werden nicht von der Umgebung übernommen, die Variable SHELLOPTS wird, wenn sie in der Umgebung angezeigt wird, ignoriert, und die effektive Benutzer-ID wird auf die echte Benutzer-ID gesetzt.

Es scheint, Ihre setuid(0) Anruf umgangen diesen Schutz.

+2

Whoa. Nun, ich habe gesagt, es war dreckig. Es scheint, dass ich den Bash-Prozess, der durch das System() hervorgebracht wurde, davon überzeugt habe, dass ich tatsächlich, wirklich, ehrlich Wurzel war, Gott schwöre. Es scheint etwas Refactoring in Ordnung zu sein. – JCCyC