Archivi categoria: WikiNotes

Determinare i permessi di file e directory

Nei sistemi operativi multi-utente viene solitamente previsto un meccanismo che garantisca l’accesso in lettura e scrittura a file e directory solo a chi ha i permessi per farlo.

I sistemi Unix-like, come Linux,  implementano un sistema che distingue i permessi di lettura, scrittura ed esecuzione in 3 livelli di accesso: il proprietario (user), un gruppo di utenti (group) e tutti gli altri. Il file system associa a ogni file (e directory) una mascheratura di bit, ciascuno dei quali ha un significato e il relativo valore determina il permesso di accesso. Si hanno un bit per stabilire il permesso in lettura, un’altro bit per il permesso in scrittura e un altro ancora per il permesso di esecuzione. Questa tripla si ripete per altre due volte, ottenendo così tre triple, una per livello.

Tuttavia, per questioni di leggibilità, si preferisce visualizzare questa mascheratura attraverso il suo corrispettivo valore decimale che possiamo calcolare tramite questo schema:

Livello Read Write Execute Somma
User 4 2 1 7
Group 4 2 1 7
All 4 2 1 7

Per ottenere il valore è sufficiente calcolare la somma di ogni riga.

Per esempio: abilitiamo l’utente-proprietario ad accedere in lettura e in scrittura, mentre la sola lettura tutti gli altri. Lo schema verrebbe così:

Livello Read Write Execute Somma
User 4 2 6
Group 4 4
All 4 4

Pertanto, per impostare questi permessi ad un ipotetico file pippo è sufficiente aprire una shell e scrivere:

# chmod 644 pippo

Se i permessi di lettura e scrittura risultano ovvi, quello di esecuzione merita una spiegazione a parte. Questo tipo di abilitazione ha un significato particolare quando viene associato a:

  • file: in questo caso indica se il file può essere eseguito o meno. Pensiamo ad esempio ad un file binario o a uno shell script.
  • directory: in questo caso indica se si hanno i permessi aprirla, ovvero leggerne il suo contenuto.

 

Controllare l’accesso ai membri di una classe

Con l’utilizzo dei qualificatori di accesso possiamo determinare quando un particolare campo o metodo di una classe può essere invocato da un’altra. Impararne il corretto utilizzo è un requisito essenziale per chiunque desideri progettare un’interfaccia software solida, robusta e ben scritta.

Il linguaggio Java definisce due livelli di accesso:

  • a livello di classe, o esternopublic, oppure package-private (nessun modificatore esplicitamente dichiarato);
  • a livello di membro di una classe, o interno: public, private, protected, o package-private (nessun modificatore esplicito).

Quando una classe viene dichiarata public, diventa visibile a tutte le altre. Se invece non viene definito nessun modificatore, allora rimane visibile soltanto all’interno dello stesso package dove la classe è stata dichiarata.

All’interno di una classe possiamo utilizzare il qualificatore public per rendere accessibile ovunque quel campo o quel metodo, oppure nessun modificatore (package-private) per limitarne l’accesso all’interno dello stesso package. In aggiunta possiamo utilizzare i qualificatori private e protected. Il primo indica che il membro può essere visto soltanto nella sua classe. Il secondo invece indica che il membro può essere visto anche dalle classi dello stesso package e, in aggiunta, dalle sue classi discendenti, anche in package differenti.

La tabella che segue schematizza quanto appena detto:

Livelli di accesso
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

 

Come si può vedere, una classe ha sempre accesso a tutti i suoi membri. La colonna Package ci dice invece quando il membro è accessibile dalle altre classi dello stesso package. La colonna Subclass indica invece quando una classe figlia ha accesso al membro, a prescindere dal package di appartenenza. La colonna World, infine, ci dice quando tutte le altre classi hanno accesso al membro.

