X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=835e350b82a589013480f2272b8ec2584d180aad;hp=355348627fd4cbbdc7384b9c1d309fcce328f6b2;hb=8e2e384f75e8ea30c3ea290d736af1077f20117b;hpb=c3693d1ea04bf85054e11ef98c244f000656b845 diff --git a/filedir.tex b/filedir.tex index 3553486..835e350 100644 --- a/filedir.tex +++ b/filedir.tex @@ -32,15 +32,15 @@ dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows) che permettono di fare riferimento allo stesso file chiamandolo con nomi diversi o accedendovi da directory diverse. -Questo è possibile anche in ambiente unix, dove tali collegamenti sono +Questo è possibile anche in ambiente Unix, dove tali collegamenti sono usualmente chiamati \textit{link}; ma data la struttura del sistema di gestione dei file (ed in particolare quanto trattato in -\secref{sec:file_architecture}) ci sono due metodi sostanzialmente diversi per +\secref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per fare questa operazione. -Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di -un file su disco avviene attraverso il suo inode, e il nome che si trova in -una directory è solo una etichetta associata ad un puntatore a che fa +Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di un +file su disco avviene attraverso il suo inode\index{inode}, e il nome che si +trova in una directory è solo una etichetta associata ad un puntatore a che fa riferimento al suddetto inode. Questo significa che la realizzazione di un link è immediata in quanto uno @@ -282,8 +282,8 @@ specificato. La funzione che permette di creare un nuovo link simbolico \bodydesc{La funzione restituisce zero in caso di successo e -1 per un errore, nel qual caso la variabile \var{errno} restituisce i valori: \begin{errlist} - \item[\macro{EPERM}] il filesystem che contiene \param{newpath} non supporta i - link simbolici. + \item[\macro{EPERM}] il filesystem che contiene \param{newpath} non supporta + i link simbolici. \item[\macro{ENOENT}] una componente di \param{newpath} non esiste o \param{oldpath} è una stringa vuota. \item[\macro{EEXIST}] esiste già un file \param{newpath}. @@ -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} @@ -1700,7 +1846,7 @@ sono tre e i loro prototipi sono i seguenti: specificati dalle variabili \var{owner} e \var{group}. \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per - un errore, in caso di errore \texttt{errno} viene settato ai valori: + un errore, in caso di errore \var{errno} viene settato ai valori: \begin{errlist} \item[\macro{EPERM}] L'\textit{effective user id} non corrisponde a quello del proprietario del file o non è zero, o utente e gruppo non sono validi @@ -1744,11 +1890,56 @@ 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. - -In generale questa directory coincide con la - +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, che è la directory che per +il processo costituisce la radice dell'albero dei file e rispetto alla quale +vengono risolti i pathname assoluti (si ricordi quanto detto in +\secref{sec:file_organization}). + +La radice 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 \var{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} +\noindent in questo modo la directory radice del processo diventerà +\param{path} (che ovviamente deve esistere) ed ogni pathname assoluto sarà +risolto a partire da essa, rendendo impossibile accedere alla parte di albero +sovrastante; si ha cioè quella che viene chiamata una \textit{chroot jail}. + +Solo l'amministratore può usare questa funzione, e la nuova radice, per quanto +detto in \secref{sec:proc_fork}, sarà ereditata da tutti i processi figli. Si +tenga presente che la funzione non cambia la directory di lavoro corrente, che +potrebbe restare fuori dalla \textit{chroot jail}. + +Un caso tipico di uso di \func{chroot} è quello di un server ftp, in questo +caso infatti si vuole che il server veda solo i file che deve trasferire, per +cui in genere si una \textit{chroot jail} alla directory che contiene i file. +Si tenga presente però che in questo caso occorrerà replicare all'interno +della \textit{chroot jail} tutti i file (in genere programmi e librerie) di +cui il server potrebbe avere bisogno. + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: