Finito umask, chmod & C.
[gapil.git] / filedir.tex
index 0c06fb26974db6e1d41aba5629dc4856e0958d6e..0ee1b396f777da6e1848c3207554e051495fef7f 100644 (file)
@@ -45,27 +45,27 @@ 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 \textsl{w},
-\textit{r} \textsl{x}) ed applicabili rispettivamente al proprietario, al
-gruppo, a tutti.  I restanti tre bit (\textsl{suid}, \textsl{sgid}, e
+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 (\textsl{suid}, \textsl{sgid}, e
 \textsl{sticky}) sono usati per indicare alcune caratteristiche più complesse
 su cui torneremo in seguito (vedi \secref{sec:filedir_suid_sgid} e
 \secref{sec:filedir_sticky}).
 
-Anche i permessi sono tenuti per ciascun file (di qualunque tipo, quindi anche
-per le fifo, i socket e i file di dispositivo) nell'inode, in opportuni bit
-del campo \var{st\_mode} della struttura letta da \func{stat} (vedi
-\figref{fig:filedir_stat_struct}). 
-
-In genere ci si riferisce a questi permessi usando le lettere \textsl{u} (per
-\textit{user}), \textsl{g} (per \textit{group}) e \textsl{o} (per
-\textit{other}), inoltre se si vuole indicare tutti questi gruppi insieme si
-usa la lettera \textsl{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 di owner, group ed all, le cui
-iniziali possono da luogo a confusione. Le costanti che permettono di accedere
-al valore numerico di questi bit nel campo \var{st\_mode} sono riportate in
-\ntab.
+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:filedir_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.
 
 \begin{table}[htb]
   \centering
@@ -133,10 +133,10 @@ regolari possono essere 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; anche utente e gruppo a cui appartiene vengono
-ignorati quando il link viene risolto, vengono controllati sono quando viene
+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 (vedi \secref{sec:filedir_sticky}).
+\textsl{sticky bit} settato (si veda \secref{sec:filedir_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
@@ -201,6 +201,7 @@ 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.
 
+
 \subsection{I bit \textsl{suid} e \textsl{sgid}}
 \label{sec:filedir_suid_sgid}
 
@@ -236,7 +237,8 @@ parte con i privilegi di root.
 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 (torneremo sull'argomento in
-\secref{sec:prochand_perms}).
+\secref{sec:prochand_perms}) per evitare che possano essere usati per
+guadagnare privilegi non consentiti.
 
 La presenza dei bit \textsl{suid} e \textsl{sgid} su un file può essere
 rilevata con il comando \cmd{ls -l}, in tal caso comparirà la lettera \cmd{s}
@@ -248,24 +250,26 @@ questi bit. Infine questi bit possono essere controllati all'interno di
 \tabref{tab:filedir_file_mode_flags}.
 
 Gli stessi bit vengono ad assumere in significato completamente diverso per le
-directory, normalmente infatti Linux usa la convezione di SVR4 per indicare
+directory, normalmente infatti Linux usa la convenzione di SVR4 per indicare
 con questi bit l'uso della semantica BSD nella creazione di nuovi file (si
-veda \secref{sec:filedir_ownership} per una spiegazione al proposito).
+veda \secref{sec:filedir_ownership} per una spiegazione dettagliata al
+proposito).
 
 Infine Linux utilizza il bit \textsl{sgid} per una ulteriore estensione
-mutuata da SVR4; il caso in cui il file abbia il bit \textsl{sgid} settato ma
-non il corrispondente bit per l'esecuzione viene infatti utilizzato per
-attivare per quel file il \textit{mandatory locking} (argomento che
-affronteremo nei dettagli in \secref{sec:xxx_mandatory_lock}).
+mutuata da SVR4. Il caso in cui il file abbia il bit \textsl{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:xxx_mandatory_lock}).
+
 
 \subsection{Il bit \textsl{sticky}}
 \label{sec:filedir_sticky}
 
-L'ultimo dei bit rimanenti, identificato dalla costante \macro{S\_ISVTX} è in
+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
 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.  
+si poteva settare questo bit.
 
 L'effetto di questo bit era che il segmento di testo del programma (si veda
 \secref{sec:proc_mem_layout} per i dettagli) veniva scritto nella swap la