I livelli di accesso influiscono in maniera significativa nella progettazione di un’interfaccia software. Quando si usano le classi provenienti da una libreria esterna, come ad esempio quelle della libreria standard di Java, i qualificatori determinano infatti quali classi e quali membri è possibile utilizzare nel proprio codice sorgente. Inoltre, quando si scrive una nuova classe e si definisce il livello di accesso di ogni singola variabile e di ciascun metodo, si definisce implicitamente una nuova interfaccia, nascondendo al mondo esterno l’implementazione dell’interfaccia stessa. Questo concetto è alla base dell’incapsulamento e del polimorfismo nel paradigma della programmazione a oggetti.

Prendiamo adesso, a titolo di esempio, un insieme di classi definite in due package distinti e vediamo come i qualificatori di accessi modificano la visibilità di ogni membro nelle altre classi.

classes-access

Visibilità
Modifier Alpha Beta Alphasub Gamma
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

 

Ecco alcuni consigli per scegliere il livello di accesso più appropriato: se altri programmatori usano la nostra classe, dobbiamo assicurarci che non si verifichino errori causati da un utilizzo scorretto.

  • Limitiamo l’accesso per quel particolare membro della classe al livello più restrittivo, purché ciò abbia senso. E’ sempre meglio usare il qualificatore private a meno che non ci sia una ragione valida per fare diversamente.
  • Evitiamo di dichiarare campi public, ad eccezione delle costanti. Variabili pubbliche tendono infatti a legarti a quella particolare implementazione e limita la flessibilità nella modifica e revisione del codice.

Clonazione di un disco

In questo periodo sto leggendo un libro davvero interessante: Computer Forensics di Ghirardini – Faggioli, Apogeo Editore. Il testo tratta delle tecniche di analisi forense in ambito informatico. Grazie a questo libro ho appreso una nuova tecnica per effettuare il clone di un disco. Avevo già trattato questo argomento in precedenza. Tuttavia questo sistema è molto più accurato ed elegante e merita certamente di essere menzionato tra i miei appunti di informatica, in quanto tale metodologia può rivelarsi davvero utile.
Per prima cosa la copia: viene usato il comando dd che esegue una copia byte per byte a prescindere dal tipo di filesystem utilizzato. Ad esempio il comando:

# dd if=/dev/sda of=/percorso/nome_file.img bs=2048

esegue una copia del disco (device) sda (compresa l’MBR, la struttura delle partizioni e lo spazio non utilizzato) nel file nome_file.img. Ovviamente, invertendo gli argomenti, è possibile ripristinare un’immagine creata precedentemente nel disco.
La destinazione deve risiedere necessariamente in un disco diverso da quello sorgente. Quindi dobbiamo disporre di un altro supporto, interno o esterno, purché abbastanza capiente da contenere il file immagine, che avrà come dimensione finale la dimensione nominale del disco sorgente. Come possiamo fare se non si dispone di un supporto secondario? Gli autori descrivono come trasferire il file immagine in un’altra macchina via rete attraverso il tool netcat. Questo programma è in grado di restare in ascolto su una determinata porta e riportare tutto quello vi passa in un file. Dunque, possiamo procedere in questa maniera: nel computer di destinazione, che farà da server, avviare netcat:

$ netcat -l -p 5959 > nome_file.img

Sul pc client, dove risiede il disco da clonare:

# dd if=/dev/sda bs=2048 | netcat 192.168.0.1 5959

I parametri sono ovviamente a titolo di esempio. Quindi, nel caso reale, dovremo indicare l’indirizzo reale del server e una porta che non sia già usata da un altro programma in quel momento.
Una volta ottenuta l’immagine del disco, è possibile ripristinarla allo stesso modo, oppure montarla attraverso i loop device. Tuttavia dobbiamo ricordarci che quello che abbiamo in mano è la copia raw del disco e non una partizione. Quindi dobbiamo prima analizzare lo schema di partizionamento del disco, poi procedere con il montaggio della partizione di nostro interesse. Quindi:

$ fdisk -u -l nome_file.img

e otterremmo un risultato simile a questo:

Device Boot      Start         End      Blocks   Id  System
nome_file.img1   *          63   113627744    56813841    7  HPFS/NTFS
nome_file.img2       113627745   156296384    21334320    7  HPFS/NTFS

