Hi,
ich möchte auf einem der Unirechner ein script schreiben, das es allen Benutzern ermöglicht, einen Prozess (jackstart, der nur in einer Instanz auf dem System laufen kann) abzuschießen, auch wenn er einem anderen Benutzer gehört. Hintergrund ist, daß manche Studenten vor dem Ausloggen vergessen, diesen Prozess zu stoppen und dieser Prozess den Audioport blockiert.
Ich habe mit shellscripten die ProzessID isoliert. Leider lassen sich shellscripte, die diesen Prozess abschießen, nicht setuid ausführen. Mit einem kleinen c-Programm könnte sich das lösen lassen, aber ich bekomme die Prozessid die das Shellscript auf stdout ausgibt nicht ohne weiteres in das C-Programm, da sie auf stdout ausgegeben wird (ich halte es für keine gute Idee, die Prozessid in eine Datei zu schreiben und dann von dem c-Programm lesen zu lassen).
Hat jemand eine Idee? Ich habe es auch mit perl versucht, aber perl mault auch darüber, daß es den kill Befehl nicht suid ausführen möchte...
-- Orm
On Sunday 24 April 2005 17:05, Orm Finnendahl wrote:
Ich habe mit shellscripten die ProzessID isoliert. Leider lassen sich shellscripte, die diesen Prozess abschießen, nicht setuid ausführen. Mit einem kleinen c-Programm könnte sich das lösen lassen, aber ich bekomme die Prozessid die das Shellscript auf stdout ausgibt nicht ohne weiteres in das C-Programm, da sie auf stdout ausgegeben wird (ich halte es für keine gute Idee, die Prozessid in eine Datei zu schreiben und dann von dem c-Programm lesen zu lassen).
Starte das Shell-Script von dem C-Programm aus mit einer Pipe:
int pfd[2],pid;
pipe(pfd); if(pid=fork()){ /*Elternteil*/ read(pfd[0],...) waitpid(pid,0,0); } else { /*Kind*/ /*ersetze stdout durch pipe*/ close(STDOUT_FILENO); dup2(pfd[1],STDOUT_FILENO); /*führe script aus*/ fcntl(STDOUT_FILENO,F_SETFD,0); execl("/bin/sh","/pfad/zu/deinem/script",0); /*Hoppla! Script konnte nicht ausgeführt werden!*/ exit(1); } close(pfd[0]);close(pfd[1]);
/*hier kennst Du die PID von read...*/
Das ganze könnte sicherheitstechnisch noch etwas umgemodelt werden, aber man muss schon verdammt clever sein, um hier noch was auszunutzen.
Konrad
Hallo Konrad,
das war exakt, wonach ich suchte. Herzlichen Dank für die Mühe! Ich hoffe, ich verstehe alles. Ansonsten werde ich mich evtl. noch einmal melden.
Gruß, Orm
Am 24. April 2005, 17:13 Uhr (+0200) schrieb Konrad Rosenbaum:
Starte das Shell-Script von dem C-Programm aus mit einer Pipe:
int pfd[2],pid;
pipe(pfd); if(pid=fork()){ /*Elternteil*/ read(pfd[0],...) waitpid(pid,0,0); } else { /*Kind*/ /*ersetze stdout durch pipe*/ close(STDOUT_FILENO); dup2(pfd[1],STDOUT_FILENO); /*führe script aus*/ fcntl(STDOUT_FILENO,F_SETFD,0); execl("/bin/sh","/pfad/zu/deinem/script",0); /*Hoppla! Script konnte nicht ausgeführt werden!*/ exit(1); } close(pfd[0]);close(pfd[1]);
/*hier kennst Du die PID von read...*/
Das ganze könnte sicherheitstechnisch noch etwas umgemodelt werden, aber man muss schon verdammt clever sein, um hier noch was auszunutzen.
Konrad
Lug-dd maillist - Lug-dd@schlittermann.de http://mailman.schlittermann.de/mailman/listinfo/lug-dd
Hallo,
On Sun, 24 Apr 2005 17:05:23 +0200 Orm Finnendahl finnendahl@folkwang-hochschule.de wrote:
Ich habe mit shellscripten die ProzessID isoliert. Leider lassen sich shellscripte, die diesen Prozess abschießen, nicht setuid ausführen. Mit einem kleinen c-Programm könnte sich das lösen lassen, aber ich bekomme die Prozessid die das Shellscript auf stdout ausgibt nicht ohne weiteres in das C-Programm, da sie auf stdout ausgegeben wird (ich halte es für keine gute Idee, die Prozessid in eine Datei zu schreiben und dann von dem c-Programm lesen zu lassen).
also c ist in diesem Fall viel zu viel. Nimm einfach sudo.
Henning
Am 24. April 2005, 19:17 Uhr (+0200) schrieb Henning Schild:
also c ist in diesem Fall viel zu viel. Nimm einfach sudo.
das geht zwar problemlos, ist aber nicht ganz so gut zu automatisieren, da die Benutzer dafür in einem Terminal arbeiten müssen, um ihr Passwort einzugeben.
das C Programm funktioniert soweit prima, aber trotz suid will es einem Benutzer nicht erlauben, den kill Befehl auszuführen, wenn ihm der Prozess nicht gehört. Ich erhalte folgenden output:
[orm@studio01 orm]$ ls -l /usr/local/bin/killjack -r-s--x--x 1 root root 13195 24. Apr 19:39 /usr/local/bin/killjack [orm@studio01 orm]$ killjack killjack: executing '/bin/kill 6470' kill 6470: Die Operation ist nicht erlaubt [orm@studio01 orm]$
Habe ich da irgend etwas Grundlegendes nicht verstanden?
-- Orm
On Sunday 24 April 2005 19:43, Orm Finnendahl wrote:
das C Programm funktioniert soweit prima, aber trotz suid will es einem Benutzer nicht erlauben, den kill Befehl auszuführen, wenn ihm der Prozess nicht gehört. Ich erhalte folgenden output:
Mach ein setuid(0); bevor Du kill aufrufst. Es gibt nicht nur eine UID, sondern 3:
UID: die UID desjenigen der das Programm aufruft EUID: die effektive UID mit deren Rechten es arbeitet FUID: die UID mit der Dateizugriffe authorisiert werden (Linux: identisch mit EUID)
Ich bin mir nicht sicher, aber ich glaube kill gehört zu den wenigen Kommandos, die UID und EUID prüfen (die meisten nur die EUID).
Konrad
Am 24. April 2005, 19:57 Uhr (+0200) schrieb Konrad Rosenbaum:
Mach ein setuid(0); bevor Du kill aufrufst. Es gibt nicht nur eine UID, sondern 3:
UID: die UID desjenigen der das Programm aufruft EUID: die effektive UID mit deren Rechten es arbeitet FUID: die UID mit der Dateizugriffe authorisiert werden (Linux: identisch mit EUID)
Ich bin mir nicht sicher, aber ich glaube kill gehört zu den wenigen Kommandos, die UID und EUID prüfen (die meisten nur die EUID).
Genau das wars. kill ist da offensichtlich sehr empfindlich. Kommando funktioniert jetzt und der Fuß ist auch noch dran ;-)
Mal sehen, ob sich die Methode in der Praxis bewährt...
-- Orm
Am Sonntag, den 24.04.2005, 19:43 +0200 schrieb Orm Finnendahl:
[orm@studio01 orm]$ ls -l /usr/local/bin/killjack -r-s--x--x 1 root root 13195 24. Apr 19:39 /usr/local/bin/killjack [orm@studio01 orm]$ killjack killjack: executing '/bin/kill 6470' kill 6470: Die Operation ist nicht erlaubt [orm@studio01 orm]$
Habe ich da irgend etwas Grundlegendes nicht verstanden?
Ohne jetzt genau zu wissen, worum es eigentlich geht: Was ist denn an
int kill(pid_t pid, int sig);
falsch? (man -S 2 kill)
HTH, Eric
Hallo Orm,
On Sun, Apr 24, 2005 at 19:43:18 +0200, Orm Finnendahl wrote:
das geht zwar problemlos, ist aber nicht ganz so gut zu automatisieren, da die Benutzer dafuer in einem Terminal arbeiten muessen, um ihr Passwort einzugeben.
Bei entsprechender Parametrisierung ist kein Passwort noetig. Zeile aus /etc/sudoers:
username ALL=NOPASSWD: /path/to/killjackscript
In diesem Fall muesste das Skript natuerlich auch die eigentliche kill-Aktion uebernehmen, nicht nur die PID raussuchen.
das C Programm funktioniert soweit prima, aber trotz suid will es einem Benutzer nicht erlauben, den kill Befehl auszufuehren, wenn ihm der Prozess nicht gehoert. Ich erhalte folgenden output:
[orm@studio01 orm]$ ls -l /usr/local/bin/killjack -r-s--x--x 1 root root 13195 24. Apr 19:39 /usr/local/bin/killjack [orm@studio01 orm]$ killjack killjack: executing '/bin/kill 6470' kill 6470: Die Operation ist nicht erlaubt
Konrads suid-Programm ruft das kill-Kommando ueber 'sh -c' auf (sh ist ueblicherweise bash). Die bash stellt fest, ob sie im suid-Kontext laeuft (also ob sich effective userid und real userid unterscheiden). Ist das der Fall, faellt sie auf die real userid zurueck -- das ist ein Sicherheitsfeature der bash.
bye, Chris
lug-dd@mailman.schlittermann.de