[Avanti]  [Indietro]  [Su]  

3.3.2 Le funzioni setuid e setgid

Le due funzioni che vengono usate per cambiare identità (cioè utente e gruppo di appartenenza) ad un processo sono rispettivamente setuid e setgid; come accennato in sez. 3.3.1 in Linux esse seguono la semantica POSIX che prevede l'esistenza dell'user-ID salvato e del group-ID salvato; i loro prototipi sono:

Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento: l'unico errore possibile è EPERM.

Il funzionamento di queste due funzioni è analogo, per cui considereremo solo la prima; la seconda si comporta esattamente allo stesso modo facendo riferimento al group-ID invece che all'user-ID. Gli eventuali group-ID supplementari non vengono modificati.

L'effetto della chiamata è diverso a seconda dei privilegi del processo; se l'user-ID effettivo è zero (cioè è quello dell'amministratore di sistema) allora tutti gli identificatori (real, effective e saved) vengono impostati al valore specificato da uid, altrimenti viene impostato solo l'user-ID effettivo, e soltanto se il valore specificato corrisponde o all'user-ID reale o all'user-ID salvato. Negli altri casi viene segnalato un errore (con EPERM).

Come accennato l'uso principale di queste funzioni è quello di poter consentire ad un programma con i bit suid o sgid impostati (vedi sez. 5.3.2) di riportare l'user-ID effettivo a quello dell'utente che ha lanciato il programma, effettuare il lavoro che non necessita di privilegi aggiuntivi, ed eventualmente tornare indietro.

Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui viene gestito l'accesso al file /var/log/utmp. In questo file viene registrato chi sta usando il sistema al momento corrente; chiaramente non può essere lasciato aperto in scrittura a qualunque utente, che potrebbe falsificare la registrazione. Per questo motivo questo file (e l'analogo /var/log/wtmp su cui vengono registrati login e logout) appartengono ad un gruppo dedicato (utmp) ed i programmi che devono accedervi (ad esempio tutti i programmi di terminale in X, o il programma screen che crea terminali multipli su una console) appartengono a questo gruppo ed hanno il bit sgid impostato.

Quando uno di questi programmi (ad esempio xterm) viene lanciato, la situazione degli identificatori è la seguente:

   group -ID reale  =  gid (del chiamante)
group -ID effettivo  =  utmp

 group -ID salvato  =  utmp
in questo modo, dato che il group-ID effettivo è quello giusto, il programma può accedere a /var/log/utmp in scrittura ed aggiornarlo. A questo punto il programma può eseguire una setgid(getgid()) per impostare il group-ID effettivo a quello dell'utente (e dato che il group-ID reale corrisponde la funzione avrà successo), in questo modo non sarà possibile lanciare dal terminale programmi che modificano detto file, in tal caso infatti la situazione degli identificatori sarebbe:
   group-ID  reale  =  gid (invariato)

group-ID  effettivo  =  gid
 group-ID  salvato  =  utmp  (invariato)
e ogni processo lanciato dal terminale avrebbe comunque gid come group-ID effettivo. All'uscita dal terminale, per poter di nuovo aggiornare lo stato di /var/log/utmp il programma eseguirà una setgid(utmp) (dove utmp è il valore numerico associato al gruppo utmp, ottenuto ad esempio con una precedente getegid), dato che in questo caso il valore richiesto corrisponde al group-ID salvato la funzione avrà successo e riporterà la situazione a:
   group-ID  reale  =  gid (invariato)
group-ID  effettivo  =  utmp
 group-ID  salvato  =  utmp  (invariato)
consentendo l'accesso a /var/log/utmp.

Occorre però tenere conto che tutto questo non è possibile con un processo con i privilegi di amministratore, in tal caso infatti l'esecuzione di una setuid comporta il cambiamento di tutti gli identificatori associati al processo, rendendo impossibile riguadagnare i privilegi di amministratore. Questo comportamento è corretto per l'uso che ne fa login una volta che crea una nuova shell per l'utente; ma quando si vuole cambiare soltanto l'user-ID effettivo del processo per cedere i privilegi occorre ricorrere ad altre funzioni (si veda ad esempio sez. 3.3.4).


[Avanti]  [Indietro]  [Su]  
© 2000-2003 Simone Piccardi
Pubblicazione web curata da Mirko Maischberger