Finiti file temporanei e iniziata chroot, inserita sezione sullo scheduler
[gapil.git] / filedir.tex
index 355348627fd4cbbdc7384b9c1d309fcce328f6b2..5d1c21e5e475680fa0735abaa8a9c27242b1847d 100644 (file)
@@ -718,9 +718,155 @@ creare il file dopo aver controllato che questo non esista, nel momento fra il
 controllo e la creazione si ha giusto lo spazio per una \textit{race
   condition} (si ricordi quanto visto in \secref{sec:proc_race_cond}).
 
 controllo e la creazione si ha giusto lo spazio per una \textit{race
   condition} (si ricordi quanto visto in \secref{sec:proc_race_cond}).
 
-Per questo motivo il kernel le \acr{glibc} provvedono una serie di funzioni da
-utilizzare per la gestione dei file temporanei.
+Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei,
+di cui si abbia certezza di unicità (al momento della generazione); la prima
+di queste funzioni è \func{tmpnam} il cui prototipo è:
+\begin{prototype}{stdio.h}{char *tmpnam(char *string)}
+  Restituisce il puntatore ad una stringa contente un nome di file valido e
+  non esistente al momento dell'invocazione. 
+
+  \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
+  \macro{NULL} in caso di fallimento. Non sono definiti errori.}
+\end{prototype}
+\noindent se si è passato un puntatore \param{string} non nullo questo deve
+essere di dimensione \macro{L\_tmpnam} (costante definita in \file{stdio.h},
+come \macro{P\_tmpdir} e \macro{TMP\_MAX}) ed il nome generato vi verrà
+copiato automaticamente; altrimenti il nome sarà generato in un buffer statico
+interno che verrà sovrascritto ad una chiamata successiva.  Successive
+invocazioni della funzione continueranno a restituire nomi unici fino ad un
+massimo di \macro{TMP\_MAX} volte. Al nome viene automaticamente aggiunto come
+prefisso la directory specificata da \macro{P\_tmpdir}.
+
+Di questa funzione esiste una versione rientrante, \func{tmpnam\_r}, che non
+fa nulla quando si passa \macro{NULL} come parametro. Una funzione simile,
+\func{tempnam}, permette di specificare un prefisso per il file
+esplicitamente, il suo prototipo è:
+\begin{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)}
+  Restituisce il puntatore ad una stringa contente un nome di file valido e
+  non esistente al momento dell'invocazione.
+
+  \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
+  \macro{NULL} in caso di fallimento, \var{errno} viene settata a
+  \macro{ENOMEM} qualora fallisca l'allocazione della stringa.}
+\end{prototype}
 
 
+La funzione alloca con \code{malloc} la stringa in cui resituisce il nome, per
+cui è sempre rientrante, occorre però ricordarsi di disallocare il puntatore
+che restituisce.  L'argomento \param{pfx} specifica un prefisso di massimo 5
+caratteri per il nome provvisorio. La funzione assegna come directory per il
+file temporaneo (verificando che esista e sia accessibili), la prima valida
+delle seguenti:
+\begin{itemize*}
+\item La variabile di ambiente \macro{TMPNAME} (non ha effetto se non è
+  definita o se il programma chiamante è \acr{suid} o \acr{sgid}, vedi
+  \secref{sec:file_suid_sgid}).
+\item il valore dell'argomento \param{dir} (se diverso da \macro{NULL}).
+\item Il valore della costante \macro{P\_tmpdir}.
+\item la directory \file{/tmp}.
+\end{itemize*}
+
+In ogni caso, anche se la generazione del nome è casuale, ed è molto difficile
+ottere un nome duplicato, nulla assicura che un altro processo non possa avere
+creato, fra l'ottenimento del nome e l'apertura del file, un altro file con lo
+stesso nome; per questo motivo quando si usa il nome ottenuto da una di queste
+funzioni occorre sempre aprire il nuovo file in modalità di esclusione (cioè
+con l'opzione \macro{O\_EXCL} per i file descriptor o con il flag \code{x} per
+gli stream) che fa fallire l'apertura in caso il file sia già esistente.
+
+Per evitare di dovere effettuare a mano tutti questi controlli, lo standard
+POSIX definisce la funzione \func{tempfile}, il cui prototipo è:
+\begin{prototype}{stdio.h}{FILE *tmpfile (void)}
+  Restituisce un file temporaneo aperto in lettura/scrittura.
+  
+  \bodydesc{La funzione ritorna il puntatore allo stream associato al file
+    temporaneo in caso di successo e \macro{NULL} in caso di errore, nel qual
+    caso \var{errno} viene settata a
+    \begin{errlist}
+    \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+    \item[\macro{EEXIST}] Non è stato possibile generare un nome univoco.
+    \end{errlist}
+    ed inoltre \macro{EFAULT}, \macro{EMFILE}, \macro{ENFILE}, \macro{ENOSPC},
+    \macro{EROFS} e \macro{EACCESS}.}
+\end{prototype}
+\noindent restituisce direttamente uno stream già aperto (in modalità
+\code{r+b}, si veda \secref{sec:file_fopen}) e pronto per l'uso che viene
+automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
+standard non specifica in quale directory verrà aperto il file, ma \acr{glibc}
+prima tentano con \macro{P\_tmpdir} e poi con \file{/tmp}. Questa funzione è
+rientrante e non soffre di problemi di \textit{race condition}.
+
+Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
+caso si possono usare le vecchie funzioni \func{mktemp} e \func{mkstemp} che
+modificano una stringa di input che serve da modello e che deve essere
+conclusa da 6 caratteri \code{X} che verranno sostituiti da un codice
+unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale,
+il suo prototipo è:
+\begin{prototype}{stlib.h}{char *mktemp(char *template)}
+  Genera un filename univoco sostituendo le \code{XXXXXX} finali di
+  \param{template}.
+  
+  \bodydesc{La funzione ritorna il puntatore \param{template} in caso di
+    successo e \macro{NULL} in caso di errore, nel qual caso \var{errno} viene
+    settata a:
+    \begin{errlist}
+    \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+    \end{errlist}}
+\end{prototype}
+\noindent dato che \param{template} deve poter essere modificata dalla
+funzione non si può usare una stringa costante.  Tutte le avvertenze riguardo
+alle possibili \textit{race condition} date per \func{tmpnam} continuano a
+valere; inoltre in alcune vecchie implementazioni il valore di usato per
+sostituire le \code{XXXXXX} viene formato con il \acr{pid} del processo più
+una lettera, il che mette a disposizione solo 26 possibilità, e rende il nome
+temporaneo facile da indovinare. Per tutti questi motivi la funzione è
+deprecata e non dovrebbe mai essere usata.
+
+
+
+La seconda funzione, \func{mkstemp} è sostanzialmente equivalente a
+\func{tmpfile}, ma restituisce un file descriptor invece di uno stream; il suo
+prototipo è:
+\begin{prototype}{stlib.h}{int mkstemp(char *template)}
+  Genera un file temporaneo con un nome ottenuto sostituendo le \code{XXXXXX}
+  finali di \param{template}.
+  
+  \bodydesc{La funzione ritorna il file descriptor in caso successo e
+    -1 in caso di errore, nel qual caso \var{errno} viene settata a:
+    \begin{errlist}
+    \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+    \item[\macro{EEXIST}] non è riuscita a creare un file temporano, il
+      contenuto di \param{template} è indefinito.
+    \end{errlist}}
+\end{prototype}
+\noindent come per \func{mktemp} \param{template} non può essere una stringa
+costante. La funzione apre un file in lettura/scrittura con la funzione
+\func{open}, usando l'opzione \macro{O\_EXCL} (si veda
+\secref{sec:file_open}), in questo modo al ritorno della funzione si ha la
+certezza di essere i soli utenti del file. I permessi sono settati al valore
+\code{0600}\footnote{questo è vero a partire dalle \acr{glibc} 2.0.7, le
+  versioni precedenti delle \acr{glibc} e le vecchie \acr{libc5} e \acr{libc4}
+  usavano il valore \code{0666} che permetteva a chiunque di leggere i
+  contenuti del file.} (si veda \secref{sec:file_perm_overview}).
+
+In OpenBSD è stata introdotta un'altra funzione\footnote{introdotta anche in
+  Linux a partire dalle \acr{glibc} 2.1.91.} simile alle precedenti,
+\func{mkdtemp}, che crea una directory temporanea; il suo prototipo è:
+\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
+  Genera una directory temporaneo il cui nome è ottenuto sostituendo le
+  \code{XXXXXX} finali di \param{template}.
+  
+  \bodydesc{La funzione ritorna il puntatore al nome della directory in caso
+    successo e \macro{NULL} in caso di errore, nel qual caso \var{errno} viene
+    settata a:
+    \begin{errlist}
+    \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+    \end{errlist}
+    più gli altri eventuali codici di errore di \func{mkdir}.}
+\end{prototype}
+\noindent la directory è creata con permessi \code{0700} (al solito si veda
+\capref{cha:file_unix_interface} per i dettagli); dato che la creazione della
+directory è sempre esclusiva i precedenti problemi di \textit{race condition}
+non si pongono.
 
 
 \section{La manipolazione delle caratteristiche dei files}
 
 
 \section{La manipolazione delle caratteristiche dei files}