@@ -275,39 +279,42 @@ continuo indicizzato direttamente in questo modo si poteva risparmiare in
 tempo di caricamento rispetto alla ricerca del file su disco.
 
 Ovviamente per evitare che gli utenti potessero intasare la swap solo
-l'amministratore era in grado di settare questo bit, che venne poi chiamato
-anche \textit{saved text bit}, da cui deriva il nome della costante. Le
-attuali implementazioni di memoria virtuale e filesystem rendono
-sostanzialmente inutile questo procedimento.
+l'amministratore era in grado di settare questo bit, che venne chiamato anche
+\textit{saved text bit}, da cui deriva il nome della costante. Le attuali
+implementazioni di memoria virtuale e filesystem rendono sostanzialmente
+inutile questo procedimento. Lo \textsl{sticky bit} è indicato attraverso la
+lettera \cmd{t} al posto della \cmd{x} nei permessi per gli altri.
 
 Benché ormai non venga più utilizzato per i file, lo \textsl{sticky bit} ha
-invece assunto un uso corrente per le directory\footnote{lo \textsl{sticky
-    bit} è una estensione non definita nello standard POSIX, Linux però la
-  supporta, così come BSD e SVR4}, se il bit è settato infatti un file può
-essere rimosso dalla directory soltanto se l'utente ha il permesso di
-scrittura ed inoltre è vera una delle seguenti condizioni:
+assunto un uso corrente per le directory\footnote{lo \textsl{sticky bit} è 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:
 \begin{itemize}
 \item l'utente è proprietario del file
 \item l'utente è proprietario della directory
 \item l'utente è l'amministratore 
 \end{itemize}
-il classico esempio di directory che ha questo bit settato è \file{/tmp}, i
+un classico esempio di directory che ha questo bit settato è \file{/tmp}, i
 permessi infatti di solito sono settati come:
 \begin{verbatim}
 drwxrwxrwt    6 root     root         1024 Aug 10 01:03 /tmp
 \end{verbatim}
-in questo modo chiunque può leggere, scrivere ed eseguire i file, o crearne di
-nuovi, ma solo l'utente che ha creato un file nella directory potrà
-cancellarlo o rinominarlo.
+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, evitando così che utente
+possa, più o meno consapevolemnte, cancellare i file degli altri.
+
 
 \subsection{La titolarità di nuovi file e directory}
 \label{sec:filedir_ownership}
 
 Vedremo in \secref{sec:fileunix_base_func} quali sono le funzioni per creare
 nuovi file, ma se è possibile specificare in sede di creazione quali permessi
-applicare ad un nuovo file, non si può indicare a quale utente e gruppo deve
-appartenere. Lo stesso problema di presenta per la creazione di nuove
-directory (descritto in \secref{sec:filedir_dir_creat_rem}).
+applicare ad un nuovo 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:filedir_dir_creat_rem}).
 
 Lo standard POSIX prescrive che l'uid del nuovo file corrisponda
 all'\textit{effective user id} del processo che lo crea; per il gid invece
@@ -316,17 +323,17 @@ prevede due diverse possibilit
 \item il gid del file corrisponde all'\textit{effective group id} del processo
 \item il gid del file corrisponde al gid della directory in cui esso è creato
 \end{itemize}
-in genere BSD usa sempre la seconda possibilità, che viene per questo anche
-chiamata semantica BSD. Linux invece segue quella che viene chiamata semantica
-SVR4; di norma cioè il nuovo file viene creato con il gid del processo, se
-però la directory in cui viene creato il file ha il bit sgid settato allora
-viene usato il gid di quest'ultima.
+in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
+semantica BSD. Linux invece segue quella che viene chiamata semantica SVR4; di
+norma cioè il nuovo file viene creato, seguendo la prima opzione, con il gid
+del processo, se però la directory in cui viene creato il file ha il bit sgid
+settato allora viene usata la seconda opzione..
 
 Usare la semantica BSD ha il vantaggio che il 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
+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 sgid, questo è comunque il comportamento di
+anche propagato anche il bit 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 gid
 del gruppo primario dello stesso.
@@ -395,44 +402,193 @@ suid bit) che vuole controllare se l'utente originale ha i permessi per
 accedere ad un certo file.
 
 
