2009-08-03 10 views
5

C'è un modo per modificare UID/GID solo di un thread in un processo con multithreading?Modifica UID/GID solo di un thread in Linux

Il motivo di ciò è la scrittura di un'applicazione di archiviazione file: le ACL e la quota non vengono applicate a meno che l'uid/gid del chiamante non sia impostato sull'utente corretto, i nuovi file/directory non vengono creati con uid/gid corretti ecc.

Le applicazioni di rete possono in genere fork() all'inizio e elaborare ogni richiesta dell'utente in un processo separato. Se c'è bisogno di dati condivisi, deve passare attraverso una sorta di memoria condivisa. Tuttavia, ad es. il FUSE (linux user filesystem) usa per impostazione predefinita il multithreading e, in combinazione con i collegamenti Python, non sarebbe pratico provare a utilizzare un modello di fork.

L'UID "coerente" per un intero processo sembra essere conforme allo standard POSIX, tuttavia i vecchi Linux non seguivano il POSIX e consentivano uidi diversi per thread diversi. I nuovi kernel sembrano seguire POSIX, c'è un modo per consentire il vecchio comportamento "rotto"?

risposta

5

Avete controllato se setfsuid()/setfsgid() sono per-thread o per-process? Sono progettati specificamente per questo caso d'uso (file server).

+0

Questo è meglio - ho controllato e sorprendentemente scoperto che sono davvero per-thread. Questo probabilmente sarebbe il modo preferito. Tuttavia, il motivo per cui non ho provato è che quota() e access() non funzionano. Altre cose funzionano, quindi questo è probabilmente un bug di Linux. – ondra

+0

Sì, sembra un bug, dal momento che i commenti nel codice del kernel per sys_setfsuid() menzionano specificamente access() ... – caf

+0

@Ondrej, si prega di inviare un codice (o un collegamento ad esso), dimostrando che 'fsuid' è , a differenza di altri costrutti UID/GID, per thread e non per processo. Specifica anche le versioni del kernel e degli glibc, nonché l'implementazione del threading (NPTL, LinuxThreads, OndrejThreads, ecc.). – pilcrow

5

Per modificare l'uid solo per un thread è necessario utilizzare syscall direttamente: syscall (SYS_setresuid, ...); La funzione libc setresuid() la sincronizzerà per tutti i thread (usando un singolo che invia a tutti i thread)!

Problemi correlati