Per montare la partizione dobbiamo calcolare il valore di offset che è dato dal numero di blocco iniziale * 512. Nell’esempio, la partizione nome_file.img1, che è di tipo ntfs inizia dal blocco 63, perciò: 63 * 512 = 32256. Quindi:

# mount -t ntfs -o ro,loop,offset=32256 nome_file.img /percorso/mountpoint

Soluzioni a linea di comando per il backup in Mac OS X

Fare il backup del proprio hard drive è un po’ come andare dal dentista: importante ma sgradevole, tanto da rimandarlo o dimenticarsene. Proprio per questo, il miglior modo per tenere al sicuro i propri dati è di programmare dei backup in modo regolare. Esistono in commercio diverse soluzioni, tra cui il software Apple .mac Backup, che però necessita la sottoscrizione del relativo servizio a pagamento e che l’utente si sia autenticato.
La tradizionale alternativa UNIX consiste nell’eseguire programmi di backup a linea di comand in uno script di cron, ma molti amministratori ignorano la varietà di opzioni disponibili per backup non controllati sotto Mac OS X.
Questo articolo tratta di alcuni aspetti inerenti la gestione dei backup e delle particolari considerazioni per i sistemi Mac OS X, la varietà delle opzioni che permettono la creazione delle copie e i trabocchetti nei quali si può cadere quando si sviluppa un sistema di backup. L’articolo non copre i flags BSD e i sistemi precedenti a Mac OS v10.4 (Tiger). Inoltre, per semplicità, si presumerà che nei filesystem per i quali si intende effettuare le copie, non siano attivi gli ACL (se si usa Mac OS X Server o fsaclctl). Ci sono alcune questioni su come questi programmi di backup interagiscono con gli ACL che esulano l’obiettivo di questo articolo e pertanto non verranno trattate. E’ possibile comunque consultare la documentazione di ogni programma in maniera più approfondita.

Un po’ di storia, dump e tar

Lo scopo principale di un backup è quello di riprodurre, nella maniera più accurata possibile, lo stato di un filesystem. Nella maggior parte dei casi la duplicazione del contenuto di un file non è sufficiente; la gerarchia del filesystem, i permessi, le date e le altre informazioni devono anch’esse essere preservate. I due principali programmi di backup UNIX, dump e tar, hanno approcci differenti sotto questo aspetto.Il programma dump legge la struttura sottostante il filesystem e ne produce una copia esatta. Fin dagli inizi di UNIX, dump esegue una scansione della tabella degli inode, crea una lista completa di tutti i file del disco e della struttura dei filesystem, analizza le directory e quindi il contenuto dei file. Questo approccio è dovuto alla particolare struttura di un filesystem UNIX, che è differente da un filesystem HFS+. Al contrario, tar usa le API del filesystem per creare l’immagine di una directory e dei file in esso contenuti. Questo approccio risulta più semplice e più portabile ma il formato del file tar non gestisce direttamente le peculiarità di Mac OS X come ad esempio le resource forks e i metadati del filesystem.
In tutti i casi, backup affidabili generalmente richiedono un filesystem inerte, ovvero un filesystem che non venga modificato durante il processo di copia. Per esempio, un file che viene spostato da una directory ad un’altra durante la creazione del backup, potrebbe risultare in entrambe all’interno del backup, o (peggio) in nessuna. Potrebbero verificarsi anche altri tipi errori, alcuni meno evidenti. Un file molto grande che viene riscritto durante il processo di copia, potrebbe venire troncato prima della fine o contenere dati non coerenti dove alcune parti provengono dalla versione originale e altre dalla versione modificata del file, con conseguente perdita di dati.
Sfortunatamente, i moderni sistemi sono spesso attivi 24 ore su 24, 7 giorni su 7, rendendo così impossibile la programmazione dei backup. Tuttavia, in una situazione del genere, una precisa strategia di backup diventa particolarmente importante, vista la più alta probabilità che un data copia di backup si corrompa in qualche modo. Inoltre potrebbe essere utile se si considerano strategie di backup che non operino a livello di filesystem; ad esempio, l’esportazione delle tabelle da un database è un operazione assicurata che produce un’immagine valida di quel databas, che può essere così tranquillamente copiato.

