Aggiunte seteuid, setreuid, setresuid
[gapil.git] / prochand.tex
index ef6c064a0552dcbfa657378321a7ce663b38fbfb..9eb7912a0ddd47eb9c4a3b8b2db8ecafca1156d8 100644 (file)
@@ -377,6 +377,8 @@ periodo di attesa.
 Se eseguiamo il comando senza specificare attese (come si può notare in
 \texttt{\small 17--19} i valori di default specificano di non attendere),
 otterremo come output sul terminale:
 Se eseguiamo il comando senza specificare attese (come si può notare in
 \texttt{\small 17--19} i valori di default specificano di non attendere),
 otterremo come output sul terminale:
+
+\footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest 3
 Process 1963: forking 3 child
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest 3
 Process 1963: forking 3 child
@@ -393,6 +395,7 @@ Child 3, parent 1963, exiting
 Spawned 3 child, pid 1966 
 Go to next child 
 \end{verbatim} %$
 Spawned 3 child, pid 1966 
 Go to next child 
 \end{verbatim} %$
+\normalsize
 
 Esaminiamo questo risultato: una prima conclusione che si può trarre è non si
 può dire quale processo fra il padre ed il figlio venga eseguito per
 
 Esaminiamo questo risultato: una prima conclusione che si può trarre è non si
 può dire quale processo fra il padre ed il figlio venga eseguito per
@@ -431,6 +434,8 @@ Un secondo aspetto molto importante nella creazione dei processi figli 
 quello dell'interazione dei vari processi con i file; per illustrarlo meglio
 proviamo a redirigere su un file l'output del nostro programma di test, quello
 che otterremo è:
 quello dell'interazione dei vari processi con i file; per illustrarlo meglio
 proviamo a redirigere su un file l'output del nostro programma di test, quello
 che otterremo è:
+
+\footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest 3 > output
 [piccardi@selidor sources]$ cat output
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest 3 > output
 [piccardi@selidor sources]$ cat output
@@ -457,6 +462,7 @@ Go to next child
 Spawned 3 child, pid 1970 
 Go to next child 
 \end{verbatim}
 Spawned 3 child, pid 1970 
 Go to next child 
 \end{verbatim}
+\normalsize
 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
@@ -660,6 +666,8 @@ avr
 di terminazione.  Come verifica di questo comportamento possiamo eseguire il
 comando \cmd{forktest} imponendo a ciascun processo figlio due
 secondi di attesa prima di uscire, il risultato è:
 di terminazione.  Come verifica di questo comportamento possiamo eseguire il
 comando \cmd{forktest} imponendo a ciascun processo figlio due
 secondi di attesa prima di uscire, il risultato è:
+
+\footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest -c2 3
 Process 1972: forking 3 child
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest -c2 3
 Process 1972: forking 3 child
@@ -676,6 +684,7 @@ Go to next child
 Child 2, parent 1, exiting
 Child 1, parent 1, exiting
 \end{verbatim}
 Child 2, parent 1, exiting
 Child 1, parent 1, exiting
 \end{verbatim}
+\normalsize
 come si può notare in questo caso il processo padre si conclude prima dei
 figli, tornando alla shell, che stampa il prompt sul terminale: circa due
 secondi dopo viene stampato a video anche l'output dei tre figli che
 come si può notare in questo caso il processo padre si conclude prima dei
 figli, tornando alla shell, che stampa il prompt sul terminale: circa due
 secondi dopo viene stampato a video anche l'output dei tre figli che
@@ -705,6 +714,8 @@ condizione: lanciamo il comando \cmd{forktest} in background, indicando al
 processo padre di aspettare 10 secondi prima di uscire; in questo caso, usando
 \cmd{ps} sullo stesso terminale (prima dello scadere dei 10 secondi)
 otterremo:
 processo padre di aspettare 10 secondi prima di uscire; in questo caso, usando
 \cmd{ps} sullo stesso terminale (prima dello scadere dei 10 secondi)
 otterremo:
