2010-02-16 12 views
11

Sto provando a fare la cosa sicura e ho un programma che deve essere eseguito come root per eliminare i suoi privilegi quando non ne ha bisogno. Funziona bene se ho chmod il mio binario con il bit SUID e lo faccio appartenere a root, poiché ora ho UID = qualche utente e EUID = root, quindi posso usare seteuid(0) e seteuid(getuid()) rispettivamente per aumentare e rilasciare i diritti di amministratore.Come utilizzare setuid() da root per diventare utente, con la possibilità di diventare nuovamente root in seguito?

Ma se uso sudo invece di impostare SUID, quindi UID == EUID == 0, e quindi chiamare seteuid(getuid()) non avrà alcun effetto. E non posso semplicemente cambiare lo UID con un certo valore da qualche utente casuale, dato che la pagina man setuid() afferma chiaramente che se viene chiamata da un programma in esecuzione come root, si perdono i privilegi per sempre, senza alcuna speranza di farli tornare indietro.

Quindi, come posso fare in modo che il mio programma perda temporaneamente i suoi privilegi quando viene eseguito utilizzando sudo?

+0

È necessario tornare all'UID dell'utente che ha eseguito 'sudo' o solo a un utente casuale, con privilegi inferiori? –

+0

Mi accontenterò di "nessuno". ma se conosci un modo semplice per ottenere il chiamante sudo, sono interessato. – Florian

+3

meh, è ​​facile, solo bisogno di 'getenv (" SUDO_UID ")'. – Florian

risposta

10

seteuid(some random uid) per rilasciare i privilegi, seteuid(0) per riaverli, quando è in esecuzione come root.

+3

Ovviamente - questo lascia il problema di ottenere l'UID originale dell'utente che ha chiamato 'sudo' - se l'OP deve tornare a quell'utente? –

+0

Ovviamente, c'è la possibilità che l'UID casuale che si passa sia l'UID del sysadmin. – immibis

+0

sudo crea variabili d'ambiente contenenti l'UID e il GID dell'utente chiamante. Puoi passare a "nessuno" leggere la variabile e passare a quell'utente. Non consiglio di leggere le variabili d'ambiente come root. "nessuno" è un account limitato presente sulla maggior parte dei sistemi Unix. – wheredidthatnamecomefrom

6

Sembra seteuid (x) dovrebbe funzionare a cadere e re-raise privs ...

$ cat > t12.c 
#include <stdio.h> 
#include <unistd.h> 

void p(void) { printf("euid=%4d uid=%4d\n", geteuid(), getuid()); } 

int main(void) { p(); seteuid(100); p(); seteuid(0); p(); return 0; } 
$ cc -Wall t12.c 
$ sudo chown root a.out && sudo chmod 4555 a.out 
$ sudo ./a.out 
euid= 0 uid= 0 
euid= 100 uid= 0 
euid= 0 uid= 0 
$ ./a.out 
euid= 0 uid= 501 
euid= 100 uid= 501 
euid= 0 uid= 501 
$ 
+0

Come ci si assicura che uid = 100 non sia nel gruppo sudoers? – dashesy

+0

Ciò conta solo per sudo stesso. L'unico privilegio speciale che il gruppo sudoers concede è la possibilità di usare il comando sudo. Non fa in modo che l'id utente abbia accesso root. – wheredidthatnamecomefrom

1

fork() prima di cadere privilegi. Attendere l'attività genitore fino a quando il bambino con privilegi ridotti viene fatto, quindi riprendere in parent con root.

seteuid non è portatile per tutti i dispositivi e ha anche altri inconvenienti.

Problemi correlati