Considerazioni in merito a HFS/HFS+

Il filesystem HFS+ usato in Mac OS X ha una serie di funzionalità e caratteristiche molto diverse da quelle di un tradizionale filesystem UNIX. Più semplicemente, un programma di backup che si basa sulle API del filesystem, per questioni di portabilità, non è in grado di creare copie valide di un filesystem HFS+.
Innanzitutto ogni cosa ha una sua resource fork. Le resource fork vengono ignorate dalle API UNIX tradizionali, in quanto gestiscono solo la data fork di un file. Ci sono poi altre questioni che possono mettere in dubbio una strategia di backup. Gli attributi di un file (i flags del Finder, le date, il tipo di file e i riferimenti a chi lo ha creato) sono informazioni addizionali che un sistema di backup standard per UNIX non solo non ha modo di leggere, ma anche di registrare. Congiuntamente, questi dati sono riferiti da ora in poi come “attributi estesi”.
Il filesystem HFS+ non usa gli inode allo stesso modo dei filesystem UNIX (infatti gli hard link vengono emulati grazie ad un elaborato sistema che riproduce gli stessi effetti di un tradizionale hard link UNIX). Di conseguenza uan strategia di backup basata sulla scansione degli inode è praticamente impossibile.
Gli alberi binari del filesystem da sole potrebbero offrire una soluzione ma in pratica è meglio ignorare questa implementazione e concentrarsi sulle API; questo approccio offre risultati più consistenti ed è portabile.
A causa delle differenze tra i filesystem HFS + e gli UNIX tradizionali (come ad esempio UFS, il filesystem di Berkeley disponibile in Mac OS X) è necessario l’utilizzo di soluzioni particolari per la creazione e il ripristino delle copie di backup nei sistemi Mac OS X.
Inoltre i sistemi non-Mac non possono essere usati per la copia di file provenienti da un sistema Mac. Se si scompattano i file di un archivio su un’altra macchina e poi li si ricompatta, i datiche non possono essere rappresentati su quella macchina verrebbero irrimediabilmente persi.

Cosa funziona in Mac OS X v10.4 Tiger