+
+\footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ps T
   PID TTY      STAT   TIME COMMAND
 \begin{verbatim}
 [piccardi@selidor sources]$ ps T
   PID TTY      STAT   TIME COMMAND
@@ -715,6 +726,7 @@ otterremo:
   571 pts/0    Z      0:00 [forktest <defunct>]
   572 pts/0    R      0:00 ps T
 \end{verbatim} %$
   571 pts/0    Z      0:00 [forktest <defunct>]
   572 pts/0    R      0:00 ps T
 \end{verbatim} %$
+\normalsize 
 e come si vede, dato che non si è fatto nulla per riceverne lo stato di
 terminazione, i tre processi figli sono ancora presenti pur essendosi
 conclusi, con lo stato di zombie e l'indicazione che sono stati terminati.
 e come si vede, dato che non si è fatto nulla per riceverne lo stato di
 terminazione, i tre processi figli sono ancora presenti pur essendosi
 conclusi, con lo stato di zombie e l'indicazione che sono stati terminati.
@@ -816,6 +828,7 @@ base del valore specificato tramite la variabile \var{pid}, secondo lo
 specchietto riportato in \ntab:
 \begin{table}[!htb]
   \centering
 specchietto riportato in \ntab:
 \begin{table}[!htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|c|p{10cm}|}
     \hline
     \textbf{Valore} & \textbf{Significato}\\
   \begin{tabular}[c]{|c|p{10cm}|}
     \hline
     \textbf{Valore} & \textbf{Significato}\\
@@ -1387,8 +1400,8 @@ seguono la sematica POSIX che prevede l'esistenza di \textit{saved user id} e
 \headdecl{unistd.h}
 \headdecl{sys/types.h}
 
 \headdecl{unistd.h}
 \headdecl{sys/types.h}
 
-\funcdecl{int setuid(uid\_t uid)} setta l' \textit{user ID} del processo
-corrente.  
+\funcdecl{int setuid(uid\_t uid)} setta l'\textit{user ID} del processo
+corrente.
 
 \funcdecl{int setgid(gid\_t gid)} setta il \textit{group ID} del processo
 corrente.
 
 \funcdecl{int setgid(gid\_t gid)} setta il \textit{group ID} del processo
 corrente.
@@ -1399,7 +1412,9 @@ l'unico errore possibile 
 
 Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
 la prima; la seconda si comporta esattamente allo stesso modo facendo
 
 Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
 la prima; la seconda si comporta esattamente allo stesso modo facendo
-riferimento al \textit{group id} invece che all'\textit{user id}.  
+riferimento al \textit{group id} invece che all'\textit{user id}.  Gli
+eventuali \textit{supplementary group id} non vengono modificati da nessuna
+delle funzioni che tratteremo in questa sezione.
 
 
 L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
 
 
 L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
@@ -1408,22 +1423,13 @@ sistema) allora tutti gli identificatatori (\textit{real}, \textit{effective}
 e \textit{saved}) vengono settati al valore specificato da \var{uid},
 altrimenti viene settato solo l'\textit{effective user id}, e soltanto se il
 valore specificato corrisponde o al \textit{real user id} o al \textit{saved
 e \textit{saved}) vengono settati al valore specificato da \var{uid},
 altrimenti viene settato solo l'\textit{effective user id}, e soltanto se il
 valore specificato corrisponde o al \textit{real user id} o al \textit{saved
-  user id}. Negli altri casi segnalato un errore (con \macro{EPERM}).
+  user id}. Negli altri casi viene segnalato un errore (con \macro{EPERM}).
 
 Come accennato l'uso principale di queste funzioni è quello di poter
 
 Come accennato l'uso principale di queste funzioni è quello di poter
-consentire ad un programma con i bit \acr{suid} o \acr{sgid} settati, di
+consentire ad un programma con i bit \acr{suid} o \acr{sgid} settati di
 riportare l'\textit{effective user id} a quello dell'utente che ha lanciato il
 riportare l'\textit{effective user id} a quello dell'utente che ha lanciato il
