/proc in BASH script bearbeiten

Hi,

ich möchte als unprivilegierter User in der Lage sein Bluetooth an / aus zu schalten. Dazu habe ich folgendes mini-script:

/usr/bin/bluetoothctl
Code:
#!/bin/bash
if [ "$1" = "on" ]; then
	echo "on"
	echo 1 > /sys/devices/platform/thinkpad_acpi/bluetooth_enable 
fi

if [ "$1" = "off" ]; then
	echo "off"
	echo 0 > /sys/devices/platform/thinkpad_acpi/bluetooth_enable 
fi

Ich habe also das SUID bit und "root" als Owner gesetzt:
Code:
mathias@apprentice:~$ ls -l /usr/bin/bluetoothctl 
-rwsr-xr-x 1 root root 222 2009-04-11 11:00 /usr/bin/bluetoothctl
mathias@apprentice:~$

Allerdings bekommt ich immernoch permission denied:
Code:
mathias@apprentice:~$ id
uid=1000(mathias) gid=1000(mathias) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),111(netdev),116(powerdev),1000(mathias)
mathias@apprentice:~$ bluetoothctl off
off
/usr/bin/bluetoothctl: line 10: /sys/devices/platform/thinkpad_acpi/bluetooth_enable: Permission denied
mathias@apprentice:~$

Ich verstehe nicht wieso ... Sollte doch eigentlich also root laufen!?!?!

cu
serow
 
Solange dein Skript nirgendwo root-Rechte annimmt, ist es logisch, dass du auch keine root-Rechte hast beim Ausführen der Befehle. Das SUID-Flag macht nur Sinn, wenn das damit versehene Programm auch setuid()-Aufrufe nutzt. Du wirst also um sudo nicht herum kommen, wenn es unbedingt ein Shell-Skript sein muss.
 
Es kann auch Perl sein. Wie mache ich das dann in Perl? Bin noch nicht lange mit Perl vertraut.

Was sind setuid Aufrufe?

cu
serow
 
setuid()-Aufrufe sind Systemaufrufe zum Ändern der aktuellen UID. Damit ein Programm diesen Systemruf nutzen kann, muss es das setuid-Flag haben. Bei Perl kann man es mit dem sogenannten setuid-Perl machen. Ein Beispiel dazu hatte ich mal im Thread -> zu SUID <- gepostet.
 
Jetzt, wo das Problem erfolgreich gelöst wurde, kann ich mal nach herzenslust klugscheißen :D.

Das SUID-Flag macht nur Sinn, wenn das damit versehene Programm auch setuid()-Aufrufe nutzt.
Ähmm, nein. Bei einem mit SUID-Bit versehenen Executable wird die effektive UID durch die des Besitzers der Executable ersetzt; setuid(2) setzt nur die effektive UID, und ist deshalb, bei solchen Vorhaben, relativ sinnlos (bzw. unnötig redundant) .

Das erklärt aber noch nicht, warum Serow's Script nicht funktioniert. Eigentlich sollte es ja funktionieren,
aber es wird ja nicht das Script ausgeführt, *sondern* der Interpreter (bash)!
Und der ist _NICHT_ suid! (Wäre ja auch selten dämlich bash SUID-root zu haben...).

Als Beispiel, um die Theorie ein bisschen greifbarer zu machen ;):
Code:
$ id
uid=1000 gid=1000
$ cat > id.sh <<EOF
#!/bin/bash -p
id
EOF
$ sudo chown root:root id.sh
$ sudo chmod 4755 id.sh
$ ./id.sh
uid=1000 gid=1000
// Aha, SUID bei dem sript bringt nichts.. (wussten wir schon, aber egal...)
// probieren wir was anderes:
$ sudo chmod 4755 /bin/bash
$ ./id.sh
uid=1000 gid=1000 euid=0 
// die effektive UID ist also 0, hmm, was könnten wir damit jetzt bloss alles machen..
// (dient nur zur Verdeutlichung , dass wir auch wirklich root-Privilegien haben)
$ /bin/bash -p -c 'tail -1 /etc/shadow' 
tcpdump:!:14330:0:99999:7:::
// wichtig! folgende zeile nicht vergessen...
$ sudo chmod 755 /bin/bash
Anmerkung: die Option "-p" wird benötigt, weil bash ansonsten seine Privilegien wieder abgibt ("man 1 bash" für näheres).


grüße
 
Und dann werfen wir mal einen Blick in die Quelltexte der Bash und was finden wir dort?

Code:
/* Is this shell running setuid? */
static int running_setuid;
...
  running_setuid = uidget ();
...
  if (running_setuid && privileged_mode == 0)
    disable_priv_mode ();
...
  setuid (current_user.uid);
  setgid (current_user.gid);
...

Es würde die Bash recht wenig stören ob das setuid-Flag gesetzt ist, wenn es keine entsprechenden setuid-Calls gäbe.

Edit: Im übrigen muss bei Serows Skript nicht der Interpreter mit root-Rechten laufen, sondern die echo-Befehle.
 
Es würde die Bash recht wenig stören ob das setuid-Flag gesetzt ist, wenn es keine entsprechenden setuid-Calls gäbe.
Es würde die Bash recht wenig stören, ob das SUID-Flag gesetzt ist, wenn es nicht seine Privilegien droppen wollte.

Wie bereits erwähnt, droppt bash seine Privilegien, wenn nicht der "-p"-Switch übergeben wird. Das ist der einzige Grund, warum bash setuid(2) in seinem Code hat. Um seine Privilegein zu droppen. Nicht mehr und auch nicht weniger.

grüße

Edit:
Edit: Im übrigen muss bei Serows Skript nicht der Interpreter mit root-Rechten laufen, sondern die echo-Befehle.
Nein, ">" wird von dem Interpreter (bash) interpretiert. Ergo muss der Interpreter als root laufen; kann man auch schön an der Fehlermeldung erkennen:
Code:
/usr/bin/bluetoothctl: line 10: /sys/devices/platform/thinkpad_acpi/bluetooth_enable: Permission denied
 
Stimmt, hab das gerade mal mit einem Test-Programm ausprobierte. Da hast du wohl recht. Dieses Verhalten beim setuid-Flag war mir bisher so nie bewusst. Wieder ein Grund mehr, warum man Linux besser nur mit RBAC (oder garnicht) nutzen sollte. ;)
 
Zurück
Oben