chmod +s
-
Hallo,
habe da ein Verständnisproblem.
$ chown user1:user1 a.out $ chmod +s a.out $ ls -l a.out -rwsr-sr-x 1 user1 user1 11520 2004-02-19 12:06 a.out
Wenn ich jetzt das Programm als user2 starte, läuft es mit den Gruppenrechten von user2 und nicht von user1.
In dem Testprogramm führe ich ls aus und ich bekomme den Inhalt des Verzeichnises angezeigt, wobei das Verzeichnis so aussieht:$ ls -ld . drwxr-x--- 2 user2 user2 4096 2004-02-19 12:09 .
user1 ist nicht in der Gruppe von user2.
Wieso wird hier die Gruppe vom ausführenden Benutzer "vererbt"?
-
Wie testest Du das?
uo@uo tmp $ cat foo.c #include <stdio.h> #include <unistd.h> int main(void) { printf("uid: %i, gid: %i\n", getuid(), getgid()); printf("euid: %i, egid: %i\n", geteuid(), getegid()); } uo@uo tmp $ gcc foo.c uo@uo tmp $ sudo chown apache:apache a.out uo@uo tmp $ sudo chmod +s a.out uo@uo tmp $ ls -l a.out -rwsr-sr-x 1 apache apache 7309 Feb 19 15:07 a.out uo@uo tmp $ ./a.out uid: 1000, gid: 100 euid: 81, egid: 81
Du siehst, der Code laeuft unter Gruppe 81.
-
Ja, die Ausgaben bekomme ich auch. Aber wieso gibt mir der ls-Aufruf in folgendem Beispiel kein "permission denied", obwohl nur root und die Gruppe root lesen darf?
root@denis:~/tmp$ cat a.c int main() { printf("uid: %i, gid: %i\n", getuid(), getgid()); printf("euid: %i, egid: %i\n", geteuid(), getegid()); printf("\n--- ls ---\n"); system("ls"); } root@denis:~/tmp$ gcc a.c root@denis:~/tmp$ chown denis:denis a.out root@denis:~/tmp$ chmod +s a.out root@denis:~/tmp$ chmod ug=rwx,o= . root@denis:~/tmp$ ls -ld a.out . drwxrwx--- 2 root root 4096 2004-02-19 16:16 . -rwsr-sr-x 1 denis denis 12084 2004-02-19 16:16 a.out root@denis:~/tmp$ ./a.out uid: 0, gid: 0 euid: 1000, egid: 1000 --- ls --- a.c a.out
Wenn ich auch der Gruppe root die Lese-Berechtigung für das Verzeichnis entziehe, bekomme ich auch das erwartete permission denied.
-
Ergaenze das Programm mal um ein
system("id")
und Du siehst: id wird wieder als root ausgefuehrt.
Warum das? system() verhaelt sich per Definition wie fork() gefolgt von execl(<shell path>, "sh", "-c", command, (char *)0);. sh ist auf den meisten Linux-Systemen die Bash 2, und diese setzt uid und gid auf die gespeicherten Werte zurueck, bevor sie den Befehl ausfuehrt.
-
Ah danke, jetzt verstehe ich.
Ich wusste nicht, dass ein Prozess die Möglichkeit hat, seine effektive userid einfach wieder zurück zu setzen.
Ursprünglich wollte ich damit die Rechte eines Programms einschränken, aber so ist dieses uid/gid-Bit ja nur zu gebrauchen, wenn man einem Programm mehr Rechte geben will
-
Schau Dir mal setresuid() an. Damit kannst Du im aufgerufenen Prozess alle Spuren der alten uid loeschen. Wenn Du keinen Zugriff auf den Source des zu beschraenkenden Programms hast, musst Du einen kleinen Wrapper schreiben.