-programma, per effettuare il lavoro che non necessita di privilegi aggiuntivi,
-ed eventualmente tornare indietro. 
-
-Occorre però tenere conto che tutto questo non è possibile nel caso di root,
-in tal caso infatti l'esecuzione una \func{setuid} con un \textit{effective
-  user id} uguale a zero comporta il cambiamento di tutti gli identificatori
-associati al processo rendendo impossibile riguadagnare i privilegi di
-amministratore. Questo è l'uso che ne fa \cmd{login} una volta che crea una
-nuova shell per l'utente, ma se si vuole cambiare soltanto l'\textit{effective
-  user id} occorre ricorrere ad altre funzioni (si veda ad esempio
-\secref{sec:proc_seteuid}).
+programma, effettuare il lavoro che non necessita di privilegi aggiuntivi, ed
+eventualmente tornare indietro.
 
 Come esempio per chiarire dell'uso di queste funzioni prediamo quello con cui
 viene gestito l'accesso al file \file{/var/log/utmp}.  In questo file viene
 
 Come esempio per chiarire dell'uso di queste funzioni prediamo quello con cui
 viene gestito l'accesso al file \file{/var/log/utmp}.  In questo file viene
@@ -1447,10 +1453,10 @@ situazione degli identificatori 
 in questo modo, dato che l'\textit{effective group id} è quello giusto, il
 programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo, a
 questo punto il programma può eseguire una \func{setgid(getgid())} per settare
 in questo modo, dato che l'\textit{effective group id} è quello giusto, il
 programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo, a
 questo punto il programma può eseguire una \func{setgid(getgid())} per settare
