2009-08-03 6 views
5

Gibt es eine Möglichkeit, UID/GID nur eines Threads in einem Multithread-Prozess zu ändern?Ändern UID/GID nur eines Threads in Linux

Der Grund dafür ist das Schreiben einer Datei-Serving-Anwendung - die ACLs und Kontingente sind nicht erzwungen, es sei denn die UID/GID des Aufrufers ist auf den richtigen Benutzer eingestellt, neue Dateien/Verzeichnisse werden nicht mit der richtigen UID/GID erstellt usw.

Die Netzwerkanwendungen können sich normalerweise am Anfang selbst fork() und jede Benutzeranforderung in einem separaten Prozess bearbeiten. Wenn gemeinsame Daten benötigt werden, müssen sie eine Art gemeinsamen Speicher durchlaufen. B. Das FUSE (Linux User Filesystem) verwendet standardmäßig Multithreading und in Verbindung mit Python-Bindings wäre es nicht praktisch, ein Forking-Modell zu verwenden.

Die 'konsistente' UID für einen ganzen Prozess scheint nach dem POSIX-Standard zu sein, aber alte Linuxes folgten nicht dem POSIX und erlaubten verschiedene UIDs für verschiedene Threads. Die neuen Kernel scheinen POSIX zu folgen, gibt es eine Möglichkeit, das alte "kaputte" Verhalten zuzulassen?

Antwort

5

Haben Sie überprüft, ob setfsuid()/setfsgid() per-Thread oder pro-Prozess sind? Sie sind speziell für diesen Anwendungsfall (Dateiserver) konzipiert.

+0

Das ist besser - ich habe überprüft und überraschend herausgefunden, dass sie wirklich per-thread sind. Dies wäre wahrscheinlich der bevorzugte Weg. Allerdings - der Grund, warum ich es nicht getestet habe, ist, dass quota() und access() nicht funktionieren. Andere Dinge funktionieren - also ist das wahrscheinlich ein Linux-Bug. – ondra

+0

Ja, das klingt wie ein Fehler, da die Kommentare im Kernel-Code für sys_setfsuid() speziell access() erwähnen ... – caf

+0

@Ondrej, bitte poste den Code (oder einen Link dazu), was zeigt, dass 'fsuid' ist , im Gegensatz zu anderen UID/GID-Konstrukten, pro Thread und nicht pro Prozess. Bitte geben Sie auch Ihre Kernel- und glibc-Versionen sowie Ihre Threading-Implementierung an (NPTL, LinuxThreads, OndrejThreads usw.). – pilcrow

5

Um die UID nur für einen Thread zu ändern, müssen Sie den Syscall direkt verwenden: syscall (SYS_setresuid, ...); Die libc-Funktion setresuid() synchronisiert sie für alle Threads (mit einem Signal, das sie an alle Threads sendet)!