+\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
+\label{sec:filedir_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 cui prototipi sono:
+
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/stat.h} 
+  
+  \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del
+  file indicato da \var{path} al valore indicato da \var{mode}.
+  
+  \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa
+  il file descriptor \var{fd} per indicare il file.
+
+  Le funzioni restituiscono 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 corrisponde a quello
+    del proprietario del file o non è zero.
+  \end{errlist}
+  Oltre a questi entrambe restituiscono gli errori \macro{EROFS} e
+  \macro{EIO}; \func{chmod} restituisce anche \macro{EFAULT},
+  \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ENOTDIR},
+  \macro{EACCES}, \macro{ELOOP}; \func{chmod} anche \macro{EBADF}.
+\end{functions}
+
+I valori possibili per \var{mode} sono indicati in \ntab. I valori possono
+esser combinati con l'OR binario delle relative macro, o specificati
+direttamente, come per l'analogo comando di shell, con il valore ottale. Ad
+esempio i permessi standard assegnati ai nuovi file (lettura e scrittura per
+il proprietario, sola lettura per il gruppo e gli altri) sono corrispondenti
+al valore ottale $0644$, un programma invece avrebbe anche il bit di
+esecuzione attivo, con un valore di $0755$, se si volesse attivare il bit suid
+il valore da fornire sarebbe $4755$.
+
+\begin{table}[!htb]
+  \centering
+  \begin{tabular}[c]{|c|c|l|}
+    \hline
+    \var{mode} & Valore & Significato \\
+
+    \hline
+    \hline
+    \macro{S\_ISUID} & 04000 & set user ID \\
+
+    \macro{S\_ISGID} & 02000 & set group ID \\
+    
+    \macro{S\_ISVTX} & 01000 & sticky bit \\
+
+    \hline
+    \macro{S\_IRWXU} & 00700 & l'utente ha tutti i permessi \\
+
+    \macro{S\_IRUSR} & 00400 & l'utente ha il permesso di lettura  \\
+
+    \macro{S\_IWUSR} & 00200 & l'utente ha il permesso di scrittura \\
+
+    \macro{S\_IXUSR} & 00100 & l'utente ha il permesso di esecuzione \\
+
+    \hline
+    \macro{S\_IRWXG} & 00070 & il gruppo ha tutti i permessi  \\
+
+    \macro{S\_IRGRP} & 00040 & il gruppo ha il permesso di lettura  \\
+
+    \macro{S\_IWGRP} & 00020 & il gruppo ha il permesso di scrittura \\
+
+    \macro{S\_IXGRP} & 00010 & il gruppo ha il permesso di esecuzione \\
+
+    \hline
+    \macro{S\_IRWXO} & 00007 & gli altri hanno tutti i permessi \\
+
+    \macro{S\_IROTH} & 00004 & gli altri hanno il permesso di lettura  \\
+
+    \macro{S\_IWOTH} & 00002 & gli altri hanno il permesso di scrittura \\
+
+    \macro{S\_IXOTH} & 00001 & gli altri hanno il permesso di esecuzione \\
+
+    \hline
+  \end{tabular}
+  \caption{I valori delle costanti usate per indicare i permessi dei file.}
+  \label{tab:filedir_permission_const}
+\end{table}
+
+Il cambiamento dei permessi di un file attraverso queste funzioni ha comunque
+alcune limitazioni, provviste per motivi di sicurezza. Questo significa che
+anche se si è proprietari del file non tutte le operazioni sono permesse, in
+particolare:
+\begin{itemize}
+\item siccome solo l'amministratore può settare lo \textit{sticky bit} se 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ò
+  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 \textsl{sgid} ad un file appartenente a un gruppo per cui
+  non si hanno diritti, questo viene automaticamente cancellato (senza
+  notifica di errore) da \var{mode} qualora il gruppo del file non corrisponda
+  a quelli associati al processo (la cosa non avviene quando
+  l'\textit{effective user id} del processo è zero).
+\end{itemize}
+
+Per alcuni filesystem\footnote{il filesystem \textsl{ext2} supporta questa
+  caratteristica, che è mutuata da BSD.} è inoltre prevista una ulteriore
+misura di sicurezza, volta ad scongiurare l'abuso dei bit \textsl{suid} e
+\textsl{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 \textsl{suid} su cui può
+scrivere, un eventuale modifica comporterà la perdita di ogni ulteriore
+privilegio.
+
+
 \subsection{La funzione \texttt{umask}}
 \label{sec:filedir_umask}
 
 Oltre che dai valori indicati in sede di creazione, i permessi assegnati ai
 nuovi file sono controllati anche da una maschera di bit settata con la
-funzione \func{umask}. Questa viene utilizzata per impedire che alcuni
-permessi possano essere assegnati ai nuovi file, tutti i bit indicati nella
-maschera vengono infatti esclusi quando un nuovo file viene creato.
+funzione \func{umask}, il cui prototipo è:
 
+\begin{prototype}{stat.h}
+{mode\_t umask(mode\_t mask)}
 
-\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
-\label{sec:filedir_chmod}
+  Setta la maschera dei permessi dei bit al valore specificato da \var{mask}
+  (di cui vengono presi solo i 9 bit meno significativi).
+  
+  La funzione ritorna il precedente valore della maschera. È una delle poche
+  funzioni che non restituisce codici di errore.
+\end{prototype}
 
-Per cambiare i permessi di un file il sistema mette ad disposizione due
-funzioni, che operano rispettivamente su un filename e un file descriptor, i
-prototipi sono:
+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.
+
+In genere questa maschera serve per impostare un default che escluda alcuni
+permessi (usualmente quello di scrittura per il gruppo e gli altri,
+corrispondente ad un valore di $022$). Essa è utile perché le routine
+dell'interfaccia ANSI C degli stream non prevedono l'esistenza dei permessi, e
+pertanto tutti i nuovi file vengono sempre creati con un default di $666$
+(cioè permessi di lettura e scrittura per tutti, si veda
+\tabref{tab:filedir_permission_const} per un confronto); in questo modo è
+possibile cancellare automaticamente i permessi non voluti, senza doverlo fare
+esplicitamente.
+
+In genere il valore di \func{umask} viene stabilito una volta per tutte al
+login, e di norma gli utenti non hanno motivi per modificarlo. Se però si
+vuole che un processo possa creare un file che chiunque possa leggere allora
+occorrerà cambiare il valore di \func{umask}.
+
+\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
+\label{sec:filedir_chown}
+
+Come per i permessi, il sistema fornisce anche delle funzioni che permettano
+di cambiare utente e gruppo cui il file appartiene; le funzioni in questioni
+sono tre e i loro prototipi sono i seguenti:
 
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/stat.h} 
   
   \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del
-  file indicato da \var{path} al valore indicato da \var{mode}
+  file indicato da \var{path} al valore indicato da \var{mode}.
   
-  \funcdecl{chmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa il
-  file descriptor \var{fd} per indicare il file.
-
+  \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa
+  il file descriptor \var{fd} per indicare il file.
 
   Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
   caso di errore \texttt{errno} viene settato ai valori:
   \begin{errlist}
-  \item \texttt{EPERM} L'uid non corrisponde a quello del file o non è zero.
+  \item \macro{EPERM} L'\textit{effective user id} non corrisponde a quello
+    del proprietario del file o non è zero.
   \end{errlist}
+  Oltre a questi entrambe restituiscono gli errori \macro{EROFS} e
+  \macro{EIO}; \func{chmod} restituisce anche \macro{EFAULT},
+  \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ENOTDIR},
+  \macro{EACCES}, \macro{ELOOP}; \func{chmod} anche \macro{EBADF}.
 \end{functions}
 
 
-\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
-\label{sec:filedir_chown}
+
+
+
+
+
+
 
 
 
@@ -482,13 +638,8 @@ i seguenti:
   descriptor \var{filedes}.
   
   Le funzioni restituiscono zero in caso di successo e -1 per un errore, in
-  caso di errore \texttt{errno} viene settato ai valori:
-  \begin{errlist}
-  \item \texttt{EACCESS} non c'è il permesso di accedere al file.
-  \item \texttt{ENOTDIR} una componente del pathname non è una directory.
-  \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
-    completare l'operazione. 
-  \item \texttt{ENAMETOOLONG} il filename è troppo lungo.
+  caso di errore \texttt{errno} viene settato ai valori \macro{EACCESS}, 
+  \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ENAMETOOLONG}.
   \end{errlist}
 \end{functions}