-l'\textit{effective group id} a quello dell'utente (ed usando il \textit{real
-  group id} 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:
+l'\textit{effective group id} a quello dell'utente (e dato che il \textit{real
+  group id} 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:
 \begin{eqnarray*}
   \label{eq:2}
   \textit{real group id}      &=& \textrm{\acr{gid} (invariato)}  \\
 \begin{eqnarray*}
   \label{eq:2}
   \textit{real group id}      &=& \textrm{\acr{gid} (invariato)}  \\
@@ -1472,13 +1478,114 @@ avr
 \end{eqnarray*}
 consentendo l'accesso a \file{/var/log/utmp}.
 
 \end{eqnarray*}
 consentendo l'accesso a \file{/var/log/utmp}.
 
+Occorre però tenere conto che tutto questo non è possibile con root, in tal
+caso infatti l'esecuzione una \func{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 \cmd{login} una volta che crea una nuova shell per l'utente; ma quando si
+vuole cambiare soltanto l'\textit{effective user id} del processo per cedere i
+privilegi occorre ricorrere ad altre funzioni (si veda ad esempio
+\secref{sec:proc_seteuid}).
+
+
+\subsection{Le funzioni \func{setreuid} e \func{setresuid}}
+\label{sec:proc_setreuid}
+
+Queste due funzioni derivano da BSD che non supportando\footnote{almeno fino
+  alla versione 4.3+BSD TODO, verificare e aggiornare la nota} i \textit{saved
+  id} le usava per poter scambiare fra di loro effective e real id. I
+prototipi sono:
+
+\begin{functions}
+\headdecl{unistd.h}
+\headdecl{sys/types.h}
+
+\funcdecl{int setreuid(uid\_t ruid, uid\_t euid)} setta il \textit{real user
+  ID} e l'\textit{effective user ID} del processo corrente ai valori
+specificati da \var{ruid} e \var{euid}.
+  
+\funcdecl{int setregid(gid\_t rgid, gid\_t egid)} setta il \textit{real group
+  ID} e l'\textit{effective group ID} del processo corrente ai valori
+specificati da \var{rgid} e \var{egid}.
+
+Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
+l'unico errore possibile è \macro{EPERM}. 
+\end{functions}
+
+Gli utenti normali possono settare gli identificatori soltanto ai valori del
+loro \textit{effective id} o \textit{real id}, valori diversi comportano il
+fallimento della chiamata; l'amministratore invece può specificare un valore
+qualunque. Specificando -1 come valore l'identificatore corrispondente viene
+lasciato inalterato.
+
+Con queste funzione si possono scambiare fra loro \textit{real id} e
+\textit{effective id}, e pertanto è possibile implementare un comportamento
+simile a quello visto in precedenza per \func{setgid}, cedendo i privilegi con
+un primo scambio, e recuperandoli, eseguito il lavoro non privilegiato, con un
+secondo scambio.
+
+In questo caso però occorre porre molta attenzione quando si creano nuovi
+processi nella fase intermedia, questi infatti avranno un \textit{real id}
+privilegiato, che dovrà essere esplicitamente eliminato prima di porre in
+esecuzione un nuovo processo, che altrimenti potrebbero riottenere detti
+privilegi.
+
+Come accennato le funzioni derivano da un'implementazione che non prevedeva la
+presenza di \textit{saved id}, per evitare che questo possa essere
+riutilizzato nella fase intermedia per recuperare un \textit{effective id}
+(privilegiato) originale, tutte le volte che uno degli identificatori viene
+modificato da una di queste funzioni, il \textit{saved id} viene sempre
+settato al nuovo valore che viene ad assumere l'\textit{effective id}.
+
 
 \subsection{Le funzioni \func{seteuid} e \func{setegid}}
 \label{sec:proc_seteuid}
 
 
 \subsection{Le funzioni \func{seteuid} e \func{setegid}}
 \label{sec:proc_seteuid}
 
+Queste funzioni sono un'estensione allo standard POSIX.1 (ma sono comunque
+supportate dalla maggior parte degli unix) usate per cambiare gli
+\textit{effective id}; i loro prototipi sono:
 
 
-\subsection{Le funzioni \func{setreuid} e \func{setresuid}}
-\label{sec:proc_setreuid}
+\begin{functions}
+\headdecl{unistd.h}
+\headdecl{sys/types.h}
+
+\funcdecl{int seteuid(uid\_t uid)} setta l'\textit{effective user ID} del
+processo corrente.
+
+\funcdecl{int setegid(gid\_t gid)} setta l'\textit{effective group ID} del
+processo corrente.
+
+Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
+l'unico errore possibile è \macro{EPERM}. 
+\end{functions}
+
+
+
+
+\subsection{Le funzioni \func{setresuid} e \func{setresgid}}
+\label{sec:proc_setresuid}
+
+Queste due funzioni sono una estensione introdotta in Linux dal kernel 2.1.44,
+e permettono un completo controllo su tutti gli identificatori (\textit{real},
+\textit{effective} e \textit{saved}), i prototipi sono:
+
+\begin{functions}
+\headdecl{unistd.h}
+\headdecl{sys/types.h}
+
+\funcdecl{int setresuid(uid\_t ruid, uid\_t euid, uid\_t suid)} setta il
+\textit{real user ID}, l'\textit{effective user ID} e il \textit{saved user
+  ID} del processo corrente ai valori specificati rispettivamente da
+\var{ruid}, \var{euid} e \var{suid}.
+  
+\funcdecl{int setresgid(gid\_t rgid, gid\_t egid, gid\_t sgid)} setta il
+\textit{real group ID}, l'\textit{effective group ID} e il \textit{saved group
+  ID} del processo corrente ai valori specificati rispettivamente da
+\var{rgid}, \var{egid} e \var{sgid}.
+
+Le funzioni restituiscono 0 in caso di successo e -1 in caso di fallimento:
+l'unico errore possibile è \macro{EPERM}. 
+\end{functions}
 
 
 \subsection{Le funzioni \func{setfsuid} e \func{setfsgid}}
 
 
 \subsection{Le funzioni \func{setfsuid} e \func{setfsgid}}