Esistono alcune soluzioni commerciali per Mac OS X. Dettagli in merito allo loro compatibilità e funzionalità esulano da questo articolo, ma i relativi rivenditori saranno quasi con ogni probabilità felici di rispondere a tali domande. Assicuratevi di chiedere tutte le informazioni che vi servono secondo le vostre specifiche esisgenze. Non tutti i programmi compatibili con Mac OS X supportano pienamente tutte le sue funzionalità.
Ci sono alcune utilità già incluse in Mac OS X che possono essere utili allo scopo almeno in parte. Il più conosciuto è senz’altro ditto, un’utility specifica per Mac OS X che sin dalla nascita è stata in grado di gestire le resource fork dei file (nelle versioni precedenti la 1.4, il flag -rsrc deve essere passato per permettere a ditto di copiare le resource fork). Ditto può essere usato quasi in ogni tipo di situazione dal momento che può copiare interi file, archiviarli e ripristinarli. L’archivio crreato da ditto può essere sia nel formato PkZip che cpio. Siccome ditto può essere eseguito dalla linea di comando, è molto semplice programmare i backup e gestire eventuali problemi senza la necessità di una supervisione costante.
Un’altra opzione è tar che, a partire da Mac OS X 10.4, riconoscee gestisce le resource fork e gli attributi. Per contro non è in grado di gestire path molto lunghi e potrebbe non salvare i nomi dei file in maniera corretta (tale anomalia viene seganalata con un messaggio di errore). Tar può comunque archiviare e ripristinare le resource fork e gli attributi dei file. Nelle versioni più obsolete di Mac OS X tar non gestiva niente che non fosse solo il data fork e i permessi del file.
L’utilità pax è un’alternativa più flessibile rispetto a tar supportando le intestazioni di formati multipli. Preserva inoltre gli attributi estesi. Grazie a queste funzionalità pax è in grado di gestire path più lunghe.
L’utilità rsync offre performance migliori quando si eseguono copie di file particolarmente grossi. Per copiare gli attributi estesi occorre specificare il flag -E. rsync può essere usato in rete per centralizzare i backup.
In termini di affidabilità e velocità l’Apple Software Restore (ASR) è difficile da battere. Questo programma viene usato per la creazione di CD di ripristino in volumi HFS+. Per usare ASR, occorre creare un’immagine del disco  usando Disk Utility (usare il comando Crea immagine da directory, no Crea immagine da dispositivo). Un backup creato in questo modo può essere ripristinato in altri dischi come nello stesso. ASR può ripristinare i dati sostiuendoli oppure ridormattando il disco e poi copiarli in esso. In ogni caso, il largo impiego è dovuto essenzialmente per la velocità but of course it does remove any existing files.
Le immagini disco usate da ASR sono immagini disco standard Mac e possono essere montate nel desktop per copiare file specifici.
Vi è anche un’utlità a riga di comando denominata asr che può essere usata allo stesso modo. Inoltre è possibile specificare un volume esistente come sorgente piuttosto che un un’immagine compressa. Se asr viene richiamato senza il flag -erase, il programma semplicemente estrae i dati nella posizione corrente. Da tenere presente che asr non è in grado di operare in sorgenti o destinazioni che non siano volumi, ovvero non è possibile copiare i file in una subdirectory.
Per effettuare il restore di macchine di cui si conosce perfettamente la configurazione. è possibile usare asr in modelità serve, in cui fornirà una stream da una immagine sorgente. I sistemi client non possono usare questo sistema per un ripristino in locale  senza prima aver riformattato il volume di destinazione.Questo è un ottimo modo per effettuare il backup della configurazione del sistema, ma sarà necessario usare qualcos’altro per i file personali.

Avvertimenti

Ci sono alcune cose da tenere bene a mente quando si sviluppa una strategia di backup. Una delle cose più importanti è quella di testare il proprio sistema di backup in più circostanze differenti. Una delle cose più ovvie da testare è se è effettivamente possibile ripristinare i file. Un programmatore che ha sviluppato un’utilità per l’archiviazione a scopo ricreativo ha osservato che la gente rimane si è sempre impressionata per la qualità dei suoi backup senza chiedersi mai se era possibile effettuarne poi il ripristino. Prima di iniziare a fidarsi del proprio ssitema, è necessario effettuare il ripristino dei dati per testarlo! Ripristinare una gran varietà di file per testare tutte le possibilità: file con resource fork, file con l’ACL (se lo si utilizza), ecc.
I backup su sistemi attivi possono perdere dati significativi. Qualunque strategiadi backup che si adotta per questo tipo di sistemi devono tenere presente questo; se non si prevede questo rischio.

Come prevenire la creazione dei file .DS_Store sui dischi di rete

Mac OS X, quando monta un volume crea nel suo filesystem un file nascosto denominato .DS_Store dove memorizza alcune informazioni usate poi dal Finder. Questo sistema risulta a volte antipatico se un utente si connette ad una condivisione SMB all’interno di una rete ibrida. In questi casi infatti il file risulta visibile agli altri utenti Window e Linux.
Questo meccanismo può essere disattivato per le sole connessioni SMB/CIFS, AFP, NFS e WebDAV.
Aprite il terminale e digitate il seguente comando, seguito da Invio:

$ defaults write com.apple.desktopservices DSDontWriteNetworkStores true

Questo comando modifica le impostazioni dell’utente che si è loggato. Pertanto, in caso di più utenti registrati sul Mac, accedete e per ognuno di essi ripetete la procedura sopra descritta.
La disattivazione della creazione dei file .DS_Store sui dischi di rete non permetterà la gestione dei commenti del Finder su di essi.
Per ulteriori informazioni potete consultare il sito di supporto Apple, in particolare l’articolo HT1629 e 107822.