From ac55941f7ae7823e62c277d6be313147ef950f7b Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 24 Jan 2012 00:50:25 +0000 Subject: [PATCH] Trattazione del significato di immutable e di append-only --- filedir.tex | 259 +++++++++++++++++++++++++++++++---------------- img/fileperm.dia | Bin 1874 -> 1886 bytes 2 files changed, 169 insertions(+), 90 deletions(-) diff --git a/filedir.tex b/filedir.tex index 9eff764..fcc0c59 100644 --- a/filedir.tex +++ b/filedir.tex @@ -538,10 +538,10 @@ Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che non sono presenti su un classico filesystem di tipo Unix; le principali sono le seguenti: \begin{itemize} -\item i \textit{file attributes} consentono di modificare il comportamento del - kernel quando agisce su gruppi di file. Possono essere impostati su file e - directory e in quest'ultimo caso i nuovi file creati nella directory - ereditano i suoi attributi. +\item gli attributi estesi (vedi sez.~\ref{sec:file_xattr}) che consentono di + estendere le informazioni salvabili come metadati e le ACL (vedi + sez.~\ref{sec:file_ACL}) che consentono di estendere il modello tradizionale + dei permessi sui file. \item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di montaggio. La semantica BSD comporta che i file in una directory sono creati con lo stesso identificatore di gruppo della directory che li contiene. La @@ -558,11 +558,12 @@ le seguenti: dell'\textit{inode} (evitando letture multiple e spreco di spazio), non tutti i nomi però possono essere gestiti così per limiti di spazio (il limite è 60 caratteri). -\item vengono supportati i file immutabili (che possono solo essere letti) per - la protezione di file di configurazione sensibili, o file - \textit{append-only} che possono essere aperti in scrittura solo per - aggiungere dati (caratteristica utilizzabile per la protezione dei file di - log). +\item vengono supportati \itindex{file~attributes} i cosiddetti \textit{file + attributes} che attivano comportamenti specifici per i file su cui vengono + attivati come marcarli come immutabili (che possono cioè essere soltanto + letti) per la protezione di file di configurazione sensibili, o come + \textit{append-only} (che possono essere aperti in scrittura solo per + aggiungere dati) per la protezione dei file di log. \end{itemize} La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un @@ -3732,11 +3733,12 @@ riferimento al suo file descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un collegamento simbolico saranno modificati i suoi tempi invece di quelli del file a cui esso punta. -Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file -fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare -valori con questa precisione. Per questo sono state introdotte due nuove -funzioni, \funcd{futimens} e \func{utimensat}, in grado di eseguire questo -compito; i rispettivi prototipi sono: +Nonostante il kernel nelle versioni più recenti supporti, come accennato, +risoluzioni dei tempi dei file fino al nanosecondo, le funzioni fin qui +esaminate non consentono di impostare valori con questa precisione. Per questo +sono state introdotte due nuove funzioni di sistema, \funcd{futimens} e +\funcd{utimensat}, in grado di eseguire questo compito; i rispettivi prototipi +sono: \begin{funcproto}{ \fhead{sys/time.h} @@ -3746,18 +3748,41 @@ compito; i rispettivi prototipi sono: timespec times[2], int flags)} \fdesc{Cambia i tempi di un file.} } + {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EBADF}] da fare + \item[\errcode{EACCES}] si è richiesta l'impostazione del tempo corrente ma + non si ha il permesso di scrittura sul file, o non si è proprietari del + file o non si hanno i privilegi di amministratore; oppure il file è + immutabile (vedi sez.~\ref{sec:file_perm_overview}). + \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido (solo + \func{futimens}), oppure \param{dirfd} non è \const{AT\_FDCWD} o un file + descriptor valido (solo \func{utimensat}). + \item[\errcode{EFAULT}] \param{times} non è un puntatore valido (per + entrambe), oppure \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è + \var{NULL} o non è un puntatore valido (solo \func{utimensat}). + \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi + di \param{times} (per entrambe), oppure è si usato un valore non valido + per \param{flags}, oppure \param{pathname} è \var{NULL}, \param{dirfd} non + è \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW} + (solo \func{utimensat}). + \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo + corrente, ma non si è proprietari del file o non si hanno i privilegi di + amministratore; oppure il file è \itindex{file~attributes} immutabile o + \textit{append-only} (vedi sez.~\ref{sec:file_perm_overview}). + \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle + componenti di \param{pathname} (solo \func{utimensat}) \end{errlist} - ed inoltre nel loro significato generico.} + ed inoltre per entrambe \errval{EROFS} e per \func{utimensat} + \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel + loro significato generico.} \end{funcproto} Entrambe le funzioni utilizzano per indicare i valori dei tempi un -vettore \param{times} di due strutture \struct{timespec} che permette di -specificare un valore di tempo con una precisione fino al nanosecondo, la cui -definizione è riportata in fig.~\ref{fig:sys_timespec_struct}. +vettore \param{times} di due strutture \struct{timespec}, la cui definizione è +riportata in fig.~\ref{fig:sys_timespec_struct}, che permette di specificare +un valore dei tempi con una precisione fino al nanosecondo. \begin{figure}[!htb] \footnotesize \centering @@ -3782,23 +3807,39 @@ quello di ultima modifica. Quando si usa uno di questi valori speciali per \var{tv\_nsec} il corrispondente valore di \var{tv\_sec} viene ignorato. Queste due funzioni sono una estensione definita nella revisione POSIX.1-2008 -dello standard POSIX; sono state introdotte a partire dal kernel 2.6.22, e -supportate dalla \acr{glibc} a partire dalla versione 2.6.\footnote{in - precedenza, a partire dal kernel 2.6.16, era stata introdotta la funzione - \funcm{futimesat} seguendo una bozza della revisione dello standard poi - modificata, questa funzione, sostituita da \func{utimensat}, è stata - dichiarata obsoleta, non è supportata da nessuno standard e non deve essere - più utilizzata: pertanto non la tratteremo.} La prima è sostanzialmente una -estensione di \func{futimes} che consente di specificare i tempi con -precisione maggiore, la seconda supporta invece, rispetto ad \func{utimes}, -una sintassi più complessa che, come vedremo in sez.~\ref{sec:file_openat} -consente una indicazione sicura dei \itindsub{pathname}{relativo} -\textit{pathname relativi} specificando la directory da usare come riferimento -in \param{dirfd} e la possibilità di usare per \param{flags} il valore -\const{AT\_SYMLINK\_NOFOLLOW} per indicare alla funzione di non dereferenziare -i collegamenti simbolici; si rimanda pertanto la spiegazione del significato -degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che -usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. +dello standard POSIX, in Linux sono state introdotte a partire dal kernel +2.6.22,\footnote{si tenga presente però che per kernel precedenti il 2.6.26 le + due funzioni sono difettose nel rispetto di alcuni requisiti minori dello + standard e nel controllo della correttezza dei tempi, per i dettagli dei + quali si rimanda alla pagina di manuale.} e supportate dalla \acr{glibc} a +partire dalla versione 2.6.\footnote{in precedenza, a partire dal kernel + 2.6.16, era stata introdotta una \textit{system call} \funcm{futimesat} + seguendo una bozza della revisione dello standard poi modificata; questa + funzione, sostituita da \func{utimensat}, è stata dichiarata obsoleta, non è + supportata da nessuno standard e non deve essere più utilizzata: pertanto + non ne parleremo.} La prima è sostanzialmente una estensione di +\func{futimes} che consente di specificare i tempi con precisione maggiore, la +seconda supporta invece, rispetto ad \func{utimes}, una sintassi più complessa +che consente una indicazione sicura del file su cui operare specificando la +directory su cui si trova tramite il file descriptor \param{dirfd} ed il suo +nome come \itindsub{pathname}{relativo} \textit{pathname relativo} +in \param{pathname}.\footnote{su Linux solo \func{utimensat} è una + \textit{system call} e \func{futimens} è una funzione di libreria, infatti + se \param{pathname} è \var{NULL} \param{dirfd} viene considerato un file + descriptor ordinario e il cambiamento del tempo applicato al file + sottostante, qualunque esso sia, per cui \code{futimens(fd, times}) è del + tutto equivalente a \code{utimensat(fd, NULL, times, 0)}.} + +Torneremo su questa sintassi e sulla sua motivazione in +sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le +cosiddette funzioni \textit{at}) che la utilizzano; essa prevede comunque +anche la presenza dell'argomento \param{flags} con cui attivare flag di +controllo che modificano il comportamento della funzione, nel caso specifico +l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla +funzione di non dereferenziare i collegamenti simbolici, cosa che le permette +di riprodurre le funzionalità di \func{lutimes}. + + \section{Il controllo di accesso ai file} @@ -3807,25 +3848,28 @@ usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella del controllo di accesso ai file, che viene implementato per qualunque filesystem standard.\footnote{per standard si intende che implementa le - caratteristiche previste dallo standard POSIX; in Linux sono disponibili - anche una serie di altri filesystem, come quelli di Windows e del Mac, che - non supportano queste caratteristiche.} In questa sezione ne esamineremo i -concetti essenziali e le funzioni usate per gestirne i vari aspetti. + caratteristiche previste dallo standard POSIX; in Linux sono utilizzabili + anche filesystem di altri sistemi operativi, che non supportano queste + caratteristiche.} In questa sezione ne esamineremo i concetti essenziali e +le funzioni usate per gestirne i vari aspetti. \subsection{I permessi per l'accesso ai file} \label{sec:file_perm_overview} -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 utente e gruppo (\ids{UID} e \ids{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 -\struct{stat} (si veda sez.~\ref{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.} +Ad ogni file Linux associa sempre, oltre ad un insieme di permessi, l'utente +che ne è proprietario (il cosiddetto \textit{owner}) ed un gruppo di +appartenenza, indicati dagli identificatori di utente e gruppo (\ids{UID} e +\ids{GID}) di cui abbiamo già parlato in +sez.~\ref{sec:proc_access_id}.\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 queste + proprietà vengono assegnate in maniera fissa con opportune opzioni di + montaggio.} Anche questi sono mantenuti \index{itinode} sull'\textit{inode} +insieme alle altre proprietà e sono accessibili da programma tramite la +funzione \func{stat} (trattata in sez.~\ref{sec:file_stat}), che restituisce +l'utente proprietario nel campo \var{st\_uid} ed il gruppo proprietario nel +campo \var{st\_gid} della omonima struttura \struct{stat}. Il controllo di accesso ai file segue un modello abbastanza semplice che prevede tre permessi fondamentali strutturati su tre livelli di accesso. @@ -3833,10 +3877,11 @@ Esistono varie estensioni a questo modello,\footnote{come le \itindex{Access~Control~List~(ACL)} \textit{Access Control List} che sono state aggiunte ai filesystem standard con opportune estensioni (vedi sez.~\ref{sec:file_ACL}) per arrivare a 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 -soddisfare tutte le necessità più comuni. I tre permessi di base associati ad -ogni file sono: + sofisticati come il \itindex{Mandatory~Access~Control~(MAC)} + \textit{mandatory access control} di SE-Linux e delle altre estesioni come + \textit{Smack} o.} ma nella maggior parte dei casi il meccanismo standard è +più che sufficiente a soddisfare 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}). @@ -3870,23 +3915,23 @@ I restanti tre bit (noti come \itindex{suid~bit} \textit{suid bit}, \itindex{sgid~bit} \textit{sgid bit}, e \itindex{sticky~bit} \textit{sticky bit}) sono usati per indicare alcune caratteristiche più complesse del meccanismo del controllo di accesso su cui torneremo in seguito (in -sez.~\ref{sec:file_special_perm}); lo schema di allocazione dei bit è -riportato in fig.~\ref{fig:file_perm_bit}. - -Anche i permessi, come tutte le altre informazioni pertinenti al file, sono -memorizzati \itindex{inode} nell'\textit{inode}; in particolare essi sono -contenuti in alcuni bit del campo \var{st\_mode} della struttura \struct{stat} +sez.~\ref{sec:file_special_perm}), lo schema di allocazione dei bit è +riportato in fig.~\ref{fig:file_perm_bit}. Come tutte le altre proprietà di +una file anche i permessi sono memorizzati \itindex{inode} +nell'\textit{inode}, e come accennato in sez.~\ref{sec:file_types} essi sono +contenuti in una parte del campo \var{st\_mode} della struttura \struct{stat} (si veda di nuovo fig.~\ref{fig:file_stat_struct}). In genere ci si riferisce ai tre livelli dei privilegi usando le lettere \texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o} (per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti insieme si usa la lettera \texttt{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 +questa distinzione dato che in certi casi, mutuando la terminologia in uso a +suo tempo 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}, già viste in +tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza in tab.~\ref{tab:file_bit_perm}. \begin{table}[htb] @@ -3924,18 +3969,18 @@ La prima regola è che per poter accedere ad un file attraverso il suo \textit{pathname} occorre il permesso di esecuzione in ciascuna delle directory che compongono il \textit{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 significa che essa può -essere attraversata nella risoluzione del \textit{pathname}, ed è distinto dal -permesso di lettura che invece implica che si può leggere il contenuto della -directory. +esecuzione). Per una directory infatti il permesso di esecuzione significa che +essa può essere attraversata nella risoluzione del \textit{pathname}, e per +questo viene anche chiamato permesso di attraversamento. Esso è sempre +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). +lettura si potrà lo stesso aprire un file all'interno di una una directory (se +si hanno i permessi adeguati per il medesimo) ma non si potrà vederlo con +\cmd{ls} mancando il permesso di leggere il contenuto della directory. Per +crearlo o rinominarlo o cancellarlo invece occorrerà avere 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 tab.~\ref{tab:file_open_flags}) di sola lettura o @@ -3947,14 +3992,15 @@ 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 stessi permessi occorrono per cancellare un file da una directory (si ricordi 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 riferimento). +disco). Per la cancellazione non è necessario nessun tipo di permesso per il +file stesso dato che, come illustrato in sez.~\ref{sec:link_symlink_rename} +esso non viene toccato, nella cancellazione viene solo modificato il contenuto +della directory, 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 -avere il permesso di esecuzione, inoltre solo i file regolari possono essere -eseguiti. +shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre, +oltre al permesso di lettura per accedere al contenuto, avere anche il +permesso di esecuzione. Inoltre solo i file regolari possono essere eseguiti. I permessi per un collegamento simbolico sono ignorati, contano quelli del file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta @@ -3993,18 +4039,18 @@ di accesso sono i seguenti: proprietario del file (nel qual caso si dice che il processo è proprietario del file) allora: \begin{itemize*} - \item se il relativo\footnote{per relativo si intende il bit di user-read se - il processo vuole accedere in lettura, quello di user-write per - l'accesso in scrittura, ecc.} bit dei permessi d'accesso dell'utente è - impostato, l'accesso è consentito - \item altrimenti l'accesso è negato + \item se il relativo\footnote{per relativo si intende il bit di + \textit{user-read} se il processo vuole accedere in lettura, quello di + \textit{user-write} per l'accesso in scrittura, ecc.} bit dei permessi + d'accesso dell'utente è impostato, l'accesso è consentito; + \item altrimenti l'accesso è negato. \end{itemize*} \item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari dei processi corrispondono al \ids{GID} del file allora: \begin{itemize*} \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è - consentito, - \item altrimenti l'accesso è negato + consentito; + \item altrimenti l'accesso è negato. \end{itemize*} \item Se il bit dei permessi d'accesso per tutti gli altri è impostato, l'accesso è consentito, altrimenti l'accesso è negato. @@ -4017,6 +4063,38 @@ 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. +\itindbeg{file~attributes} +A questi che sono i permessi ordinari si aggiungono, per i filesystem che +supportano questa estensione, due permessi speciali mantenuti nei cosiddetti +\textit{file attributes}, che si possono leggere ed impostare con i comandi +\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questo comando e le + spiegazioni riguardo gli altri \textit{file attributes} si rimanda alla + sezione 1.4.4 di \cite{AGL}.} + +Il primo è il cosiddetto attributo di immutabilità (\textit{immutable}, +identificato dalla lettera \texttt{i}) che impedisce ogni modifica al file, +\textit{inode} compreso. Questo significa non solo che non se ne può cambiare +il contenuto, ma neanche nessuno dei metadati, ed in particolare non si può +cancellare, rinominare, modificare nei permessi o nei tempi, o creare +\textit{hard link} verso di esso. + +Il secondo è il cosiddetto attributo di \textit{append-only}, (identificato +dalla lettera \texttt{a}) che consente soltanto la scrittura del file in coda +al file. Il file cioè può essere soltanto esteso, ma i suoi metadati, a parte +i tempi che può però possono essere impostati al valore corrente, non possono +essere modificati, quindi di nuovo non si potrà cancellare, rinominare, o +modificare nei permessi. + +Entrambi questi attributi attivano queste proprietà a livello di filesytem, +per cui a differenza dei permessi ordinari esse varranno per qualunque utente +compreso l'amministratore. L'amministratore è l'unico che può attivare o +disattivare questi attributi,\footnote{più precisamente un processo con la + \itindex{capabilities} capacità \const{CAP\_LINUX\_IMMUTABLE}.} e potendo +rimuoverli è comunque capace di tornare in grado di eseguire qualunque +operazione. +\itindbeg{file~attributes} + + \subsection{I bit dei permessi speciali} \label{sec:file_special_perm} @@ -6669,8 +6747,9 @@ opportuno dettagliare maggiormente. 2.4).\\ \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare sui file gli attributi \textit{immutable} e - \itindex{append~mode} \textit{append only} (se - supportati).\\ + \itindex{append~mode} \textit{append-only} (vedi + sez.~\ref{sec:file_perm_overview}) se + supportati.\\ \const{CAP\_MKNOD} & La capacità di creare \index{file!di~dispositivo} file di dispositivo con \func{mknod} (vedi diff --git a/img/fileperm.dia b/img/fileperm.dia index e6a24a5ba89e7dee1927fd2c7aa8b7e1a72777c4..ddb68ada930e9735db36ac78152d89144980779f 100644 GIT binary patch delta 1879 zcmV-d2dMbc4&Dxs9Dmg*)&TdI=&jxKXwpLj(Bsz&-_Sr|tH`%(yrpQzY1*E72 z<{Xj!pP$IXOFn;jUWLO)nxsJ-jSU2#F{IHfo(IulZ2a^6_m7_O<$mya9*|G`XOWQA zkpD)MW}n8!lCkxt(dg;v3545}us8u>umLF@{YS!(jCi4uaeqG;4vPlngpust{w`rG z38ouHhY?xPu`wmHAB!a3L~~o^T~5w=~IiqzQ2{wk@h!EwyGYq)(KmY zWD!JVKfGEL>n=zq>o{Qv30T?XG>$_` zqMcWkZ0PNN(isW4#G0xlP>Y9vvAE^=A4r(KqyoF!$7s7Yau-Q3Zw}nE5;azyf;n4G zo|~Er0%*hY%e=h>cMiAe96knVFb!!{9fODoE8<{&+kcJu%kMB}{OQ*PHM6r;`x2RZ z)TZ|JFOkJ2nA5aHjOS%)EG_rNMs2NrS?;9`v%7WiO3z({WJ{C1`LCy!`EdUQ@3}N2 zGZs7^J{8&|p8iW`Y+u>G8Hwg3nGZh>zsAqTsi(sGDZzYf{0Yw+>#};>7^h{awbt=b zQV=+I5Px`=4N!(mo%!kX(t5(5pG1q09z58t&3(A8{R`qR0{bri_co6-q^rp+PNH&8 zqN_^fE^@k*D|RG5zyijXG*~QIgZ0~NPvc}xleR~1hT=8;(q;TKspzh@zl*DhFgnTq z=6FD&@xZkyIUZ0J3Hx|30aOtWLY30-(BpW(qJQyVN{$8${9`m&0IP@wQ^&%)j0ICP z7PvkoM}q~>F&b=OsfY%lO6hp$MLhfwM6@CxEb)MFqz8oU=KLTdYsz;mEY<=m!YLtJC(U5=1FAy|RA}w1~TDEjy`A1>d04fre-6ktr zi+`$KRE}_G7Fd#HWdidkEACB^tV;E&E~2GXD=k-CTAp-ixdmx?%B1DBOUu*Js+X20 zDlII1*nt5$N{f3_B&|}ts*7l8)k@13mzE=4T6RHNjxuRE?b6a6_y%bqD4t2Tq-WAk zoh_uSvxV9_TS#}d8nq=pOCx>G(l01W)qm&^wdzW%imU27eP#t!p@XV~=Q`}Xw_!=t zl?@Qew1iNe;Kg3{!E$c%$g*~5S@v;JrY<{~uckXIcd_v9xn|v6!!ne*l}~ZRsyt=) zhYw^Ggxj(4E#g6w#vx(E7^ZBSEt{}BV{hWOc#{M)DMrfm&rwP&S8CV7W`5ZohkpRJ z5EgTKuD=&)@D?}c%X1o5dO|4Xh=jo+TG8rnlyc@&tXpbYxm30I=DMJG%pd78EKZMN zs$r4%T$5xHnZQ4h$O2H4NRy~hfto{oCXpf%nL1DO7FgtpFTs?Z zDYAfB%oJIgMVdt|8q_T6Ba1p%sANgc6`92mT7Ovdq*G)s zMsqZaG>cj^s9DrQ7GWqpM)RbP(cIz~&C@K>ENao9W>Ftm)WP{Cj`UfyLVv#q^{8LO zG>g=*2UJ7RwQ znmF>#arBLG)y>`{k4ie!JnAEl{4Q2_%H@#-Z1dPXvH|Q>|0rh5*XgN=Ow`3F5K7+TXJs70 z*%;8x{#t?6i~be~!}r?T^7!Su5ZMlY6Dir@2la}ro{#@b+{LaM43OMiHQB~?A7@)? zoI8_4yALEv2W$`wehjvH^rvF RBxH3z_#bu#in*ha00736rPKfb delta 1867 zcmV-R2ekO!4$=;g9Dg+_)&au?4CuqU=YX~uN2@Fu5}m{^`|P9Sn`}!~Y>I4^9s>y= zfjLK{|K}(2@RE<8Ugq)eiD!9~Cbt$r*c$R=l1`&!c5D6f_4oII_33W#aT>7?@@JN@ z`B45vk{4IE)}s)M52MlZ^D~N9ITLAy;%JF-KKhTvF&oK3BY*2|FdSA5OqpQCz0F-F zL>7&gf)5im=eO3FO}@>tbeT-8b*W9cNgAiw@QKB@*1L!DV~sXuMhAAz*j}(1A7`9> zYc`GLCk(GKz2Mog+4&;PBUwbO7AHj->=eH%Wj3X9Styy^z5CU9w|=C}jlHe92W@mB z<}8~<$*CXNHh=NDAt(wcrLr;HFbJ{l_+;BAm%AIAbr+j;mzi}J<@bv;6B&!dsmpPi z#+)T;2>t7E6hptCm779wH&qmgj$9asHYLtZ(n4?b67dWzqC};2xA{u<{&D z#pC_Ux#q$MyZG>9U*CdjhbwaqpQ1b($GonNQ6iKTv41tc>c;%>cUUrh|L2ODSzBv- ziA)3Ta`*C=$ZQ!+dEO$%!!iw)9yi5CZLNM>?zIiGzIF6UFI~iJ#j}n1&-<78aPtLk zxHM!F5j}0MDs7UE|K$_0sqEi^B~zA7hwq1<(-&*sQ<43YXnJdX!H11?Ts>(_((7=L*;7zM`-a0;0w^W*Wc^-MlLOJ*_OdT@PL`tW`C7b0H-?oIjoI*&Z&^ZQAf zC8s@!t}0c!DCu%qu^sslRWSa@quHZ4WBoeY<20M{tnJayL-7)S`D6NgU(;P}e;3yi zVYHY3)$u@7<3Vaub3BkD5;pN*BWxlblqv=B(0}82psMj;YmNqr!d)~th?8rI#NS%%WI@+nP3 zou}gd@PW;vcy(+2naH5Y)0hcn4Rf(7mQ6T;wK4Hqy38V;RU_r{=Qv3$*J{_Hc7OSC z0|^1@5US?%P=Bw|;5BXzm*<>W>4~wLBNj)qWX|iqQ7)NNvu^3!%B8x+Hx20;+v>3DJ<1aSi42j*hCI<*V3DuB z1XFjW$U$~BQ{(`PfJH4D1Qzv?MI9_uak1Xood=pRmEPq<1UqpJ; zFA~5aGb|#|FM10sqUtQtKci2oEb7lZS`I8S#UhwTdjl-8)z3lHJx0UTF&ggC7!6ot zh(#F2XnkT)!|q1vsP98_Zm8Z<#=-(Vp+iDaoHK^q8;Y>hd8qsRo5PybpGHRC-VVn` z_OeXevn)%Wn^miB`#$E$?0$k8!p9XM@mwT^sB-DzsVon>Z#rfhu zHXs|2?R%50DL>|Sv9^;Us`(JQ0%x>1CyW%%9N+!%vt!Gg8(wIhvwtMtWybI}G4=Kh7dtDUC(&51Rj~-(TNU$N8go4>+6`Ucy>2fU&x