From 2b2c30012bd057981a709f801810e2a0a310ce3c Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 21 May 2008 11:33:11 +0000 Subject: [PATCH] Materiale sulle ACL, inizio delle varie funzioni di gestione --- filedir.tex | 300 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 252 insertions(+), 48 deletions(-) diff --git a/filedir.tex b/filedir.tex index b26b986..9216ca0 100644 --- a/filedir.tex +++ b/filedir.tex @@ -3046,26 +3046,28 @@ L'elenco dei vari tipi di voci presenti in una ACL, con una breve descrizione del relativo significato, è riportato in tab.~\ref{tab:acl_tag_types}. Tre di questi tipi, \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER}, corrispondono direttamente ai tre permessi ordinari dei -file (proprietario, gruppo proprietario e tutti gli altri) e una ACL valida -deve sempre contenere una ed una sola voce per ciascuno di questi tipi. +file (proprietario, gruppo proprietario e tutti gli altri) e per questo una +ACL valida deve sempre contenere una ed una sola voce per ciascuno di questi +tipi. Una ACL può poi contenere un numero arbitrario di voci di tipo \const{ACL\_USER} e \const{ACL\_GROUP}, ciascuna delle quali indicherà i permessi assegnati all'utente e al gruppo indicato dal relativo qualificatore; -ovviamente un utente o gruppo potranno essere indicati una sola volta -all'interno di una ACL. Inoltre se in una ACL esiste una voce di uno di questi -due tipi è obbligatoria anche la presenza di una ed una sola voce di tipo -\const{ACL\_MASK}, che negli altri casi è opzionale. +ovviamente ciascuna di queste voci dovrà fare riferimento ad un utente o ad un +gruppo diverso, e non corrispondenti a quelli proprietari del file. Inoltre se +in una ACL esiste una voce di uno di questi due tipi è obbligatoria anche la +presenza di una ed una sola voce di tipo \const{ACL\_MASK}, che negli altri +casi è opzionale. Quest'ultimo tipo di voce contiene la maschera dei permessi che possono essere assegnati tramite voci di tipo \const{ACL\_USER}, \const{ACL\_GROUP} e -\const{ACL\_GROUP\_OBJ}, se in una di queste voci si fosse specificato un +\const{ACL\_GROUP\_OBJ}; se in una di queste voci si fosse specificato un permesso non presente in \const{ACL\_MASK} questo verrebbe ignorato. L'uso di -\const{ACL\_MASK} è di particolare utilità quando associata ad una -\textit{default ACL} di una directory in quanto i permessi così specificati -vengono ereditati da tutti i file creati nella stessa, ottenendo una sorta di -\itindex{umask} \textit{umask} associata ad un oggetto sul filesystem -piuttosto che a un processo. +una ACL di tipo \const{ACL\_MASK} è di particolare utilità quando essa +associata ad una \textit{default ACL} su una directory, in quanto i permessi +così specificati verranno ereditati da tutti i file creati nella stessa +directory. Si ottiene così una sorta di \itindex{umask} \textit{umask} +associata ad un oggetto sul filesystem piuttosto che a un processo. Dato che le ACL vengono a costituire una estensione dei permessi ordinari, uno dei problemi che si erano posti nella loro standardizzazione era appunto @@ -3077,9 +3079,10 @@ riflesso sui permessi ordinari dei file\footnote{per permessi ordinari si intende quelli mantenuti nell'\textit{inode}, che devono restare dato che un filesystem può essere montato senza abilitare le ACL.} e viceversa. In realtà la mappatura è diretta solo per le voci \const{ACL\_USER\_OBJ} e -\const{ACL\_OTHER}, nel caso di \const{ACL\_GROUP\_OBJ} questo vale fintanto -che non è presente una voce di tipo \const{ACL\_MASK}, nel qual caso valgono -invece i permessi in essa specificati.\footnote{questo diverso comportamento a +\const{ACL\_OTHER}, nel caso di \const{ACL\_GROUP\_OBJ} questo vale soltanto +se non è presente una voce di tipo \const{ACL\_MASK}, se invece questa è +presente verranno tolti dai permessi di \const{ACL\_GROUP\_OBJ} tutti quelli +non presenti in \const{ACL\_MASK}.\footnote{questo diverso comportamento a seconda delle condizioni è stato introdotto dalla standardizzazione \textit{POSIX 1003.1e Draft 17} per mantenere il comportamento invariato sui sistemi dotati di ACL per tutte quelle applicazioni che sono conformi @@ -3091,62 +3094,263 @@ quello relativo alla creazione di nuovi file,\footnote{o oggetti sul \func{creat} (vedi sez.~\ref{sec:file_open}), \func{mkdir} (vedi sez.~\ref{sec:file_dir_creat_rem}), \func{mknod} e \func{mkfifo} (vedi sez.~\ref{sec:file_mknod}).} che come accennato può essere modificato dalla -presenza di una default ACL sulla directory che contiene quel file. Se questa -non c'è valgono le regole illustrate in sez.~\ref{sec:file_perm_management} -per cui essi sono determinati dalla \itindex{umask} \textit{umask} del -processo, e la sola differenza è che i permessi ordinari da esse risultanti -vengono automaticamente rimappati su una ACL di accesso assegnata al nuovo -file che contiene solo le tre voci di tipo \const{ACL\_USER\_OBJ}, +presenza di una \textit{default ACL} sulla directory che contiene quel file. +Se questa non c'è valgono le regole usuali illustrate in +sez.~\ref{sec:file_perm_management}, per cui essi sono determinati dalla +\itindex{umask} \textit{umask} del processo, e la sola differenza è che i +permessi ordinari da esse risultanti vengono automaticamente rimappati anche +su una ACL di accesso assegnata automaticamente al nuovo file, che contiene +soltanto le tre corrispondenti voci di tipo \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER}. Se invece è presente una ACL di default sulla directory che contiene il nuovo -file questa diventerà la sua ACL di accesso, a meno di non aver indicato nelle -funzioni di creazione che lo consentono uno specifico insieme di -permessi.\footnote{tutte le funzioni citate in precedenza supportano un - argomento \var{mode} che indichi un insieme di permessi iniziale.} In tal -caso quelli non presenti in tale insieme saranno eliminati dalle voci -corrispondenti nella ACL. - -Ovviamente la presenza della ACL modifica anche le regole del controllo di -accesso ai file illustrate in sez.~\ref{sec:file_perm_overview}; per il -controllo vengono sempre utilizzati gli identificatori del gruppo -\textit{effective} del processo, ed i passi attraverso i quali viene stabilito -se esso ha diritto di accesso sono i seguenti: -\begin{enumerate} +file questa diventerà automaticamente la sua ACL di accesso, a meno di non +aver indicato, nelle funzioni di creazione che lo consentono, uno specifico +valore per i permessi ordinari;\footnote{tutte le funzioni citate in + precedenza supportano un argomento \var{mode} che indichi un insieme di + permessi iniziale.} in tal caso saranno eliminati dalle voci corrispondenti +nella ACL tutti quelli non presenti in tale indicazione. + +Dato che questa è la ragione che ha portato alla loro creazione, la pricipale +modifica introdotta con la presenza della ACL è quella alle regole del +controllo di accesso ai file illustrate in sez.~\ref{sec:file_perm_overview}. +Come nel caso ordinario per il controllo vengono sempre utilizzati gli +identificatori del gruppo \textit{effective} del processo, ma in presenza di +ACL i passi attraverso i quali viene stabilito se esso ha diritto di accesso +sono i seguenti: +\begin{enumerate*} \item Se l'user-ID del processo è nullo l'accesso è sempre garantito senza - nessun ulteriore controllo. + nessun controllo. \item Se l'user-ID del processo corrisponde al proprietario del file allora: \begin{itemize*} \item se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto, - l'accesso è consentito - \item altrimenti l'accesso è negato + l'accesso è consentito; + \item altrimenti l'accesso è negato. \end{itemize*} \item Se l'user-ID del processo corrisponde ad un qualunque qualificatore presente in una voce \const{ACL\_USER} allora: \begin{itemize*} \item se la voce \const{ACL\_USER} corrispondente e la voce \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è - consentito - \item altrimenti l'accesso è negato + consentito; + \item altrimenti l'accesso è negato. \end{itemize*} -\item Se il group-ID del processo o uno dei group-ID supplementari corrisponde - al gruppo proprietario del file o a un qualunque qualificatore di una voce - di tipo allora: +\item Se è il group-ID del processo o uno dei group-ID supplementari + corrisponde al gruppo proprietario del file allora: \begin{itemize*} - \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è - consentito, - \item altrimenti l'accesso è negato + \item se la voce \const{ACL\_GROUP\_OBJ} e una eventuale voce + \const{ACL\_MASK} (se non vi sono voci di tipo \const{ACL\_GROUP} questa + può non essere presente) contengono entrambe il permesso richiesto, + l'accesso è consentito; + \item altrimenti l'accesso è negato. \end{itemize*} -\item Se il bit dei permessi d'accesso per tutti gli altri è impostato, +\item Se è il group-ID del processo o uno dei group-ID supplementari + corrisponde ad un qualunque qualificatore presente in una voce + \const{ACL\_GROUP} allora: + \begin{itemize*} + \item se la voce \const{ACL\_GROUP} corrispondente e la voce + \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è + consentito; + \item altrimenti l'accesso è negato. + \end{itemize*} +\item Se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto, l'accesso è consentito, altrimenti l'accesso è negato. -\end{enumerate} +\end{enumerate*} + +I passi di controllo vengono eseguiti esattamente in questa sequenza, e la +decisione viene presa non appena viene trovata una corrispondenza con gli +identificatori del processo. Questo significa che i permessi presenti in una +voce di tipo \const{ACL\_USER} hanno la precedenza sui permessi ordinari +associati al gruppo proprietario del file (vale a dire su +\const{ACL\_GROUP\_OBJ}). + +Per la gestione delle ACL lo standard \textit{POSIX 1003.1e Draft 17} ha +previsto delle apposite funzioni ed tutta una serie di tipi di dati +dedicati;\footnote{fino a definire un tipo di dato e delle costanti apposite + per identificare i permessi standard di lettura, scrittura ed esecuzione.} +tutte le operazioni devono essere effettuate attraverso tramite questi tipi di +dati, che incapsulano tutte le informazioni contenute nelle ACL. La prima di +queste funzioni che prendiamo in esame è \funcd{acl\_init}, il cui prototipo +è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/acl.h} + + \funcdecl{acl\_t acl\_init(int count)} + Inizializza un'area di lavoro per una ACL di \param{count} voci. + + \bodydesc{La funzione restituisce un puntatore all'area di lavoro in caso di + successo e \const{NULL} in caso di errore nel qual caso \var{errno} + assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] il valore di \param{count} è negativo. + \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile. + \end{errlist} +} +\end{functions} + +La funzione alloca ed inizializza un'area di memoria che verrà usata per +mantenere i dati di una ACL contenente fino ad un massimo di \const{count} +voci. La funzione ritorna un valore di tipo \type{acl\_t}, da usare in tutte +le altre funzioni che operano sulla ACL. La funzione si limita alla +allocazione iniziale e non inserisce nessun valore nella ACL che resta vuota. +Si tenga presente che pur essendo \type{acl\_t} un tipo opaco che identifica +``\textsl{l'oggetto}'' ACL, il valore restituito dalla funzione non è altro +che un puntatore all'area di memoria allocata per i dati richiesti; pertanto +in caso di fallimento verrà restituito un puntatore nullo e si dovrà +confrontare il valore di ritorno della funzione con ``\code{(acl\_t) NULL}''. + +Una volta che si siano completate le operazioni sui dati di una ACL la memoria +allocata dovrà essere liberata esplicitamente attraverso una chiamata alla +funzione \funcd{acl\_free}, il cui protipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/acl.h} + + \funcdecl{int acl\_free(void * obj\_p)} + + Disalloca la memoria riservata per i dati di una ACL. + + \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ se + \param{obj\_p} non è un puntatore valido, nel qual caso \var{errno} + assumerà il valore \errcode{EINVAL} +} +\end{functions} + +Si noti come la funzione richieda come argomento un puntatore di tipo +``\ctyp{void *}'', essa infatti può essere usata non solo per liberare la +memoria allocata per i dati di una ACL, ma anche per quella usata per creare +le stringhe di descrizione testuale delle ACL o per ottenere i valori dei +qualificatori di una voce; pertanto a seconda dei casi occorrerà eseguire un +\textit{cast} a ``\ctyp{void *}'' del tipo di dato di cui si vuole eseguire la +disallocazione. Si tenga presente poi che oltre a \func{acl\_init} esistono +molte altre funzioni che possono allocare memoria per i dati delle ACL, è +pertanto opportuno tenere traccia di tutte queste funzioni perché alla fine +delle operazioni tutta la memoria allocata dovrà essere liberata con +\func{acl\_free}. + +Una volta che si abbiano a disposizione i dati di una ACL tramite il +riferimento ad oggetto di tipo \type{acl\_t} questi potranno essere copiati +con la funzione \funcd{acl\_dup}, il cui prototipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/acl.h} + + \funcdecl{acl\_t acl\_dup(acl\_t acl)} + + Crea una copia della ACL \param{acl}. + + \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso + di successo e \code{(acl\_t)NULL} in caso di errore nel qual caso + \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] l'argomento \param{acl} non è un puntatore valido + per una ACL. + \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile per eseguire + la copia. + \end{errlist} +} +\end{functions} + +La funzione crea una copia dei dati della ACL indicata tramite l'argomento +\param{acl}, allocando autonomamente tutto spazio necessario alla copia e +restituendo un secondo oggetto di tipo \type{acl\_t} come riferimento a +quest'ultima. Valgono per questo le stesse considerazioni fatte per il valore +di ritorno di \func{acl\_init}, ed in particolare il fatto che occorrerà +prevedere una ulteriore chiamata esplicita a \func{acl\_free} per liberare la +memoria occupata dalla copia. + +Se si deve creare una ACL manualmente l'uso di \func{acl\_init} è scomodo, +dato che la funzione restituisce una ACL vuota, una alternativa allora è usare +\funcd{acl\_from\_mode} che consente di creare una ACL a partire da un valore +di permessi ordinari, il prototipo della funzione è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/acl.h} + + \funcdecl{acl\_t acl\_from\_mode(mode\_t mode)} + + Crea una ACL inizializzata con i permessi di \param{mode}. + + \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso + di successo e \code{(acl\_t)NULL} in caso di errore nel qual caso + \var{errno} assumerà il valore \errval{ENOMEM}. + +} +\end{functions} + +La funzione restituisce una ACL inizializzata con le tre voci obbligatorie +\const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} già +impostate secondo la corrispondenza ai valori dei permessi ordinari indicati +dalla maschera passata nell'argomento \param{mode}. Questa funzione è una +estensione usata dalle ACL di Linux e non è portabile, ma consente di +semplificare l'inizializzazione in maniera molto comoda. + +Altre due funzioni che consentono di creare una ACL già inizializzata sono +\funcd{acl\_get\_fd} e \funcd{acl\_get\_file}, che però sono per lo più +utilizzate per leggere la ACL corrente di un file; i rispettivi prototipi +sono: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/acl.h} + + \funcdecl{acl\_t acl\_get\_file(const char *path\_p, acl\_type\_t type)} + \funcdecl{acl\_t acl\_get\_fd(int fd)} + + Ottiene i dati delle ACL di un file. + + \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso + di successo e \code{(acl\_t)NULL} in caso di errore nel qual caso + \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati. + \item[\errcode{ENOTSUP}] il filesystem cui fa riferimento il file non + supporta le ACL. + \end{errlist} + ed inoltre \errval{EBADF} per \func{acl\_get\_fd}, ed \errval{EINVAL} per + valori scorretti di \param{type} e tutti i possibili errori per l'accesso ad + un file per \func{acl\_get\_file}. + +} +\end{functions} + +Le due funzioni ritornano, con un oggetto di tipo \type{acl\_t}, il valore +della ACL correntemente associata ad un file, che può essere identificato +tramite un file descriptor usando \func{acl\_get\_fd} o con un pathname usando +\func{acl\_get\_file}. Nel caso di quest'ultima funzione, che può richiedere +anche la ACL relativa ad una directory, il secondo argomento \param{type} +consente di specificare se si vuole ottenere la ACL di default o quella di +accesso. Questo argomento deve essere di tipo \type{acl\_type\_t} e può +assumere solo i due valori riportati in tab.~\ref{tab:acl_type}, + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}{|l|l|} + \hline + \textbf{Tipo} & \textbf{Descrizione} \\ + \hline + \hline + \const{ACL\_TYPE\_ACCESS} & indica una ACL di accesso.\\ + \const{ACL\_TYPE\_DEFAULT}& indica una ACL di default.\\ + \hline + \end{tabular} + \caption{Le costanti che identificano il tipo di ACL.} + \label{tab:acl_type} +\end{table} +Si tenga presente che nel caso di \func{acl\_get\_file} occorrerà che il +processo chiamante abbia privilegi di accesso sufficenti a poter leggere gli +attributi estesi dei file (come illustrati in sez.~\ref{sec:file_xattr}); +inoltre una ACL di tipo \const{ACL\_TYPE\_DEFAULT} potrà essere richiesta +soltanto per una directory, e verrà restituita solo se presente, altrimenti +verrà restituita una ACL vuota. \itindend{Access~Control~List} -% TODO trattare le ACL, la documentazione di sistema è nei pacchetti +% TODO trattare le ACL, la documentazione di sistema è nei pacchetti % libacl1-dev e acl % vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/ -- 2.30.2