X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=filedir.tex;h=f413356e1bbe840c00e38120cae29e80fab32989;hb=0b501298da2110ee71c619dde324bb7a4e04ddda;hp=d9afc5c4f6a4207a20759763484ef94a976ea43c;hpb=7c9875b4a227993152d4f28dd2620006a224ac5b;p=gapil.git diff --git a/filedir.tex b/filedir.tex index d9afc5c..f413356 100644 --- a/filedir.tex +++ b/filedir.tex @@ -16,10 +16,11 @@ 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 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. +prenderemo in esame la struttura di base del sistema delle protezioni e del +controllo dell'accesso ai file e le successive estensioni (\textit{Extended + Attributes}, ACL, quote disco, \textit{capabilities}). Tutto quello che +riguarda invece la manipolazione del contenuto dei file è lasciato ai capitoli +successivi. @@ -41,8 +42,8 @@ riguarda il comportamento e gli effetti delle varie funzioni. \label{sec:file_link} Una caratteristica comune a diversi sistemi operativi è quella di poter creare -dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows o i -nomi logici del VMS) che permettono di fare riferimento allo stesso file +dei nomi fittizi (come gli alias del vecchio MacOS o i collegamenti di Windows +o i nomi logici del VMS) 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 @@ -1483,7 +1484,7 @@ il suo prototipo è: \end{errlist}} \end{prototype} -La funzionne genera un nome univoco sostituendo le \code{XXXXXX} finali di +La funzionane genera un nome univoco sostituendo le \code{XXXXXX} finali di \param{template}; dato che \param{template} deve poter essere modificata dalla funzione non si può usare una stringa costante. Tutte le avvertenze riguardo alle possibili \itindex{race~condition} \textit{race condition} date per @@ -1596,7 +1597,7 @@ funzioni \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui prototipi sono: \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.} \end{functions} -La funzione \func{stat} legge le informazion del file il cui pathname è +La funzione \func{stat} legge le informazioni del file il cui pathname è specificato dalla stringa puntata da \param{file\_name} e le inserisce nel buffer puntato dall'argomento \param{buf}; la funzione \func{lstat} è identica a \func{stat} eccetto che se \param{file\_name} è un link simbolico vengono @@ -1792,9 +1793,9 @@ dimensione si possono usare le due funzioni \funcd{truncate} e \errval{EROFS}, \errval{EIO}, \errval{EFAULT}, \errval{ELOOP}.} \end{functions} -Emtrambe le funzioni fan sì che la dimensione del file sia troncata ad un +Entrambe le funzioni fan sì che la dimensione del file sia troncata ad un valore massimo specificato da \param{length}, e si distinguono solo per il -fatto che il file viene indicato con il pathame \param{file\_name} per +fatto che il file viene indicato con il pathname \param{file\_name} per \func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; se il file è più lungo della lunghezza specificata i dati in eccesso saranno perduti. @@ -1805,7 +1806,7 @@ lunghezza scelta; nel caso di Linux viene esteso con la creazione di un \index{file!\textit{hole}} \textsl{buco} nel \itindex{sparse~file} file e ad una lettura si otterranno degli zeri; si tenga presente però che questo comportamento è supportato solo per filesystem nativi, ad esempio su un -filesystem non nativo come il VFAT di windows questo non è possibile. +filesystem non nativo come il VFAT di Windows questo non è possibile. \subsection{I tempi dei file} \label{sec:file_file_times} @@ -1995,7 +1996,7 @@ I tempi di ultimo accesso e modifica possono essere modificati esplicitamente usando la funzione \funcd{utime}, il cui prototipo è: \begin{prototype}{utime.h} {int utime(const char *filename, struct utimbuf *times)} - Modidica i tempi di ultimo accesso e modifica di un file. + Modifica i tempi di ultimo accesso e modifica di un file. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: @@ -2057,7 +2058,7 @@ precisione; il suo prototipo è: \begin{prototype} {sys/time.h} {int utimes(const char *filename, struct timeval times[2])} - Modidica i tempi di ultimo accesso e modifica di un file. + Modifica i tempi di ultimo accesso e modifica di un file. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: @@ -2708,7 +2709,7 @@ in particolare accade che: \end{enumerate} Per alcuni filesystem\footnote{i filesystem più comuni (\textsl{ext2}, - \textsl{ext3}, \textsl{ext4}, \textsl{reiserfs}) supportano questa + \textsl{ext3}, \textsl{ext4}, \textsl{ReiserFS}) supportano questa caratteristica, che è mutuata da BSD.} è inoltre prevista un'ulteriore misura di sicurezza, volta a scongiurare l'abuso dei \itindex{suid~bit} bit \acr{suid} e \acr{sgid}; essa consiste nel cancellare automaticamente questi @@ -4096,7 +4097,6 @@ ACL di default associata a \func{path}.\footnote{questo però è una estensione \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EBADF}]. \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type} ha in valore non corretto. \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i @@ -4147,6 +4147,359 @@ ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con \itindend{Access~Control~List} +\subsection{La gestione delle quote disco} +\label{sec:disk_quota} + +Quella delle quote disco è una funzionalità introdotta inizialmente da BSD, e +presente in Linux fino dai kernel dalla serie 2.0, che consente di porre dei +tetti massimi al consumo delle risorse di un filesystem (spazio disco e +\textit{inode}) da parte di utenti e gruppi. Dato che la funzionalità ha senso +solo per i filesystem su cui si mantengono i dati degli utenti\footnote{in + genere la si attiva sul filesystem che contiene le \textit{home} degli + utenti, dato che non avrebbe senso per i file di sistema che in genere + appartengono all'amministratore.} essa deve essere esplicitamente richiesta; +questo si fa tramite due distinte opzioni di montaggio, \texttt{usrquota} e +\texttt{grpquota} che abilitano le quote rispettivamente per gli utenti e per +i gruppi. Grazie a questo è possibile usare le limitazioni sulle quote solo +sugli utenti o solo sui gruppi. + +Il meccanismo prevede che per ciascun filesystem che supporta le quote disco +(i vari \textit{extN}, \textit{btrfs}, \textit{XFS}, \textit{JFS}, +\textit{ReiserFS}) il kernel provveda sia a mantenere aggiornati i dati +relativi al consumo delle risorse da parte di utenti e/o gruppi che a far +rispettare i limiti imposti dal sistema, con la generazione di un errore di +\errval{EDQUOT} per tutte le operazioni sui file che porterebbero ad un +superamento degli stessi. Si tenga presente che questi due compiti sono +separati, il primo si attiva al montaggio del filesystem con le quote +attivate, il secondo deve essere abilitato esplicitamente. + +Per il mantenimento dei dati di consumo delle risorse vengono usati due file +riservati (uno per le quote utente e l'altro per le quote gruppo) nella +directory radice del filesystem su cui si sono attivate le quote;\footnote{la + cosa vale per tutti i filesystem tranne \textit{XFS} che mantiene i dati + internamente.} con la versione 2 del supporto delle quote, l'unica rimasta +in uso, questi file sono \texttt{aquota.user} e \texttt{aquota.group}, in +precedenza erano \texttt{quota.user} e \texttt{quota.group}. Dato che i file +vengono aggiornati soltanto se il filesystem è stato montato con il supporto +delle quote, se si abilita questo in un secondo tempo (o se si eseguono +operazioni sul filesystem senza averlo abilitato) i dati contenuti possono non +corrispondere esattamente allo stato corrente del consumo delle risorse; per +questo in genere prima di montare in scrittura un filesystem su cui sono +abilitate le quote in genere viene utilizzato il comando \cmd{quotacheck} per +verificare e aggiornare i dati. + +Le restrizioni sul consumo delle risorse prevedono due limiti, il primo viene +detto \textit{soft limit} e può essere superato per brevi periodi di tempo, il +secondo viene detto \textit{hard limit} non può mai essere superato. Il +periodo di tempo per cui è possibile superare il \textit{soft limit} è detto +``\textsl{periodo di grazia}'' (\textit{grace period}), passato questo tempo +il passaggio del \textit{soft limit} viene trattato allo stesso modo +dell'\textit{hard limit}. Questi limiti riguardano separatamente sia lo +spazio disco (i blocchi) che il numero di file (gli \textit{inode}) e devono +pertanto essere specificati per entrambe le risorse. + +La funzione che consente di controllare tutti i vari aspetti della gestione +delle quote è \funcd{quotactl}, ed il suo prototipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/quota.h} + + \funcdecl{quotactl(int cmd, const char *dev, int id, caddr\_t addr)} + + Esegue una operazione di controllo sulle quote disco. + + \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCES}] il file delle quote non è un file ordinario. + \item[\errcode{EBUSY}] si è richiesto \const{Q\_QUOTAON} ma le quote sono + già attive. + \item[\errcode{EFAULT}] l'indirizzo \param{addr} non è valido. + \item[\errcode{EIO}] errore di lettura/scrittura sul file delle quote. + \item[\errcode{EMFILE}] non si può aprire il file delle quote avendo + superato il limite sul numero di file aperti nel sistema. + \item[\errcode{EINVAL}] o \param{cmd} non è un comando valido, + o il dispositivo \param{dev} non esiste. + \item[\errcode{ENODEV}] \param{dev} non corrisponde ad un \textit{mount + point} attivo. + \item[\errcode{ENOPKG}] il kernel è stato compilato senza supporto per le + quote. + \item[\errcode{ENOTBLK}] \param{dev} non è un dispositivo a blocchi. + \item[\errcode{EPERM}] non si hanno i permessi per l'operazione richiesta. + \item[\errcode{ESRCH}] è stato richiesto uno fra \const{Q\_GETQUOTA}, + \const{Q\_SETQUOTA}, \const{Q\_SETUSE}, \const{Q\_SETQLIM} per un + filesystem senza quote attivate. + \end{errlist} +} +\end{functions} + +La funzione richiede che il filesystem sul quale si vuole operare sia montato +con il supporto delle quote abilitato; esso deve essere specificato con il +nome del file di dispositivo nell'argomento \param{dev}. Per le operazioni che +lo richiedono inoltre si dovrà indicare con l'argomento \param{id} l'utente o +il gruppo (specificati rispettivamente per \acr{uid} e \acr{gid}) su cui si +vuole operare. Alcune operazioni usano l'argomento \param{addr} per indicare +un indirizzo ad un area di memoria il cui utilizzo dipende dall'operazione +stessa. + +Il tipo di operazione che si intende effettuare deve essere indicato tramite +il primo argomento \param{cmd}, questo in genere viene specificato con +l'ausilio della macro \macro{QCMD}: +\begin{functions} + \funcdecl{int QCMD(subcmd,type)} Imposta il comando \param{subcmd} per il + tipo di quote (utente o gruppo) \param{type}. +\end{functions} +\noindent che consente di specificare, oltre al tipo di operazione, se questa +deve applicarsi alle quote utente o alle quote gruppo, nel qual +caso \param{type} deve essere rispettivamente \const{USRQUOTA} o +\const{GRPQUOTA}. + + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Comando} & \textbf{Descrizione} \\ + \hline + \hline + \const{Q\_QUOTAON} & Attiva l'applicazione delle quote disco per il + filesystem indicato da \param{dev}, si deve passare + in \param{addr} il pathname al file che mantiene le + quote, che deve esistere, e \param{id} deve indicare + la versione del formato con uno dei valori di + tab.~\ref{tab:quotactl_id_format}; l'operazione + richiede i privilegi di amministratore.\\ + \const{Q\_QUOTAOFF} & Disattiva l'applicazione delle quote disco per il + filesystem indicato da \param{dev}, \param{id} + e \param{addr} vengono ignorati; l'operazione + richiede i privilegi di amministratore.\\ + \const{Q\_GETQUOTA} & Legge i limiti ed i valori correnti delle quote nel + filesystem indicato da \param{dev} per l'utente o + il gruppo specificato da \param{id}; si devono avere + i privilegi di amministratore per leggere i dati + relativi ad altri utenti o a gruppi di cui non si fa + parte, il risultato viene restituito in una struttura + \struct{dqblk} all'indirizzo indicato + da \param{addr}.\\ + \const{Q\_SETQUOTA} & Imposta i limiti per le quote nel filesystem + indicato da \param{dev} per l'utente o il gruppo + specificato da \param{id} secondo i valori ottenuti + dalla struttura \struct{dqblk} puntata + da \param{addr}; l'operazione richiede i privilegi + di amministratore.\\ + \const{Q\_GETINFO} & Legge le informazioni (in sostanza i \textit{grace + time}) delle quote del filesystem indicato + da \param{dev} sulla struttura \struct{dqinfo} + puntata da \param{addr}, \param{id} viene ignorato.\\ + \const{Q\_SETINFO} & Imposta le informazioni delle quote del filesystem + indicato da \param{dev} come ottenuti dalla + struttura \struct{dqinfo} puntata + da \param{addr}, \param{id} viene ignorato; + l'operazione richiede i privilegi di amministratore.\\ + \const{Q\_GETFMT} & Richiede il valore identificativo (quello di + tab.~\ref{tab:quotactl_id_format}) per il formato + delle quote attualmente in uso sul filesystem + indicato da \param{dev}, che sarà memorizzato + sul buffer di 4 byte puntato da \param{addr}.\\ + \const{Q\_SYNC} & Aggiorna la copia su disco dei dati delle quote del + filesystem indicato da \param{dev}; in questo + caso \param{dev} può anche essere \val{NULL} nel + qual caso verranno aggiornati i dati per tutti i + filesystem con quote attive, \param{id} + e \param{addr} vengono comunque ignorati.\\ + \const{Q\_GETSTATS} & Ottiene statistiche ed altre informazioni generali + relative al sistema delle quote per il filesystem + indicato da \param{dev}, richiede che si + passi come argomento \param{addr} l'indirizzo di una + struttura \struct{dqstats}, mentre i valori + di \param{id} e \param{dev} vengono ignorati; + l'operazione è obsoleta e non supportata nei kernel + più recenti, che espongono la stessa informazione + nei file sotto \procfile{/proc/self/fs/quota/}.\\ +% \const{} & .\\ + \hline + \end{tabular} + \caption{Possibili valori per l'argomento \param{subcommand} di + \macro{QCMD}.} + \label{tab:quotactl_commands} +\end{table} + + +Le diverse operazioni supportate da \func{quotactl}, da indicare con +l'argomento \param{subcmd} di \macro{QCMD}, sono riportate in +tab.~\ref{tab:quotactl_commands}. In generale le operazione di attivazione, +disattivazione e di modifica dei limiti delle quote sono riservate e +richiedono i privilegi di amministratore.\footnote{per essere precisi tutte le + operazionie indicate come privilegiate in tab.~\ref{tab:quotactl_commands} + richiedono la \textit{capability} \const{CAP\_SYS\_ADMIN}.} Inoltre gli +utenti possono soltanto richiedere i dati relativi alle proprie quote, solo +l'amministratore può ottenere i dati di tutti. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Identificatore} & \textbf{Descrizione} \\ + \hline + \hline + \const{QFMT\_VFS\_OLD}& il vecchio (ed obsoleto) formato delle quote.\\ + \const{QFMT\_VFS\_V0} & la versione 0 usata dal VFS di Linux (supporta + \acr{uid} e \acr{gis} a 32 bit e limiti fino a + $2^{42}$ byte e $2^{32}$ file.\\ + \const{QFMT\_VFS\_V1} & la versione 1 usata dal VFS di Linux (supporta + \acr{uid} e \acr{gis} a 32 bit e limiti fino a + $2^{64}$ byte e $2^{64}$ file.\\ + \hline + \end{tabular} + \caption{Valori di identificazione del formato delle quote.} + \label{tab:quotactl_id_format} +\end{table} + +Alcuni dei comandi di tab.~\ref{tab:quotactl_commands} sono alquanto complessi +e richiedono un approfondimento maggiore, in particolare \const{Q\_GETQUOTA} e +\const{Q\_SETQUOTA} fanno riferimento ad una specifica struttura +\struct{dqblk}, la cui definizione è riportata in +fig.~\ref{fig:dqblk_struct},\footnote{la definizione mostrata è quella usata + fino dal kernel 2.4.22, non prenderemo in considerazione le versioni + obsolete.} nella quale vengono inseriti i dati relativi alle quote di un +singolo utente. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/dqblk.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{dqblk} per i dati delle quote disco.} + \label{fig:dqblk_struct} +\end{figure} + +La struttura viene usata sia con \const{Q\_GETQUOTA} per ottenere i valori +correnti dei limiti e dell'occupazione delle risorse, che con +\const{Q\_SETQUOTA} per effettuare modifiche ai limiti; come si può notare ci +sono alcuni campi (in sostanza \val{dqb\_curspace}, \val{dqb\_curinodes}, +\val{dqb\_btime}, \val{dqb\_itime}) che hanno senso solo in lettura in quanto +riportano uno stato non modificabile da \func{quotactl}, come l'uso corrente +di spazio e \textit{inode} o il tempo che resta nel caso si sia superato un +\textit{soft limit}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|p{10cm}|} + \hline + \textbf{Costante} & \textbf{Descrizione} \\ + \hline + \hline + \const{QIF\_BLIMITS}& Limiti sui blocchi di + spazio disco (\val{dqb\_bhardlimit} e + \val{dqb\_bsoftlimit}).\\ + \const{QIF\_SPACE} & Uso corrente + dello spazio disco (\val{dqb\_curspace}).\\ + \const{QIF\_ILIMITS}& Limiti sugli \textit{inode} + (\val{dqb\_ihardlimit} e \val{dqb\_isoftlimit}).\\ + \const{QIF\_INODES} & Uso corrente + degli \textit{inode} (\val{dqb\_curinodes}).\\ + \const{QIF\_BTIME} & Tempo di + sforamento del \textit{soft limit} sul numero di + blocchi (\val{dqb\_btime}).\\ + \const{QIF\_ITIME} & Tempo di + sforamento del \textit{soft limit} sul numero di + \textit{inode} (\val{dqb\_itime}).\\ + \const{QIF\_LIMITS} & L'insieme di \const{QIF\_BLIMITS} e + \const{QIF\_ILIMITS}.\\ + \const{QIF\_USAGE} & L'insieme di \const{QIF\_SPACE} e + \const{QIF\_INODES}.\\ + \const{QIF\_TIMES} & L'insieme di \const{QIF\_BTIME} e + \const{QIF\_ITIME}.\\ + \const{QIF\_ALL} & Tutti i precedenti.\\ + \hline + \end{tabular} + \caption{Costanti per il campo \val{dqb\_valid} di \struct{dqblk}.} + \label{tab:quotactl_qif_const} +\end{table} + + +Inoltre in caso di modifica di un limite si può voler operare solo su una +delle risorse (blocchi o \textit{inode});\footnote{non è possibile modificare + soltanto uno dei limiti (\textit{hard} o \textit{soft}, occorre sempre + rispecificarli entrambi.} per questo la struttura prevede un campo apposito, +\val{dqb\_valid}, il cui scopo è quello di indicare quali sono gli altri campi +che devono essere considerati validi. Questo campo è una maschera binaria che +deve essere espressa nei termini di OR aritmetico delle apposite costanti di +tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il significato di +ciascuna di esse ed i campi a cui fanno riferimento. + +In lettura con \const{Q\_SETQUOTA} eventuali valori presenti in \struct{dqblk} +vengono comunque ignorati, al momento la funzione sovrascrive tutti i campi e +li marca come validi in \val{dqb\_valid}. Si possono invece usare +\const{QIF\_BLIMITS} o \const{QIF\_ILIMITS} per richiedere di impostare solo +la rispettiva tipologia di limiti con \const{Q\_SETQUOTA}. Si tenga presente +che il sistema delle quote richiede che l'occupazione di spazio disco sia +indicata in termini di blocchi e non di byte; dato che questo dipende da come +si è creato il filesystem potrà essere necessario effettuare qualche +controllo.\footnote{in genere viene usato un default di 1024 byte per blocco, + ma quando si hanno file di dimensioni medie maggiori può convenire usare + valori più alti per ottenere prestazioni migliori in conseguenza di un + minore frazionamento dei dati e di indici più corti.} + +Altre due operazioni che necessitano di un approfondimento sono +\const{Q\_GETINFO} e \const{Q\_SETINFO}, che sostanzialmente consentono di +ottenere i dati relativi alle impostazioni delle altre proprietà delle quote, +che si riducono poi alla durata del \textit{grace time} per i due tipi di +limiti. In questo caso queste si proprietà generali sono identiche per tutti +gli utenti, per cui viene usata una operazione distinta dalle +precedenti. Anche in questo caso le due operazioni richiedono l'uso di una +apposita struttura \struct{dqinfo}, la cui definizione è riportata in +fig.~\ref{fig:dqinfo_struct}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/dqinfo.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{dqinfo} per i dati delle quote disco.} + \label{fig:dqinfo_struct} +\end{figure} + +Come per \struct{dqblk} anche in questo caso viene usato un campo della +struttura, \val{dqi\_valid} come maschera binaria per dichiarare quale degli +altri campi sono validi; le costanti usate per comporre questo valore sono +riportate in tab.~\ref{tab:quotactl_iif_const} dove si è riportato il +significato di ciascuna di esse ed i campi a cui fanno riferimento. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|l|} + \hline + \textbf{Costante} & \textbf{Descrizione} \\ + \hline + \hline + \const{IIF\_BGRACE}& Il \textit{grace period} per i blocchi + (\val{dqi\_bgrace}).\\ + \const{IIF\_IGRACE}& Il \textit{grace period} per gli \textit{inode} + (\val{dqi\_igrace}).\\ + \const{IIF\_FLAGS} & I flag delle quote (\val{dqi\_flags}) (inusato ?).\\ + \const{IIF\_ALL} & Tutti i precedenti.\\ + \hline + \end{tabular} + \caption{Costanti per il campo \val{dqi\_valid} di \struct{dqinfo}.} + \label{tab:quotactl_iif_const} +\end{table} + +Come in precedenza con \const{Q\_GETINFO} tutti i valori vengono letti +sovrascrivendo il contenuto di \struct{dqinfo} e marcati come validi in +\val{dqi\_valid}. In scrittura con \const{Q\_SETINFO} si può scegliere quali +impostare, si tenga presente che i tempi dei campi \val{dqi\_bgrace} e +\val{dqi\_igrace} devono essere specificati in secondi. + + +% TODO trattare quote disco +% vedi man quotactl \subsection{La gestione delle \textit{capabilities}} \label{sec:proc_capabilities} @@ -4186,19 +4539,19 @@ Il meccanismo completo delle \textit{capabilities}\footnote{l'implementazione si rifà ad una bozza di quello che doveva diventare lo standard POSIX.1e, poi abbandonato.} prevede inoltre la possibilità di associare le stesse ai singoli file eseguibili, in modo da poter stabilire quali capacità possono -essere utilizzate quando viene messo in esecuzione uno specifico programma; ma -il supporto per questa funzionalità, chiamata \textit{file capabilities}, è -stato introdotto soltanto a partire dal kernel 2.6.24. Fino ad allora doveva -essere il programma stesso ad eseguire una riduzione esplicita delle sue -capacità, cosa che ha reso l'uso di questa funzionalità poco diffuso, vista la -presenza di meccanismi alternativi per ottenere limitazioni delle capacità -dell'amministratore a livello di sistema operativo, come \index{SELinux} -SELinux. +essere utilizzate quando viene messo in esecuzione uno specifico programma +(una sorta di \acr{suid} anch'esso parcellizzato); ma il supporto per questa +funzionalità, chiamata \textit{file capabilities}, è stato introdotto soltanto +a partire dal kernel 2.6.24. Fino ad allora doveva essere il programma stesso +ad eseguire una riduzione esplicita delle sue capacità, cosa che ha reso l'uso +di questa funzionalità poco diffuso, vista la presenza di meccanismi +alternativi per ottenere limitazioni delle capacità dell'amministratore a +livello di sistema operativo, come \index{SELinux} SELinux. Con questo supporto e con le ulteriori modifiche introdotte con il kernel 2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente -rivoluzionato, rendendolo più aderente alle intezioni originali dello standard -POSIX, rimovendo il significato che fino ad allora aveva avuto la capacità +rivoluzionato, rendendolo più aderente alle intenzioni originali dello standard +POSIX, rimuovendo il significato che fino ad allora aveva avuto la capacità \macro{CAP\_SETPCAP} e le modalità di funzionamento del cosiddetto \itindex{capabilities~bounding~set} \textit{capabilities bounding set}. Ulteriori modifiche sono state apportate con il kernel 2.6.26 per @@ -4228,15 +4581,15 @@ L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui sono mantenuti i diversi insiemi di identificatori di sez.~\ref{sec:proc_setuid}; il loro significato, che è rimasto sostanzialmente -lo stesso anche dopo le modifiche seguite alla instroduzione delle +lo stesso anche dopo le modifiche seguite alla introduzione delle \textit{file capabilities} è il seguente: -\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}} +\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} \item[\textit{permitted}] l'insieme delle \textit{capabilities} ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo \textsl{può} impostare come \textsl{effettive} o come \textsl{ereditabili}. Se un processo cancella una capacità da questo insieme - non potrà più riassumerla.\footnote{questo è il comportamento più comune, - che prevede però una serie di eccezioni, dipendenti anche dal tipo di + non potrà più riassumerla.\footnote{questo nei casi ordinari, sono + previste però una serie di eccezioni, dipendenti anche dal tipo di supporto, che vedremo meglio in seguito dato il notevole intreccio nella casistica.} \item[\textit{inheritable}] l'insieme delle \textit{capabilities} @@ -4255,78 +4608,109 @@ altri tre insiemi associabili a ciascun file.\footnote{la realizzazione viene eseguita con l'uso di uno specifico attributo esteso, \texttt{security.capability}, la cui modifica è riservata, (come illustrato in sez.~\ref{sec:file_xattr}) ai processi dotato della capacità - \macro{CAP\_SYS\_ADMIN}.} A differenza delle precedenti le \textit{file - capabilities} hanno effetto soltanto quando il file che le porta viene -eseguito come programma con una \func{exec}, e forniscono un meccanismo che -consente l'esecuzione di alcuni programmi con maggiori privilegi, in sostanza -una estensione dell'uso del \acr{suid} di root. Anche questi tre insiemi sono -identicati con gli stessi nomi, ma il loro significato è: -\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}} + \macro{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto +soltanto quando il file che le porta viene eseguito come programma con una +\func{exec}, e forniscono un meccanismo che consente l'esecuzione dello stesso +con maggiori privilegi; in sostanza sono una sorta di estensione dell'uso del +\acr{suid} di root. Anche questi tre insiemi sono identificati con gli stessi +nomi, ma il loro significato è diverso: +\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}} \item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme - delle capacità che con l'esecuzione del file verranno comunque aggiunte alle + delle capacità che con l'esecuzione del programma verranno aggiunte alle capacità \textsl{permesse} del processo. \item[\textit{inheritable}] (chiamato originariamente \textit{allowed}) - l'insieme delle capacità che con l'esecuzione del file possono essere - ereditate dal processo originario (che cioè vengono tolte dalle - \textsl{ereditabili} del processo originale all'esecuzione di + l'insieme delle capacità che con l'esecuzione del programma possono essere + ereditate dal processo originario (che cioè vengono tolte + dall'\textit{inheritable set} del processo originale all'esecuzione di \func{exec}). \item[\textit{effective}] in questo caso non si tratta di un insieme ma di un unico valore logico; se attivo all'esecuzione del programma tutte le capacità che risulterebbero \textsl{permesse} verranno pure attivate, inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna - capacità verrà attivata (cioè le effettive restano vuote). + capacità verrà attivata (cioè l'\textit{effective set} resta vuoto). \end{basedescript} -Infine come accennato, esiste un altro insieme, il -\itindex{capabilities~bounding~set} \textit{capabilities bounding set}, il cui -scopo è quello di costituire un limite alle capacità che possono essere -attivate per un processo, ma il suo significato è stato completamente -modificato con l'introduzione delle \textit{file capabilities}. - - -a meno che non sia dotato della capacità - \macro{CAP\_SETPCAP} nel qual caso potrà, come vedremo in seguito, - impostarne anche altre. - -che non esegua un programma che è \acr{suid} di root o - che ce l'ha nelle \textit{capabilities} presenti sul file - eseguibile.\footnote{e neanche in questo caso se vengono usate le estensioni - introdotte con il kernel 2.6.26 che vedremo più avanti.} - -Fino al kernel 2.6.25 oltre a questi tre insiemi, che sono relativi al singolo -processo, il kernel manteneva un ulteriore insieme unico valido per tutto il -sistema, chiamato \itindex{capabilities~bounding~set} \textit{capabilities - bounding set}. Ogni volta che un programma viene posto in esecuzione con -\func{exec} il contenuto degli insiemi \textit{effective} e \textit{permitted} -venivano mascherati con un \textsl{AND} binario del contenuto corrente del -\textit{capabilities bounding set}, così che il nuovo processo potesse -disporre soltanto delle capacità in esso elencate. - -A lungo il \textit{capabilities bounding set} è stato un parametro generale di -sistema, accessibile attraverso il contenuto del file -\procfile{/proc/sys/kernel/cap-bound}, usato per impostare un limite -universale alle capacità che possono essere accordate ai vari processi. Il -suo valore poteva essere impostato esclusivamente dal primo processo eseguito -nel sistema (di norma cioè da \texttt{/sbin/init}), ogni processo eseguito -successivamente (cioè con \textsl{pid} diverso da 1) anche se eseguito con -privilegi di amministratore, era in grado soltanto di rimuovere uno dei bit -già presenti dell'insieme: questo significava che tolta una -\textit{capability} dal \textit{capabilities bounding set} questa non era più -disponibile, neanche per l'amministratore, a meno di un riavvio. - -Qualora invece si sia abilitato nel kernel il supporto per le -\textit{capabilities} dei file il \textit{capabilities bounding set} mantiene -il suo significato di limite alle capacità che possono essere assegnate al -processo, ma diventa una proprietà dello stesso (un quarto insieme che il -processo si porta dietro). In questo - - - - viene a costituire un doppio limite: - - +\itindbeg{capabilities~bounding~set} + +Infine come accennato, esiste un ulteriore insieme, chiamato +\textit{capabilities bounding set}, il cui scopo è quello di costituire un +limite alle capacità che possono essere attivate per un programma. Il suo +funzionamento però è stato notevolmente modificato con l'introduzione delle +\textit{file capabilities} e si deve pertanto prendere in considerazione una +casistica assai complessa. + +Per i kernel fino al 2.6.25, o se non si attiva il supporto per le +\textit{file capabilities}, il \textit{capabilities bounding set} è un +parametro generale di sistema, il cui valore viene riportato nel file +\procfile{/proc/sys/kernel/cap-bound}. Il suo valore iniziale è definito in +sede di compilazione del kernel, e da sempre ha previsto come default la +presenza di tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In +questa situazione solo il primo processo eseguito nel sistema (quello con +\textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di +modificarlo, ogni processo eseguito successivamente, anche se eseguito con +privilegi di amministratore,\footnote{per essere precisi occorreva la capacità + \const{CAP\_SYS\_MODULE}.} è in grado soltanto di rimuovere una delle +\textit{capabilities} già presenti dell'insieme. + +In questo caso l'effetto del \textit{capabilities bounding set} è che solo le +capacità in esso presenti possono essere trasmesse ad un altro programma +attraverso una \func{exec}. Questo in sostanza significa che se si elimina da +esso una capacità, considerato che \texttt{init} (almeno nelle versioni +ordinarie) non supporta la reimpostazione del \textit{bounding set}, questa +non sarà più disponibile per nessun processo a meno di un riavvio, eliminando +così in forma definitiva quella capacità per tutti, compreso +l'amministratore.\footnote{la qual cosa, visto il default usato per il + \textit{capabilities bounding set}, significa anche che \const{CAP\_SETPCAP} + non è stata praticamente mai usata nella sua forma originale.} + +Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set} +è diventato una proprietà di ciascun processo, che viene propagata invariata +sia attraverso una \func{fork} che una \func{exec}. In questo caso il file +\procfile{/proc/sys/kernel/cap-bound} non esiste e \texttt{init} non ha nessun +ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la +presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}). + +Con questo nuovo meccanismo il \textit{bounding set} continua a ricoprire un +ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come +limite alle capacità che possono essere aggiunte al processo in quanto +presenti nel \textit{permitted set} del programma messo in esecuzione, in +sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel +suo \textit{permitted set} solo se questa è anche nel \textit{bounding + set}. In questo modo si possono rimuovere definitivamente certe capacità da +un processo, anche qualora questo dovesse eseguire un programma +privilegiato. + +Si tenga presente però che in questo caso il \textit{bounding set} blocca +esclusivamente le capacità indicate nel \textit{permitted set} del programma +che verrebbero attivate in caso di esecuzione, non quelle eventualmente già +presenti nell'\textit{inheritable set} del processo (ad esempio perché +presenti prima di averle rimosse dal \textit{bounding set}). In questo caso +eseguendo un programma che abbia anche lui dette capacità nel suo +\textit{inheritable set} queste verrebbero assegnate. + +In questa seconda versione inoltre il \textit{bounding set} costituisce anche +un limite per le capacità che possono essere aggiunte all'\textit{inheritable + set} del processo con \func{capset}, sempre nel senso che queste devono +essere presenti nel \textit{bounding set} oltre che nel \textit{permitted set} +del processo. +\itindend{capabilities~bounding~set} +Come si può notare per fare ricorso alle \textit{capabilities} occorre +comunque farsi carico di una notevole complessità di gestione, aggravata dalla +presenza di una radicale modifica del loro funzionamento con l'introduzione +delle \textit{file capabilities}. Considerato che il meccanismo originale era +incompleto e decisamente problematico nel caso di programmi che non ne +sappiano tener conto,\footnote{si ebbe un grosso problema di sicurezza con + \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID} + dall'\textit{inheritable set} si ottenne di far fallire una \func{setuid}, + in maniera inaspettata per il programma (che aspettandosi il successo della + funzione non ne controllava lo stato di uscita) con la conseguenza di + effettuare come amministratore operazioni che altrimenti sarebbero state + eseguite, senza poter apportare danni, da utente normale.} ci soffermeremo +solo sulla implementazione completa presente a partire dal kernel 2.6.25, +tralasciando ulteriori dettagli riguardo la versione precedente. + Quando un programma viene messo in esecuzione\footnote{cioè quando viene @@ -4365,10 +4749,10 @@ tabella alcune \textit{capabilities} attengono a singole funzionalità e sono molto specializzate, mentre altre hanno un campo di applicazione molto vasto, che è opportuno dettagliare maggiormente. -\begin{table}[!h!bt] +\begin{table}[!h!btp] \centering \footnotesize - \begin{tabular}{|l|p{11.5cm}|} + \begin{tabular}{|l|p{11.9cm}|} \hline \textbf{Capacità}&\textbf{Descrizione}\\ \hline @@ -4458,12 +4842,8 @@ che è opportuno dettagliare maggiormente. \itindex{multicast} \textit{multicast}.\\ \const{CAP\_NET\_RAW} & La capacità di usare socket \texttt{RAW} e \texttt{PACKET} (vedi sez.~\ref{sec:sock_type}).\\ - \const{CAP\_SETPCAP} & Prima del 2.6.24 la capacità di impostare o - rimuovere le \textit{capabilities} da un - processo, dopo quella di impostare una capacità - del \textit{bounding set} nelle proprie - \textit{inheritable} o rimoverla dal - \textit{bounding set} stesso.\\ + \const{CAP\_SETPCAP} & La capacità di modifiche privilegiate alle + \textit{capabilities}.\\ \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti amministrativi. \\ \const{CAP\_SYS\_BOOT} & La capacità di fare eseguire un riavvio del @@ -4483,10 +4863,10 @@ che è opportuno dettagliare maggiormente. \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di \textit{accounting} dei processi (vedi sez.~\ref{sec:sys_bsd_accounting}).\\ - \const{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con + \const{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con \func{ptrace} (vedi sez.~\ref{sec:xxx_ptrace}).\\ - \const{CAP\_SYS\_RAWIO} & La capacità di eseguire operazioni sulle porte + \const{CAP\_SYS\_RAWIO} & La capacità di operare sulle porte di I/O con \func{ioperm} e \func{iopl} (vedi sez.~\ref{sec:file_io_port}).\\ \const{CAP\_SYS\_RESOURCE}& La capacità di superare le varie limitazioni @@ -4515,12 +4895,37 @@ che è opportuno dettagliare maggiormente. controllo di accesso chiamato \itindex{Discrectionary~Access~Control~(DAC)} \textit{Discrectionary Access Control} (da cui il nome DAC).} -La prima di queste capacità ``\textsl{ampie}'' è \const{CAP\_FOWNER}, che -rimuove le restrizioni poste ad un processo che non ha la proprietà di un file -in un vasto campo di operazioni;\footnote{vale a dire la richiesta che - l'user-ID effettivo del processo (o meglio il \textit{filesystem user-ID}, - vedi sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} -queste comprendono i cambiamenti dei permessi e dei tempi del file (vedi + +Prima di dettagliare il significato della capacità più generiche, conviene +però dedicare un discorso a parte a \const{CAP\_SETPCAP}, il cui significato è +stato completamente cambiato con l'introduzione delle \textit{file + capabilities} nel kernel 2.6.24. In precedenza questa capacità era quella +che permetteva al processo che la possedeva di impostare o rimuovere le +\textit{capabilities} che fossero presenti nel \textit{permitted set} del +chiamante di un qualunque altro processo. In realtà questo non è mai stato +l'uso inteso nelle bozze dallo standard POSIX, ed inoltre, come si è già +accennato, dato che questa capacità è assente nel \textit{capabilities + bounding set} usato di default, essa non è neanche mai stata realmente +disponibile. + +Con l'introduzione \textit{file capabilities} e il cambiamento del significato +del \textit{capabilities bounding set} la possibilità di modificare le +capacità di altri processi è stata completamente rimossa, e +\const{CAP\_SETPCAP} ha acquisito quello che avrebbe dovuto essere il suo +significato originario, e cioè la capacità del processo di poter inserire nel +suo \textit{inheritable set} qualunque capacità presente nel \textit{bounding + set}. Oltre a questo la disponibilità di \const{CAP\_SETPCAP} consente ad un +processo di eliminare una capacità dal proprio \textit{bounding set} (con la +conseguente impossibilità successiva di eseguire programmi con quella +capacità), o di impostare i \textit{securebits} delle \textit{capabilities}. + +La prima fra le capacità ``\textsl{ampie}'' che occorre dettagliare +maggiormente è \const{CAP\_FOWNER}, che rimuove le restrizioni poste ad un +processo che non ha la proprietà di un file in un vasto campo di +operazioni;\footnote{vale a dire la richiesta che l'user-ID effettivo del + processo (o meglio il \textit{filesystem user-ID}, vedi + sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.} queste +comprendono i cambiamenti dei permessi e dei tempi del file (vedi sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le impostazioni degli attributi estesi e delle ACL (vedi sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo @@ -4572,6 +4977,10 @@ filesystem \acr{ext3}, non subire le quote disco, aumentare i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit}) e sulle dimensioni dei messaggi delle code del SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}). +Questo modo di intendere ... da fare ... per cui +a partire dal 2.6.24/5 è divenuta quella di impostare una capacità del +\textit{bounding set} nelle proprie \textit{inheritable} o rimuoverla dal +\textit{bounding set} stesso. Per la gestione delle \textit{capabilities} il kernel mette a disposizione due funzioni che permettono rispettivamente di leggere ed impostare i valori dei @@ -5100,15 +5509,15 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: int const char oldpath newpath errno EXDEV EPERM st Smack SysV % LocalWords: EEXIST EMLINK EACCES ENAMETOOLONG ENOTDIR EFAULT ENOMEM EROFS ls % LocalWords: ELOOP ENOSPC EIO pathname nlink stat vfat fsck EISDIR ENOENT cap -% LocalWords: POSIX socket fifo sticky root system call count crash nell' init +% LocalWords: POSIX socket fifo sticky root system call count crash init linux % LocalWords: descriptor remove rename rmdir stdio glibc libc NFS DT obj dup % LocalWords: ENOTEMPTY EBUSY mount point EINVAL soft symbolic tab symlink fig % LocalWords: dangling access chdir chmod chown creat exec lchown lstat mkdir % LocalWords: mkfifo mknod opendir pathconf readlink truncate path buff size -% LocalWords: grub bootloader grep linux MAXSYMLINKS cat VFS sys dirname fcntl +% LocalWords: grub bootloader grep MAXSYMLINKS cat VFS sys dirname fcntl % LocalWords: dev umask IFREG IFBLK IFCHR IFIFO SVr sgid BSD SVID NULL from to % LocalWords: stream dirent EMFILE ENFILE dirfd SOURCE fchdir readdir struct -% LocalWords: EBADF namlen HAVE thread entry result value argument fileno ino +% LocalWords: EBADF namlen HAVE thread entry result value argument fileno % LocalWords: name TYPE OFF RECLEN UNKNOWN REG SOCK CHR BLK type IFTODT DTTOIF % LocalWords: DTYPE off reclen seekdir telldir void rewinddir closedir select % LocalWords: namelist compar malloc qsort alphasort versionsort strcoll myls @@ -5118,21 +5527,21 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: EINTR mktemp mkstemp stlib template filename XXXXXX OpenBSD buf % LocalWords: mkdtemp fstat filedes nell'header padding ISREG ISDIR ISCHR IFMT % LocalWords: ISBLK ISFIFO ISLNK ISSOCK IFSOCK IFLNK IFDIR ISUID UID ISGID GID -% LocalWords: ISVTX IRUSR IWUSR IXUSR IRGRP IWGRP IXGRP IROTH IWOTH IXOTH du -% LocalWords: blocks blksize holes lseek TRUNC ftruncate length lenght ETXTBSY +% LocalWords: ISVTX IRUSR IWUSR IXUSR IRGRP IWGRP IXGRP IROTH IWOTH IXOTH +% LocalWords: blocks blksize holes lseek TRUNC ftruncate ETXTBSY length % LocalWords: hole atime read utime mtime write ctime modification leafnode cp % LocalWords: make fchmod fchown utimbuf times actime modtime Mac owner uid fs % LocalWords: gid Control List patch mandatory control execute group other all -% LocalWords: dell' effective passwd IGID locking swap saved text IRWXU IRWXG -% LocalWords: IRWXO ext reiser capability FSETID mask capabilities chroot jail -% LocalWords: FTP Di filter reiserfs Attributes Solaris FreeBSD libacl hash +% LocalWords: effective passwd IGID locking swap saved text IRWXU IRWXG +% LocalWords: IRWXO capability FSETID mask capabilities chroot jail +% LocalWords: FTP filter Attributes Solaris FreeBSD libacl hash at % LocalWords: XFS SELinux namespace attribute security trusted Draft Modules % LocalWords: attributes mime ADMIN FOWNER libattr lattr getxattr lgetxattr of % LocalWords: fgetxattr attr ssize ENOATTR ENOTSUP NUL setxattr lsetxattr list % LocalWords: fsetxattr flags XATTR REPLACE listxattr llistxattr flistxattr by -% LocalWords: removexattr lremovexattr fremovexattr attributename lacl acl tv +% LocalWords: removexattr lremovexattr fremovexattr attributename acl % LocalWords: OBJ setfacl len any prefix separator options NUMERIC IDS SMART -% LocalWords: INDENT major number IDE Documentation makedev proc copy +% LocalWords: INDENT major number IDE Documentation makedev proc copy LNK long % LocalWords: euidaccess eaccess delete def tag qualifier permset calendar NOW % LocalWords: mutt noatime relatime strictatime atim nsec mtim ctim atimensec % LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT @@ -5145,8 +5554,13 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: LEASE lease SETFCAP AUDIT permitted inherited inheritable AND % LocalWords: bounding execve fork capget capset header hdrp datap ESRCH undef % LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm -% LocalWords: fffffeff CapEff getcap dell'IPC scheduling dell'I lookup dcookie +% LocalWords: fffffeff CapEff getcap scheduling lookup % LocalWords: NEWNS unshare nice NUMA ioctl journaling close XOPEN fdopendir +% LocalWords: btrfs mkostemp extN ReiserFS JFS Posix usrquota grpquota EDQUOT +% LocalWords: aquota quotacheck limit grace period quotactl cmd caddr addr +% LocalWords: QUOTAON ENODEV ENOPKG ENOTBLK GETQUOTA SETQUOTA SETUSE SETQLIM +% LocalWords: forced allowed sendmail SYSLOG WAKE ALARM CLOCK BOOTTIME +% LocalWords: REALTIME securebits %%% Local Variables: %%% mode: latex