@@ -1744,11 +1890,43 @@ che per il file 
 \label{sec:file_chroot}
 
 Benché non abbia niente a che fare con permessi, utenti e gruppi, questa
 \label{sec:file_chroot}
 
 Benché non abbia niente a che fare con permessi, utenti e gruppi, questa
-funzione viene usata spesso per limitare le capacità dei programmi, ed è
-pertanto pertinente al controllo di accesso. Come accennato in
-\secref{sec:proc_fork} ogni processo oltre ad una directory di lavoro
-corrente, ha anche una directory radice, cioè una directory che per il
-processo costituisce la radice dell'albero del filesystem.
+funzione viene usata spesso per restringere le capacità di acccesso di un
+programma ad una sezione limitata del filesystem, per cui ne parleremo in
+questa sezione.
+
+Come accennato in \secref{sec:proc_fork} ogni processo oltre ad una directory
+di lavoro corrente, ha anche una directory radice, cioè una directory che per
+il processo costituisce la radice dell'albero del filesystem. Questa viene
+eredidata dal padre per ogni processo figlio, (come si può vedere da
+\figref{fig:proc_task_struct} è tenuta nella struttura \type{fs\_struct}
+insieme alla directory di lavoro corrente e alla \var{umask}) e quindi di
+norma coincide con la \file{/} del sistema.
+
+In certe situazioni però per motivi di sicurezza non si vuole che un processo
+possa accedere a tutto il filesystem; per questo si può cambiare la directory
+radice con la funzione \func{chroot}, il cui prototipo è:
+\begin{prototype}{unistd.h}{int chroot(const char *path)}
+  Cambia la directory radice del processo a quella specificata da
+  \param{path}..
+  
+\bodydesc{La funzione restituisce zero in caso di successo e -1 per
+    un errore, in caso di errore \texttt{errno} viene settato ai valori:
+  \begin{errlist}
+  \item[\macro{EPERM}] L'\textit{effective user id} non è zero.
+  \end{errlist}
+  ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
+  \macro{ENOMEM}, \macro{ENOTDIR}, \macro{EACCES}, \macro{ELOOP};
+  \macro{EROFS} e \macro{EIO}.}
+\end{prototype}
+
+
+
+
+
+un caso tipico è quello di un server
+ftp che dovrebbe limitarsi 
+
 
 
-In generale questa directory coincide con la 
+Il sistema però consente di cambiare questa directory con la funzione
+\func{chroot}