In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
file e directory, iniziando dalle funzioni di libreria che si usano per
copiarli, spostarli e cambiarne i nomi. Esamineremo poi l'interfaccia che
-permette la manipolazione dei vari attributi di file e directory ed alla
-fine faremo una trattazione dettagliata su come è strutturato il sistema base
-di protezioni e controllo di accesso ai file e sulle funzioni che ne
-permettono la gestione. Tutto quello che riguarda invece la manipolazione del
-contenuto dei file è lasciato ai capitoli successivi.
+permette la manipolazione dei vari attributi di file e directory ed alla fine
+faremo una trattazione dettagliata su come è strutturato il sistema base di
+protezioni e controllo dell'accesso ai file e sulle funzioni che ne permettono
+la gestione. Tutto quello che riguarda invece la manipolazione del contenuto
+dei file è lasciato ai capitoli successivi.
\section{La gestione di file e directory}
+\label{sec:file_dir}
Come già accennato in \secref{sec:file_filesystem} in un sistema unix-like la
gestione dei file ha delle caratteristiche specifiche che derivano
funzioni usate per manipolazione nel filesytem di file e directory, per la
creazione di link simbolici e diretti, per la gestione e la lettura delle
directory; il tutto mettendo in evidenza le conseguenze della struttura
-standard della gestione dei file in un sistema unix-like, già accennate al
+standard della gestione dei file in un sistema unix-like, introdotta nel
capitolo precedente.
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
+trova in una directory è solo un'etichetta associata ad un puntatore a che fa
riferimento al suddetto inode.
Questo significa che la realizzazione di un link è immediata in quanto uno
stesso file può avere tanti nomi diversi allo stesso tempo, dati da
altrettante diverse associazioni allo stesso inode; si noti poi che nessuno di
-questi nomi viene ad assumere una particolare preferenza rispetto agli altri.
+questi nomi viene ad assumere una particolare preferenza o originalità
+rispetto agli altri.
Per aggiungere un nome ad un inode si utilizza la funzione \func{link}; si
suole chiamare questo tipo di associazione un collegamento diretto (o
Windows).
La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
-filesystem, con l'eccezione delle directory. In alcuni versioni di unix solo
+filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
l'amministratore è in grado di creare un collegamento diretto ad un'altra
-directory, questo viene fatto perché con una tale operazione è possibile
+directory: questo viene fatto perché con una tale operazione è possibile
creare dei circoli nel filesystem (vedi l'esempio mostrato in
\secref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi
non sono in grado di gestire e la cui rimozione diventerebbe estremamente
restrizioni è applicata).
Una delle caratteristiche di queste funzioni è che la creazione/rimozione
-della nome dalla directory e l'incremento/decremento del numero di riferimenti
-nell'inode deve essere una operazione atomica (si veda
-\secref{sec:proc_atom_oper}), per questo entrambe queste funzioni sono
-realizzate tramite una singola system call.
+del nome dalla directory e l'incremento/decremento del numero di riferimenti
+nell'inode devono essere effettuati in maniera atomica (si veda
+\secref{sec:proc_atom_oper}) senza possibili interruzioni fra le due
+operazioni. Per questo entrambe queste funzioni sono realizzate tramite una
+singola system call.
Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
-i riferimenti ad esso sono stati cancellati, solo quando il \textit{link
+i riferimenti ad esso sono stati cancellati: solo quando il \textit{link
count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
-questo però si aggiunge una altra condizione, e cioè che non ci siano processi
+questo però si aggiunge un'altra condizione, e cioè che non ci siano processi
che abbiano detto file aperto.
Questa proprietà viene spesso usata per essere sicuri di non lasciare file
\end{prototype}
Per cambiare nome ad un file o a una directory (che devono comunque essere
-nello stesso filesystem) si usa invece la funzione \func{rename}\footnote{la
+nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la
funzione è definita dallo standard ANSI C solo per i file, POSIX estende la
- funzione anche alle directory}, il cui prototipo è:
+ funzione anche alle directory.} il cui prototipo è:
\begin{prototype}{stdio.h}
{int rename(const char *oldpath, const char *newpath)}
\macro{EISDIR}). Nel caso \var{newpath} indichi un file esistente questo viene
cancellato e rimpiazzato (atomicamente).
-Se \var{oldpath} è una directory allora \var{newpath} se esiste deve essere
+Se \var{oldpath} è una directory allora \var{newpath}, se esiste, deve essere
una directory vuota, altrimenti si avranno gli errori \macro{ENOTDIR} (se non
è una directory) o \macro{ENOTEMPTY} (se non è vuota). Chiaramente
\var{newpath} non può contenere \var{oldpath} altrimenti si avrà un errore
\var{newpath} è un link simbolico verrà cancellato come qualunque altro file.
Infine qualora \var{oldpath} e \var{newpath} siano due nomi dello stesso file
lo standard POSIX prevede che la funzione non dia errore, e non faccia nulla,
-lasciando entrambi i nomi; Linux segue questo standard, anche se come fatto
-notare dal manuale delle glibc, il comportamento più ragionevole sarebbe
-quello di cancellare \var{oldpath}.
+lasciando entrambi i nomi; Linux segue questo standard, anche se, come fatto
+notare dal manuale delle \textit{glibc}, il comportamento più ragionevole
+sarebbe quello di cancellare \var{oldpath}.
Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
In ogni caso se \var{newpath} esiste e l'operazione fallisce per un qualche
motivo (come un crash del kernel), \func{rename} garantisce di lasciare
-presente una istanza di \var{newpath}, tuttavia nella sovrascrittura potrà
+presente un'istanza di \var{newpath}. Tuttavia nella sovrascrittura potrà
esistere una finestra in cui sia \var{oldpath} che \var{newpath} fanno
riferimento allo stesso file.
Come abbiamo visto in \secref{sec:file_link} la funzione \func{link} crea
riferimenti agli inodes, pertanto può funzionare soltanto per file che
-risiedono sullo stesso filesystem e solo per un filesystem di tipo unix.
+risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix.
Inoltre abbiamo visto che in Linux non è consentito eseguire un link diretto
ad una directory.
-Per ovviare a queste limitazioni i sistemi unix supportano un'altra forma di
+Per ovviare a queste limitazioni i sistemi Unix supportano un'altra forma di
link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
-come avviene in altri sistemi operativi, dei file speciali che contengono il
+come avviene in altri sistemi operativi, dei file speciali che contengono
semplicemente il riferimento ad un altro file (o directory). In questo modo è
possibile effettuare link anche attraverso filesystem diversi, a file posti in
-filesystem che non supportano i link diretti, a delle directory, e anche a
+filesystem che non supportano i link diretti, a delle directory, ed anche a
file che non esistono ancora.
Il sistema funziona in quanto i link simbolici sono contrassegnati come tali
Si tenga presente che la funzione non effettua nessun controllo sull'esistenza
di un file di nome \param{oldpath}, ma si limita ad inserire quella stringa
nel link simbolico. Pertanto un link simbolico può anche riferirsi ad un file
-che non esiste: quello che viene chiamato un \textit{dangling link},
-letteralmente \textsl{link ciondolante}.
-
+che non esiste: in questo caso si ha quello che viene chiamato un
+\textit{dangling link}, letteralmente un \textsl{link ciondolante}.
Come accennato i link simbolici sono risolti automaticamente dal kernel
all'invocazione delle varie system call; in \ntab\ si è riportato un elenco
\var{buff} o -1 per un errore, nel qual caso la variabile
\var{errno} viene settata a:
\begin{errlist}
- \item[\macro{EINVAL}] \var{file} non è un link simbolico o \var{size} non è
- positiva.
- \item[\macro{EROFS}] La directory su cui si vuole inserire il nuovo link è
- su un filesystem montato in sola lettura.
- \item[\macro{ENOSPC}] La directory o il filesystem in cui si vuole creare il
- link è piena e non c'è ulteriore spazio disponibile.
+ \item[\macro{EINVAL}] \param{path} non è un link simbolico o \param{size}
+ non è positiva.
\end{errlist}
ed inoltre \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
\macro{EACCES}, \macro{ELOOP}, \macro{EIO}, \macro{EFAULT} e
\begin{figure}[htb]
\centering
- \includegraphics[width=5cm]{img/link_loop}
+ \includegraphics[width=7cm]{img/link_loop}
\caption{Esempio di loop nel filesystem creato con un link simbolico.}
\label{fig:file_link_loop}
\end{figure}
Un caso comune che si può avere con i link simbolici è la creazione dei
cosiddetti \textit{loop}. La situazione è illustrata in \curfig, che riporta
la struttura della directory \file{/boot}. Come si vede si è creato al suo
-interno un link simbolico che punta di nuovo a \file{/boot}\footnote{Questo
+interno un link simbolico che punta di nuovo a \file{/boot}.\footnote{Questo
tipo di loop è stato effettuato per poter permettere a \cmd{grub} (un
- bootloader estremamente avanzato in grado di accedere direttamente
- attraverso vari filesystem al file da lanciare come sistema operativo) di
- vedere i file in questa directory, che è montata su una partizione separata
- (e che grub vedrebbe come radice), con lo stesso path con cui verrebbero
- visti dal sistema operativo.}.
+ bootloader in grado di leggere direttamente da vari filesystem il file da
+ lanciare come sistema operativo) di vedere i file in questa directory con lo
+ stesso path con cui verrebbero visti dal sistema operativo, anche se essi si
+ trovano, come è solito, su una partizione separata (e che \cmd{grub}
+ vedrebbe come radice).}
Questo può causare problemi per tutti quei programmi che effettuano la
scansione di una directory senza tener conto dei link simbolici, ad esempio se
-lanciassimo un comando del tipo \cmd{grep -r linux *}, il loop nella directory
-porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot},
+lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella
+directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot},
\file{/boot/boot/boot} e così via.
Per questo motivo il kernel e le librerie prevedono che nella risoluzione di
un pathname possano essere seguiti un numero limitato di link simbolici, il
-cui valore limite è specificato dalla costante \macro{MAXSYMLINKS}; qualora
+cui valore limite è specificato dalla costante \macro{MAXSYMLINKS}. Qualora
questo limite venga superato viene generato un errore ed \var{errno} viene
settata al valore \macro{ELOOP}.
-Un punto da tenere sempre presente è il fatto che un link simbolico può fare
-riferimento anche ad un file che non esiste; ad esempio possiamo creare un
-file temporaneo nella nostra directory con un link del tipo:
+Un punto da tenere sempre presente è che, come abbiamo accennato, un link
+simbolico può fare riferimento anche ad un file che non esiste; ad esempio
+possiamo creare un file temporaneo nella nostra directory con un link del
+tipo:
\begin{verbatim}
$ ln -s /tmp/tmp_file temporaneo
\end{verbatim}%$
$ cat temporaneo
cat: temporaneo: No such file or directory
\end{verbatim}%$
-con un errore che può sembrare sbagliato, dato che invece \cmd{ls} ci
-mostrerebbe l'esistenza di \file{temporaneo}.
+con un errore che può sembrare sbagliato, dato che un'ispezione con \cmd{ls}
+ci mostrerebbe invece l'esistenza di \file{temporaneo}.
\subsection{La creazione e la cancellazione delle directory}
\macro{ENOENT}, \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP},
\macro{EROFS}.}
\end{prototype}
-
+
La funzione crea una nuova directory vuota (che contiene solo le due voci
standard \file{.} e \file{..}). I permessi di accesso (vedi la trattazione in
\secref{sec:file_access_control}) specificati da \var{mode} (i cui possibili
\label{sec:file_mknod}
Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
-\secref{sec:file_file_types} abbiamo visto però che il sistema preveda pure
-degli altri tipi di file, come i file di dispositivo e le fifo (i socket sono
-un caso a parte, che vedremo in \secref{cha:socket_intro}).
+\secref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
+degli altri tipi di file speciali, come i file di dispositivo e le fifo (i
+socket sono un caso a parte, che vedremo in \capref{cha:socket_intro}).
-La manipolazione delle caratteristiche di questi filee e la loro cancellazione
+La manipolazione delle caratteristiche di questi file e la loro cancellazione
può essere effettuata con le stesse funzioni che operano sui file normali; ma
quando li si devono creare sono necessarie delle funzioni apposite. La prima
di queste funzioni è \func{mknod}, il suo prototipo è:
La funzione permette di creare un file speciale, ma si può usare anche per
creare file normali e fifo; l'argomento \param{mode} specifica il tipo di file
che si vuole creare ed i relativi permessi, secondo i valori riportati in
-\tabref{tab:file_mode_flags}, che vanno combinato come OR binario. I permessi
-sono comunque modificati nella maniera usuale dal valore di \var{umask} (si
-veda \secref{sec:file_umask}.
+\tabref{tab:file_mode_flags}, che vanno combinati con un OR binario. I
+permessi sono comunque modificati nella maniera usuale dal valore di
+\var{umask} (si veda \secref{sec:file_umask}).
Per il tipo di file può essere specificato solo uno fra: \macro{S\_IFREG} per
un file normale (che sarà creato vuoto), \macro{S\_IFBLK} per un device a
agli utenti normali.
I nuovi inode creati con \func{mknod} apparterranno al proprietario e al
-gruppo del processo che li creati, a meno che non si sia attivato il bit
+gruppo del processo che li ha creati, a meno che non si sia attivato il bit
\acr{sgid} per la directory o sia stata attivata la semantica BSD per il
filesystem (si veda \secref{sec:file_ownership}) in cui si va a creare
l'inode.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori \macro{EACCESS},
\macro{EEXIST}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOSPC},
- \macro{ENOTDIR} e\macro{EROFS}.}
+ \macro{ENOTDIR} e \macro{EROFS}.}
\end{functions}
\noindent come per \func{mknod} il file \param{pathname} non deve esistere
(neanche come link simbolico); al solito i permessi specificati da
\capref{cha:files_std_interface}); la funzione \func{opendir} apre uno di
questi stream e la funzione \func{readdir} legge il contenuto della directory,
i cui elementi sono le \textit{directory entry} (da distinguersi da quelle
-della cache di cui parlavamo in \secref{sec:file_vfs}) in una opportuna
+della cache di cui parlavamo in \secref{sec:file_vfs}) in un'opportuna
struttura \var{struct dirent}.
(NdA Il resto va scritto!!! É noioso e lo farò più avanti).
A ciascun processo è associato ad una directory nel filesystem che è chiamata
directory corrente o directory di lavoro (\textit{current working directory})
che è quella a cui si fa riferimento quando un filename è espresso in forma
-relativa, dove il relativa fa riferimento appunto a questa directory.
+relativa, dove il ``relativa'' fa riferimento appunto a questa directory.
Quando un utente effettua il login questa directory viene settata alla
\textit{home directory} del suo account. Il comando \cmd{cd} della shell
Il buffer deve essere sufficientemente lungo da poter contenere il pathname
completo più lo zero di terminazione della stringa. Qualora esso ecceda le
dimensioni specificate con \var{size} la funzione restituisce un errore. Si
-può anche specificare un puntatore nullo come \var{buffer}\footnote{questa è
- una estensione allo standard POSIX.1, supportata da Linux}, nel qual caso la
+può anche specificare un puntatore nullo come \var{buffer},\footnote{questa è
+ un'estensione allo standard POSIX.1, supportata da Linux.} nel qual caso la
stringa sarà allocata automaticamente per una dimensione pari a \var{size}
qualora questa sia diversa da zero, o della lunghezza esatta del pathname
altrimenti. In questo caso ci si deve ricordare di disallocare la stringa una
sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola
differenza che essa ritorna il valore della variabile di ambiente \macro{PWD},
che essendo costruita dalla shell può contenere un pathname comprendente anche
-con dei link simbolici. Usando \func{getcwd} infatti, essendo il
-pathname ricavato risalendo all'indietro l'albero della directory, si
-perderebbe traccia di ogni passaggio attraverso eventuali link simbolici.
+dei link simbolici. Usando \func{getcwd} infatti, essendo il pathname ricavato
+risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni
+passaggio attraverso eventuali link simbolici.
Per cambiare la directory di lavoro corrente si può usare la funzione
-\func{chdir} (omonima dell'analogo comando di shell) il cui nome sta appunto
-per \textit{change directory}), il suo prototipo è:
+\func{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta
+appunto per \textit{change directory}, il suo prototipo è:
\begin{prototype}{unistd.h}{int chdir(const char *pathname)}
Cambia la directory di lavoro corrente in \param{pathname}.
\subsection{I file temporanei}
\label{sec:file_temp_file}
-In molte occasioni è utile poter creare dei file temporanei; benchè la cosa
+In molte occasioni è utile poter creare dei file temporanei; benché la cosa
sembri semplice in realtà il problema è più sottile di quanto non appaia a
prima vista. Infatti anche se sembrerebbe banale generare un nome a caso e
creare il file dopo aver controllato che questo non esista, nel momento fra il
\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:
+La funzione alloca con \code{malloc} la stringa in cui restituisce 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
\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.
+ottenere 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 è:
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
+\noindent essa 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}.
+standard non specifica in quale directory verrà aperto il file, ma le
+\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}\index{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
\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.
+alle possibili \textit{race condition}\index{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à diverse per il nome del file, e rende il nome temporaneo facile da
+indovinare. Per tutti questi motivi la funzione è deprecata e non dovrebbe mai
+essere usata.
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
+\noindent come per \func{mktemp} anche in questo caso \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
\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.
+directory è sempre esclusiva i precedenti problemi di \textit{race
+ condition}\index{race condition} non si pongono.
\section{La manipolazione delle caratteristiche dei files}
\macro{ELOOP}, \macro{EFAULT}, \macro{EACCESS}, \macro{ENOMEM},
\macro{ENAMETOOLONG}.}
\end{functions}
+\noindent il loro comportamento è identico, solo che operano rispettivamente
+su un file, su un link simbolico e su un file descriptor.
-La struttura \var{stat} è definita nell'header \file{sys/stat.h} e in
-generale dipende dall'implementazione, la versione usata da Linux è mostrata
-in \nfig, così come riportata dalla man page (in realtà la definizione
-effettivamente usata nel kernel dipende dall'architettura e ha altri campi
-riservati per estensioni come tempi più precisi, o per il padding dei campi).
+La struttura \var{stat} usata da queste funzioni è definita nell'header
+\file{sys/stat.h} e in generale dipende dall'implementazione, la versione
+usata da Linux è mostrata in \nfig, così come riportata dalla man page di
+\func{stat} (in realtà la definizione effettivamente usata nel kernel dipende
+dall'architettura e ha altri campi riservati per estensioni come tempi più
+precisi, o per il padding dei campi).
\begin{figure}[!htb]
\footnotesize
\subsection{I tipi di file}
\label{sec:file_types}
-Come riportato in \tabref{tab:file_file_types} in Linux oltre ai file e
-alle directory esistono vari altri oggetti che possono stare su un filesystem;
-il tipo di file è ritornato dalla \func{stat} nel campo \var{st\_mode}
-(che è quello che contiene anche le informazioni relative ai permessi).
+Come riportato in \tabref{tab:file_file_types} in Linux oltre ai file e alle
+directory esistono vari altri oggetti che possono stare su un filesystem. Il
+tipo di file è ritornato dalla \func{stat} come maschera binaria nel campo
+\var{st\_mode} (che che contiene anche le informazioni relative ai permessi).
Dato che il valore numerico può variare a seconda delle implementazioni, lo
standard POSIX definisce un insieme di macro per verificare il tipo di files,
-queste vengono usate anche da Linux che supporta pure le estensioni per link
-simbolici e socket definite da BSD, l'elenco completo di tutte le macro è
+queste vengono usate anche da Linux che supporta pure le estensioni allo
+standard per i link simbolici e i socket definite da BSD; l'elenco completo
+delle macro con cui è possibile estrarre l'informazione da \var{st\_mode} è
riportato in \ntab.
\begin{table}[htb]
\centering
\macro{S\_ISSOCK(m)} & socket \\
\hline
\end{tabular}
- \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h})}
+ \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).}
\label{tab:file_type_macro}
\end{table}
-Oltre a queste macro è possibile usare direttamente il valore di
-\var{st\_mode} per ricavare il significato dei vari bit in esso memorizzati,
-per questo sempre in \file{sys/stat.h} sono definiti i flag riportati in
-\ntab:
+Oltre alle macro di \tabref{tab:file_type_macro} è possibile usare
+direttamente il valore di \var{st\_mode} per ricavare il tipo di file
+controllando direttamente i vari bit in esso memorizzati. Per questo sempre in
+\file{sys/stat.h} sono definite le costanti numeriche riportate in \ntab.
+
+Il primo valore dell'elenco di \secref{tab:file_mode_flags} è la maschera
+binaria che permette di estrarre i bit nei quali viene memorizzato il tipo di
+file, i valori successivi sono le costanti corrispondenti ai singoli bit, e
+possono essere usati per effettuare la selezione sul tipo di file voluto, con
+un'opportuna combinazione.
+
\begin{table}[htb]
\centering
\footnotesize
\hline
\end{tabular}
\caption{Costanti per l'identificazione dei vari bit che compongono il campo
- \var{st\_mode} (definite in \file{sys/stat.h})}
+ \var{st\_mode} (definite in \file{sys/stat.h}).}
\label{tab:file_mode_flags}
\end{table}
-Il primo valore definisce la maschera dei bit usati nei quali viene
-memorizzato il tipo di files, mentre gli altri possono essere usati per
-effettuare delle selezioni sul tipo di file voluto, combinando opportunamente
-i vari flag; ad esempio se si volesse controllare se un file è una directory o
-un file ordinario si potrebbe definire la condizione:
+Ad esempio se si volesse impostare una condizione che permetta di controllare
+se un file è una directory o un file ordinario si potrebbe definire la macro
+di preprocessore:
\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
#define IS_FILE_DIR(x) (((x) & S_IFMT) & (S_IFDIR | S_IFREG))
\end{lstlisting}
poi si effettua il confronto con la combinazione di tipi scelta.
-\subsection{La dimensione dei file}
+\subsection{Le dimensioni dei file}
\label{sec:file_file_size}
-Il membro \var{st\_size} contiene la dimensione del file in byte (se il file
-è un file normale, nel caso di un link simbolico al dimensione è quella del
-pathname che contiene).
+Il membro \var{st\_size} contiene la dimensione del file in byte (se il file è
+un file normale, nel caso di un link simbolico la dimensione è quella del
+pathname che contiene).
Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512
byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per
per l'interfaccia degli stream); scrivere sul file a blocchi di dati di
dimensione inferiore sarebbe inefficiente.
-Si tenga conto che lunghezza del file riportata in \var{st\_size} non è detto
-che corrisponda all'occupazione dello spazio su disco per via della possibile
-esistenza dei cosiddetti \textsl{buchi} (detti normalmente \textit{holes}) che
-si formano tutte le volte che si va a scrivere su un file dopo aver eseguito
-una \func{lseek} (vedi \secref{sec:file_lseek}) oltre la sua conclusione
-corrente.
+Si tenga conto che la lunghezza del file riportata in \var{st\_size} non è
+detto che corrisponda all'occupazione dello spazio su disco per via della
+possibile esistenza dei cosiddetti \textit{holes} (letteralmente
+\textsl{buchi}) che si formano tutte le volte che si va a scrivere su un file
+dopo aver eseguito una \func{lseek} (vedi \secref{sec:file_lseek}) oltre la
+sua fine.
-In tal caso si avranno differenti risultati a seconda del modi in cui si
+In questo caso si avranno risultati differenti a seconda del modo in cui si
calcola la lunghezza del file, ad esempio il comando \cmd{du}, (che riporta il
numero di blocchi occupati) potrà dare una dimensione inferiore, mentre se si
legge dal file (ad esempio usando il comando \cmd{wc -c}), dato che in tal
Un file può sempre essere troncato a zero aprendolo con il flag
\macro{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
-dimensione si possono usare le due funzioni:
+dimensione si possono usare le due funzioni \func{truncate} e
+\func{ftruncate}, i cui prototipi sono:
\begin{functions}
\headdecl{unistd.h} \funcdecl{int truncate(const char *file\_name, off\_t
length)} Fa si che la dimensione del file \var{file\_name} sia troncata ad
\begin{tabular}[c]{|c|l|l|c|}
\hline
\textbf{Membro} & \textbf{Significato} & \textbf{Funzione}
- & \textbf{Opzione} \\
+ & \textbf{Opzione di \cmd{ls}} \\
\hline
\hline
\var{st\_atime}& ultimo accesso ai dati del file &\func{read},
\func{utime} & \cmd{-c} \\
\hline
\end{tabular}
- \caption{I tre tempi associati a ciascun file}
+ \caption{I tre tempi associati a ciascun file.}
\label{tab:file_file_times}
\end{table}
directory sono file (che contengono una lista di nomi) che il sistema tratta
in maniera del tutto analoga a tutti gli altri.
-Per questo motivo tutte le volte che compiremo una operazione su un file che
+Per questo motivo tutte le volte che compiremo un'operazione su un file che
comporta una modifica del nome contenuto nella directory, andremo anche a
scrivere sulla directory che lo contiene cambiandone il tempo di modifica. Un
esempio di questo può essere la cancellazione di un file, invece leggere o
\begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
\hline
\multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
- \multicolumn{3}{|p{3cm}|}{\centering{File o directory di riferimento}}&
- \multicolumn{3}{|p{3cm}|}{\centering{Directory genitrice del riferimento}}
+ \multicolumn{3}{|p{3.6cm}|}{\centering{
+ \textbf{File o directory del riferimento}}}&
+ \multicolumn{3}{|p{3.6cm}|}{\centering{
+ \textbf{Directory contenente il riferimento}}}
&\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
\cline{2-7}
\cline{2-7}
\multicolumn{1}{|p{3cm}|}{}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
- &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}}
&\multicolumn{1}{|p{3cm}|}{} \\
\hline
\hline
\func{read}
&$\bullet$& & & & & & \\
\func{remove}
- & & &$\bullet$& &$\bullet$&$\bullet$& using
+ & & &$\bullet$& &$\bullet$&$\bullet$& se esegue
\func{unlink}\\ \func{remove}
- & & & & &$\bullet$&$\bullet$& using
+ & & & & &$\bullet$&$\bullet$& se esegue
\func{rmdir}\\ \func{rename}
& & &$\bullet$& &$\bullet$&$\bullet$& per entrambi
gli argomenti\\ \func{rmdir}
\end{table}
Si noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di
-creazione del file, usato in molti altri sistemi operativi, ma che in unix non
+creazione del file, usato in molti altri sistemi operativi, ma che in Unix non
esiste. Per questo motivo quando si copia un file, a meno di preservare
esplicitamente i tempi (ad esempio con l'opzione \cmd{-p} di \cmd{cp}) esso
avrà sempre il tempo corrente come data di ultima modifica.
\subsection{I permessi per l'accesso ai file}
\label{sec:file_perm_overview}
-Il controllo di accesso ai file in unix segue un modello abbastanza semplice
-(ma adatto alla gran parte delle esigenze) in cui si dividono i permessi su
-tre livelli. Si tenga conto poi che quanto diremo è vero solo per filesystem
-di tipo unix, e non è detto che sia applicabile a un filesystem
-qualunque\footnote{ed infatti non è vero per il filesystem vfat di Windows,
- per il quale i permessi vengono assegnati in maniera fissa con un opzione in
- fase di montaggio}. Esistono inoltre estensioni che permettono di
-implementare le ACL (\textit{Access Control List}) che sono un meccanismo di
-controllo di accesso molto più sofisticato.
-
-Ad ogni file unix associa sempre l'utente che ne è proprietario (il cosiddetto
-\textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli
-identificatori di utenti e gruppi (\acr{uid} e \acr{gid}). Questi valori
-sono accessibili da programma tramite i campi \var{st\_uid} e \var{st\_gid}
-della struttura \var{stat} (si veda \secref{sec:file_stat}). Ad ogni file
-viene inoltre associato un insieme di permessi che sono divisi in tre classi,
-e cioè attribuiti rispettivamente all'utente proprietario del file, a un
-qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti gli
-altri utenti.
-
-I permessi, così come vengono presi dai comandi e dalle routine di sistema,
-sono espressi da un numero di 12 bit; di questi i nove meno significativi sono
-usati a gruppi di tre per indicare i permessi base di lettura, scrittura ed
-esecuzione (indicati nei comandi di sistema con le lettere \cmd{w}, \cmd{r} e
-\cmd{x}) ed applicabili rispettivamente al proprietario, al gruppo, a tutti
-gli altri. I restanti tre bit (\acr{suid}, \acr{sgid}, e
-\textsl{sticky}) sono usati per indicare alcune caratteristiche più complesse
-su cui torneremo in seguito (vedi \secref{sec:file_suid_sgid} e
-\secref{sec:file_sticky}).
+Ad ogni file Linux associa sempre l'utente che ne è proprietario (il
+cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo
+degli identificatori di utenti e gruppi (\acr{uid} e \acr{gid}). Questi valori
+sono accessibili da programma tramite la funzione \func{stat}, e sono
+mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura \var{stat}
+(si veda \secref{sec:file_stat}).\footnote{Questo è vero solo per filesystem
+ di tipo Unix, ad esempio non è vero per il filesystem vfat di Windows, che
+ non fornisce nessun supporto per l'accesso multiutente, e per il quale i
+ permessi vengono assegnati in maniera fissa con un opzione in fase di
+ montaggio.}
+
+Il controllo di accesso ai file segue un modello abbastanza semplice che
+prevede tre permessi fondamentali strutturati su tre livelli di accesso.
+Esistono varie estensioni a questo modello,\footnote{come le \textit{Access
+ Control List} che possono essere aggiunte al filesystem standard con
+ opportune patch, e sono presenti in filesystem non ancora inclusi nel kernel
+ ufficiale come \textsl{xfs}, o meccanismi di controllo ancora più
+ sofisticati come il \textit{mandatory access control} di SE-Linux.} ma nella
+maggior parte dei casi il meccanismo standard è più che sufficiente a
+soffisfare tutte le necessità più comuni. I tre permessi di base associati ad
+ogni file sono:
+\begin{itemize*}
+\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
+ \textit{read}).
+\item il permesso di scrittura (indicato con la lettera \texttt{w},
+ dall'inglese \textit{write}).
+\item il permesso di esecuzione (indicato con la lettera \texttt{x},
+ dall'inglese \textit{execute}).
+\end{itemize*}
+mentre i tre livelli su cui sono divisi i privilegi sono:
+\begin{itemize*}
+\item i privilegi per l'utente proprietario del file.
+\item i privilegi per un qualunque utente faccia parte del gruppo cui
+ appartiene il file.
+\item i privilegi per tutti gli altri utenti.
+\end{itemize*}
-Anche i permessi, come tutte le altre informazioni generali, sono tenuti per
-ciascun file nell'inode; in particolare essi sono contenuti in alcuni bit
-del campo \var{st\_mode} della struttura letta da \func{stat} (di nuovo si veda
-\secref{sec:file_stat} per i dettagli).
-
-In genere ci si riferisce a questo raggruppamento dei permessi usando le
-lettere \cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o}
-(per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti
-insieme si usa la lettera \cmd{a} (per \textit{all}). Si tenga ben presente
-questa distinzione dato che in certi casi, mutuando la terminologia in uso nel
-VMS, si parla dei permessi base come di permessi per \textit{owner},
-\textit{group} ed \textit{all}, le cui iniziali possono dar luogo a confusione.
-Le costanti che permettono di accedere al valore numerico di questi bit nel
-campo \var{st\_mode} sono riportate in \ntab.
+L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
+meno significativi sono usati a gruppi di tre per indicare i permessi base di
+lettura, scrittura ed esecuzione e sono applicati rispettivamente
+rispettivamente al proprietario, al gruppo, a tutti gli altri.
+
+I restanti tre bit (noti come \acr{suid}, \acr{sgid}, e \textsl{sticky}) sono
+usati per indicare alcune caratteristiche più complesse del meccanismo del
+controllo di accesso su cui torneremo in seguito (in
+\secref{sec:file_suid_sgid} e \secref{sec:file_sticky}).
+
+Anche i permessi, come tutte le altre informazioni pertinenti al file, sono
+memorizzati nell'inode; in particolare essi sono contenuti in alcuni bit del
+campo \var{st\_mode} della struttura \func{stat} (si veda di nuovo
+\figref{fig:file_stat_struct}).
+
+In genere ci si riferisce ai tre livelli dei privilegi usando le lettere
+\cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o} (per
+\textit{other}), inoltre se si vuole indicare tutti i raggruppamenti insieme
+si usa la lettera \cmd{a} (per \textit{all}). Si tenga ben presente questa
+distinzione dato che in certi casi, mutuando la terminologia in uso nel VMS,
+si parla dei permessi base come di permessi per \textit{owner}, \textit{group}
+ed \textit{all}, le cui iniziali possono dar luogo a confusione. Le costanti
+che permettono di accedere al valore numerico di questi bit nel campo
+\var{st\_mode} sono riportate in \ntab.
\begin{table}[htb]
\centering
\label{tab:file_bit_perm}
\end{table}
-Questi permessi vengono usati in maniera diversa dalle varie funzioni, e a
-seconda che si riferiscano a file, link simbolici o directory, qui ci
+I permessi vengono usati in maniera diversa dalle varie funzioni, e a seconda
+che si riferiscano a dei file, dei link simbolici o delle directory, qui ci
limiteremo ad un riassunto delle regole generali, entrando nei dettagli più
avanti.
La prima regola è che per poter accedere ad un file attraverso il suo pathname
occorre il permesso di esecuzione in ciascuna delle directory che compongono
-il pathname, e lo stesso vale per aprire un file nella directory corrente (per
+il pathname; lo stesso vale per aprire un file nella directory corrente (per
la quale appunto serve il diritto di esecuzione).
-Per una directory infatti il permesso di esecuzione ha il significato
-specifico che essa può essere attraversata nella risoluzione del pathname, ed
-è distinto dal permesso di lettura che invece implica che si può leggere il
-contenuto della directory. Questo significa che se si ha il permesso di
-esecuzione senza permesso di lettura si potrà lo stesso aprire un file in una
-directory (se si hanno i permessi opportuni per il medesimo) ma non si potrà
-vederlo con \cmd{ls} (per crearlo occorrerà anche il permesso di scrittura per
-la directory).
-
-Avere il permesso di lettura per un file consente di aprirlo con le opzioni di
-sola lettura (\macro{O\_RDONLY}) o di lettura/scrittura (\macro{O\_RDWR}) e
-leggerne il contenuto. Avere il permesso di scrittura consente di aprire un
-file in sola scrittura (\macro{O\_WRONLY}) o lettura/scrittura
-(\macro{O\_RDWR}) e modificarne il contenuto, lo stesso permesso è necessario
-per poter troncare il file con l'opzione \macro{O\_TRUNC}.
+Per una directory infatti il permesso di esecuzione significa che essa può
+essere attraversata nella risoluzione del pathname, ed è distinto dal permesso
+di lettura che invece implica che si può leggere il contenuto della directory.
+Questo significa che se si ha il permesso di esecuzione senza permesso di
+lettura si potrà lo stesso aprire un file in una directory (se si hanno i
+permessi opportuni per il medesimo) ma non si potrà vederlo con \cmd{ls}
+(mentre per crearlo occorrerà anche il permesso di scrittura per la
+directory).
+
+Avere il permesso di lettura per un file consente di aprirlo con le opzioni
+(si veda quanto riportato in \tabref{tab:file_open_flags}) di sola lettura o
+di lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura
+consente di aprire un file in sola scrittura o lettura/scrittura e modificarne
+il contenuto, lo stesso permesso è necessario per poter troncare il file.
Non si può creare un file fintanto che non si disponga del permesso di
esecuzione e di quello di scrittura per la directory di destinazione; gli
che questo non implica necessariamente la rimozione del contenuto del file dal
disco), non è necessario nessun tipo di permesso per il file stesso (infatti
esso non viene toccato, viene solo modificato il contenuto della directory,
-rimuovendo la voce che ad esso fa rifermento).
+rimuovendo la voce che ad esso fa riferimento).
Per poter eseguire un file (che sia un programma compilato od uno script di
shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre
eseguiti.
I permessi per un link simbolico sono ignorati, contano quelli del file a cui
-fa riferimento; per questo in genere \cmd{ls} per un link simbolico riporta
-tutti i permessi come concessi; utente e gruppo a cui esso appartiene vengono
-ignorati quando il link viene risolto, vengono controllati solo quando viene
-richiesta la rimozione del link e quest'ultimo è in una directory con lo
-\textsl{sticky bit} settato (si veda \secref{sec:file_sticky}).
+fa riferimento; per questo in genere il comando \cmd{ls} riporta per un link
+simbolico tutti i permessi come concessi; utente e gruppo a cui esso
+appartiene vengono pure ignorati quando il link viene risolto, vengono
+controllati solo quando viene richiesta la rimozione del link e quest'ultimo è
+in una directory con lo \textsl{sticky bit} settato (si veda
+\secref{sec:file_sticky}).
La procedura con cui il kernel stabilisce se un processo possiede un certo
permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra
l'utente e il gruppo a cui il file appartiene (i valori di \var{st\_uid} e
\var{st\_gid} accennati in precedenza) e l'\textit{effective user id},
l'\textit{effective group id} e gli eventuali \textit{supplementary group id}
-del processo\footnote{in realtà Linux per quanto riguarda l'accesso ai file
+del processo.\footnote{in realtà Linux per quanto riguarda l'accesso ai file
utilizza al posto degli \textit{effective id} i \textit{filesystem id} (si
veda \secref{sec:proc_perms}), ma essendo questi del tutto equivalenti ai
primi, eccetto il caso in cui si voglia scrivere un server NFS, ignoreremo
- questa differenza}.
+ questa differenza.}
Per una spiegazione dettagliata degli identificatori associati ai processi si
veda \secref{sec:proc_perms}; normalmente, a parte quanto vedremo in
Si tenga presente che questi passi vengono eseguiti esattamente in
quest'ordine. Questo vuol dire che se un processo è il proprietario di un file
l'accesso è consentito o negato solo sulla base dei permessi per l'utente; i
-permessi per il gruppo non vengono neanche controllati; lo stesso vale se il
+permessi per il gruppo non vengono neanche controllati. Lo stesso vale se il
processo appartiene ad un gruppo appropriato, in questo caso i permessi per
tutti gli altri non vengono controllati.
\label{sec:file_suid_sgid}
Come si è accennato (in \secref{sec:file_perm_overview}) nei dodici bit del
-campo \var{st\_mode} usati per il controllo di accesso oltre ai bit dei
-permessi veri e propri, ci sono altri tre bit che vengono usati per indicare
-alcune proprietà speciali dei file. Due di questi sono i bit detti
-\acr{suid} (o \textit{set-user-ID bit}) e \acr{sgid} (o
+campo \var{st\_mode} di \var{stat} che vengono usati per il controllo di
+accesso oltre ai bit dei permessi veri e propri, ci sono altri tre bit che
+vengono usati per indicare alcune proprietà speciali dei file. Due di questi
+sono i bit detti \acr{suid} (da \textit{set-user-ID bit}) e \acr{sgid} (da
\textit{set-group-ID bit}) che sono identificati dalle costanti
\macro{S\_ISUID} e \macro{S\_ISGID}.
corrispondono dell'utente con cui si è entrati nel sistema.
Se però il file del programma\footnote{per motivi di sicurezza il kernel
- ignora i bit \acr{suid} e \acr{sgid} per gli script eseguibili} (che
+ ignora i bit \acr{suid} e \acr{sgid} per gli script eseguibili.} (che
ovviamente deve essere eseguibile) ha il bit \acr{suid} settato, il kernel
assegnerà come \textit{effective user id} al nuovo processo l'\acr{uid} del
proprietario del file al posto dell'\acr{uid} del processo originario. Avere
Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe
normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di
programmi devono essere scritti accuratamente per evitare che possano essere
-usati per guadagnare privilegi non consentiti (torneremo sull'argomento in
-\secref{sec:proc_perms}).
-
-La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere
-rilevata con il comando \cmd{ls -l}, in tal caso comparirà la lettera \cmd{s}
-al posto della \cmd{x} in corrispondenza dei permessi di utente o gruppo. La
-stessa lettera \cmd{s} può essere usata nel comando \cmd{chmod} per settare
-questi bit. Infine questi bit possono essere controllati all'interno di
-\var{st\_mode} con l'uso delle due costanti \macro{S\_ISUID} e
-\macro{S\_IGID}, i cui valori sono riportati in
-\tabref{tab:file_mode_flags}.
+usati per guadagnare privilegi non consentiti (l'argomento è affrontato in
+dettaglio in \secref{sec:proc_perms}).
+
+La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere rilevata con
+il comando \cmd{ls -l}, che visualizza una lettera \cmd{s} al posto della
+\cmd{x} in corrispondenza dei permessi di utente o gruppo. La stessa lettera
+\cmd{s} può essere usata nel comando \cmd{chmod} per settare questi bit.
+Infine questi bit possono essere controllati all'interno di \var{st\_mode} con
+l'uso delle due costanti \macro{S\_ISUID} e \macro{S\_IGID}, i cui valori sono
+riportati in \tabref{tab:file_mode_flags}.
Gli stessi bit vengono ad assumere in significato completamente diverso per le
directory, normalmente infatti Linux usa la convenzione di SVR4 per indicare
veda \secref{sec:file_ownership} per una spiegazione dettagliata al
proposito).
-Infine Linux utilizza il bit \acr{sgid} per una ulteriore estensione
-mutuata da SVR4. Il caso in cui il file abbia il bit \acr{sgid} settato ma
-non il corrispondente bit di esecuzione viene utilizzato per attivare per
-quel file il \textit{mandatory locking} (argomento che affronteremo nei
-dettagli in \secref{sec:file_mand_locking}).
+Infine Linux utilizza il bit \acr{sgid} per una ulteriore estensione mutuata
+da SVr4. Il caso in cui un file ha il bit \acr{sgid} settato senza che lo sia
+anche il corrispondente bit di esecuzione viene utilizzato per attivare per
+quel file il \textit{mandatory locking} (argomento che affronteremo in
+dettagliopiù avanti in \secref{sec:file_mand_locking}).
\subsection{Il bit \textsl{sticky}}
\label{sec:file_sticky}
L'ultimo dei bit rimanenti, identificato dalla costante \macro{S\_ISVTX}, è in
-parte un rimasuglio delle origini dei sistemi unix. A quell'epoca infatti la
+parte un rimasuglio delle origini dei sistemi Unix. A quell'epoca infatti la
memoria virtuale e l'accesso ai files erano molto meno sofisticati e per
ottenere la massima velocità possibile per i programmi usati più comunemente
si poteva settare questo bit.
sostanzialmente inutile questo procedimento.
Benché ormai non venga più utilizzato per i file, lo \textsl{sticky bit} ha
-assunto un uso corrente per le directory\footnote{lo \textsl{sticky bit} per
- le directory è una estensione non definita nello standard POSIX, Linux però
- la supporta, così come BSD e SVR4}, in questo caso se il bit è settato un
-file potrà essere rimosso dalla directory soltanto se l'utente ha il permesso
-di scrittura ed inoltre è vera una delle seguenti condizioni:
+invece assunto un uso importante per le directory;\footnote{lo \textsl{sticky
+ bit} per le directory è un'estensione non definita nello standard POSIX,
+ Linux però la supporta, così come BSD e SVR4.} in questo caso se il bit è
+settato un file potrà essere rimosso dalla directory soltanto se l'utente ha
+il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
+condizioni:
\begin{itemize*}
\item l'utente è proprietario del file
\item l'utente è proprietario della directory
$ ls -ld /tmp
drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp
\end{verbatim}%$
-in questo modo chiunque può leggere, scrivere ed eseguire i file temporanei
-ivi memorizzati, sia crearne di nuovi, ma solo l'utente che ha creato un file
-nella directory potrà cancellarlo o rinominarlo, così si può evitare che un
-utente possa, più o meno consapevolmente, cancellare i file degli altri.
+in questo modo chiunque può creare file in questa directory (che infatti è
+normalmente utilizzata per la creazione di file temporanei), ma solo l'utente
+che ha creato un certo file potrà cancellarlo o rinominarlo. In questo modo si
+evita che un utente possa, più o meno consapevolmente, cancellare i file degli
+altri.
\subsection{La titolarità di nuovi file e directory}
\label{sec:file_ownership}
-Vedremo in \secref{sec:file_base_func} come creare nuovi file, ma se è
-possibile specificare in sede di creazione quali permessi applicare ad un
-file, non si può indicare a quale utente e gruppo esso deve appartenere. Lo
-stesso problema di presenta per la creazione di nuove directory (procedimento
-descritto in \secref{sec:file_dir_creat_rem}).
+Vedremo in \secref{sec:file_base_func} con quali funzioni si possono creare
+nuovi file, in tale occasione vedremo che è possibile specificare in sede di
+creazione quali permessi applicare ad un file, però non si può indicare a
+quale utente e gruppo esso deve appartenere. Lo stesso problema di presenta
+per la creazione di nuove directory (procedimento descritto in
+\secref{sec:file_dir_creat_rem}).
Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
all'\textit{effective user id} del processo che lo crea; per il \acr{gid}
Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
automaticamente propagato, restando coerente a quello della directory di
-partenza, in tutte le sottodirectory. La semantica SVr4 offre una maggiore
-possibilità di scelta, ma per ottenere lo stesso risultato necessita che per
-le nuove directory venga anche propagato anche il bit \acr{sgid}. Questo è
-comunque il comportamento di default di \func{mkdir}, ed é in questo modo ad
-esempio che Debian assicura che le sottodirectory create nelle home di un
-utente restino sempre con il \acr{gid} del gruppo primario dello stesso.
+partenza, in tutte le sottodirectory. La semantica SVr4 offre la possibilità
+di scegliere, ma per ottenere lo stesso risultato di coerenza che si ha con
+BSD necessita che per le nuove directory venga anche propagato anche il bit
+\acr{sgid}. Questo è il comportamento di default di \func{mkdir}, ed è in
+questo modo ad esempio che Debian assicura che le sottodirectory create nelle
+home di un utente restino sempre con il \acr{gid} del gruppo primario dello
+stesso.
\subsection{La funzione \func{access}}
\label{sec:file_access}
-Come detto in \secref{sec:file_access_control} il controllo di accesso ad
-un file viene fatto usando \textit{effective user id} e \textit{effective
- group id} del processo, ma ci sono casi in cui si può voler effettuare il
-controllo usando il \textit{real user id} e il \textit{real group id} (cioè
-l'\acr{uid} dell'utente che ha lanciato il programma, che, come accennato in
-\secref{sec:file_suid_sgid} e spiegato in \secref{sec:proc_perms} non è
-detto sia uguale all'\textit{effective user id}). Per far questo si può usare
-la funzione \func{access}, il cui prototipo è:
+Come visto in \secref{sec:file_access_control} il controllo di accesso ad un
+file viene fatto usando \textit{effective user id} e \textit{effective group
+ id} del processo; ma ci sono casi in cui è necessario effettuare il
+controllo usando il \textit{real user id} ed il \textit{real group id} (cioè
+\acr{uid} e \acr{gid} dell'utente che ha lanciato il programma, e che, come
+accennato in \secref{sec:file_suid_sgid} e spiegato in
+\secref{sec:proc_perms}, non è detto siano uguali agli \textit{effective id}).
+Per far questo si può usare la funzione \func{access}, il cui prototipo è:
\begin{prototype}{unistd.h}
{int access(const char *pathname, int mode)}
\macro{EIO}.}
\end{prototype}
-I valori possibili per il parametro \var{mode} sono esprimibili come
+I valori possibili per l'argomento \param{mode} sono esprimibili come
combinazione delle costanti numeriche riportate in \ntab\ (attraverso un OR
binario). I primi tre valori implicano anche la verifica dell'esistenza del
file, se si vuole verificare solo quest'ultima si può usare \macro{F\_OK}, o
\hline
\end{tabular}
\caption{Valori possibile per il parametro \var{mode} della funzione
- \func{access}}
+ \func{access}.}
\label{tab:file_access_mode_val}
\end{table}
Un esempio tipico per l'uso di questa funzione è quello di un processo che sta
-eseguendo un programma coi privilegi di un altro utente (attraverso l'uso del
-\acr{suid} bit) che vuole controllare se l'utente originale ha i permessi per
-accedere ad un certo file.
+eseguendo un programma coi privilegi di un altro utente (ad esmepio attraverso
+l'uso del \acr{suid} bit) che vuole controllare se l'utente originale ha i
+permessi per accedere ad un certo file.
\subsection{Le funzioni \func{chmod} e \func{fchmod}}
\label{sec:file_chmod}
Per cambiare i permessi di un file il sistema mette ad disposizione due
-funzioni, che operano rispettivamente su un filename e su un file descriptor,
-i loro prototipi sono:
+funzioni \func{chmod} e \func{fchmod}, che operano rispettivamente su un
+filename e su un file descriptor, i loro prototipi sono:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/stat.h}
anche se si è proprietari del file non tutte le operazioni sono permesse, in
particolare:
\begin{enumerate}
-\item siccome solo l'amministratore può settare lo \textit{sticky bit}; se
+\item siccome solo l'amministratore può settare lo \textit{sticky bit}, se
l'\textit{effective user id} del processo non è zero esso viene
automaticamente cancellato (senza notifica di errore) qualora sia stato
indicato in \var{mode}.
-\item per via della semantica SVR4 nella creazione dei nuovi file, si può
+\item per via della semantica SVr4 nella creazione dei nuovi file, si può
avere il caso in cui il file creato da un processo è assegnato a un gruppo
per il quale il processo non ha privilegi. Per evitare che si possa
assegnare il bit \acr{sgid} ad un file appartenente a un gruppo per cui
Per alcuni filesystem\footnote{il filesystem \acr{ext2} supporta questa
caratteristica, che è mutuata da BSD.} è inoltre prevista una ulteriore
-misura di sicurezza, volta ad scongiurare l'abuso dei bit \acr{suid} e
+misura di sicurezza, volta a scongiurare l'abuso dei bit \acr{suid} e
\acr{sgid}; essa consiste nel cancellare automaticamente questi bit qualora un
processo che non appartenga all'amministratore scriva su un file. In questo
modo anche se un utente malizioso scopre un file \acr{suid} su cui può
-scrivere, un eventuale modifica comporterà la perdita di ogni ulteriore
+scrivere, un'eventuale modifica comporterà la perdita di ogni ulteriore
privilegio.
\subsection{La funzione \func{umask}}
delle poche funzioni che non restituisce codici di errore.}
\end{prototype}
-Questa maschera è una caratteristica di ogni processo e viene utilizzata per
-impedire che alcuni permessi possano essere assegnati ai nuovi file in sede di
-creazione, i bit indicati nella maschera vengono infatti esclusi quando un
-nuovo file viene creato.
+Questa maschera è una caratteristica di ogni processo\footnote{è infatti
+ contenuta nel campo \var{umask} di \var{fs\_struct}, vedi
+ \figref{fig:proc_task_struct}.} e viene utilizzata per impedire che alcuni
+permessi possano essere assegnati ai nuovi file in sede di creazione. I bit
+indicati nella maschera vengono infatti esclusi quando un nuovo file viene
+creato.
In genere questa maschera serve per impostare un default che escluda alcuni
permessi (usualmente quello di scrittura per il gruppo e gli altri,
suo gruppo primario o uno dei gruppi a cui appartiene.
La funzione \func{chown} segue i link simbolici, per operare direttamente su
-in link simbolico si deve usare la funzione \func{lchown}\footnote{fino alla
+un link simbolico si deve usare la funzione \func{lchown}.\footnote{fino alla
versione 2.1.81 in Linux \func{chown} non seguiva i link simbolici, da
allora questo comportamento è stato assegnato alla funzione \func{lchown},
introdotta per l'occasione, ed è stata creata una nuova system call per
- \func{chown} che seguisse i link simbolici}. La funzione \func{fchown} opera
+ \func{chown} che seguisse i link simbolici.} La funzione \func{fchown} opera
su un file aperto, essa è mutuata da BSD, ma non è nello standard POSIX.
Un'altra estensione rispetto allo standard POSIX è che specificando -1 come
-valore per \var{owner} e \var{group} i valori restano immutati.
+valore per \var{owner} e \var{group} i valori restano immutati.
Quando queste funzioni sono chiamate con successo da un processo senza i
privilegi di root entrambi i bit \acr{suid} e \acr{sgid} vengono
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.
+di lavoro corrente, ha anche una directory radice,\footnote{entrambe sono
+ contenute in due campi di \var{fs\_struct}, vedi
+ \figref{fig:proc_task_struct}.} 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, 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
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.
-
+Questo è il motivo per cui la funzione è efficace solo se dopo averla eseguita
+si cedono i privilegi di root. Infatti se in qualche modo il processo ha una
+directory di lavoro corrente fuori dalla \textit{chroot jail}, potrà comunque
+accedere a tutto il filesystem usando pathname relativi.
+
+Ma quando ad un processo restano i privilegi di root esso potrà sempre portare
+la directory di lavoro corrente fuori dalla \textit{chroot jail} creando una
+sottodirectory ed eseguendo una \func{chroot} su di essa. Per questo motivo
+l'uso di questa funzione non ha molto senso quando un processo necessita dei
+privilegi di root per le sue normali operazioni.
+
+Un caso tipico di uso di \func{chroot} è quello di un server ftp anonimo, in
+questo caso infatti si vuole che il server veda solo i file che deve
+trasferire, per cui in genere si esegue una \func{chroot} sulla 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