X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=5d1c21e5e475680fa0735abaa8a9c27242b1847d;hp=355348627fd4cbbdc7384b9c1d309fcce328f6b2;hb=b72f18d024a942eca58a8109c60479d835ee7350;hpb=c3693d1ea04bf85054e11ef98c244f000656b845 diff --git a/filedir.tex b/filedir.tex index 3553486..5d1c21e 100644 --- a/filedir.tex +++ b/filedir.tex @@ -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}). -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} @@ -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 -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}