Lezione Precedente Elenco Lezioni Lezione Successiva

Laboratorio di Sistemi Informativi

Gestione utenti

Una installazione di MySQL a regime può contenere vari schemi e varie tabelle in ogni schema. In generale, nasce il problema che non tutti gli utenti devono avere un accesso indiscriminato a questi dati. Ad esempio, l'ufficio stipendi in una impresa potrebbe aver bisogno di accedere all'archivio anagrafico dei dipendenti, ma solo in lettura. La modifica di questi dati spetta invece all'ufficio personale, e solo a questo deve essere consentito l'accesso ai dati anagrafici in scrittura.

Per fortuna, MySQL consente di dare diritti ben precisi ad utenti diversi. Il compito di assegnare questi diritti spetta all'amministratore di database (DBA: database administrator). Il DBA è una persona che si occupa della gestione e del corretto funzionamento del DBMS usato: installazione, creazione degi schemi, backup periodici dei dati sono tipici esempi di attività affidate al DBA. Non è invece detto che il DBA si occupi anche della progettazione dei database o delle applicazioni che li utilizzano: spesso questi compiti, almeno nelle grosse installazioni, vengono affidate a persone diverse, per cui il DBA ha solo il ruolo di coordinatore e di amministratore del sistema nel suo complesso.

Utenti e MySQL

Ogni qualvolta noi ci colleghiamo ad un server MySQL, esso ci identifica sulla base di due informazioni: il nome utente e il computer da cui ci colleghiamo, secondo la sintassi

<nomeutente>@<macchina da cui si collega>

o, in inglese

<username>@<hostname>

Ad esempio, l'utente pippo, quando è collegato dalla stessa macchina dove risiede il server, si chiama pippo@localhost, mentre per pluto collegato da pc-clei-001.unich.it si ha pluto@pc-clei-001.unich.it. Possiamo conoscere l'utente corrente con la funzione intrinseca user(), come in:

mysql> SELECT USER();

+-----------------+
| USER()          |
+-----------------+
| amato@localhost |
+-----------------+

Ricordiamo che possiamo specificare il nome utente con cui ci vogliamo collegare facendo partire il client mysql con l'opzione -u, mentre l'opzione -p serve a richiedere una password, nel caso sia necessaria per accedere all'account. Ad alcuni account, infatti, si può accedere anche senza alcuna password.

Utenti reali e utenti formali

Gli utenti di MySQL possono essere manipolati con comandi molto semplici:

Quando MySQL viene installato per la prima volta, viene creato automaticamento l'utente root@localhost. Talvolta questo utente viene creato privo di password, e in tal caso è bene che l'amministratore del sistema si affretti a inserirne una. È infatti ovvio che lasciare un utente privo di password costituisce un buco di sicurezza enorme, ed è del tutto inaccettabile se non in una installazione locale, dove tutte le persone che possono accedere fisicamente alla macchina sono fidate, e la macchina non è connessa in rete.

Per consentire maggiore flessibilità nella gestione dei diritti di accesso, è possibile creare utenti nella cui parte hostname compare il carattere jolly percentuale %. Il simbolo % sta ad indicare un stringa qualunqe. Ad esempio:

Notare che, quando si utilizza il carattere %, l'hostname va messo tra apici (') o accenti (`).

Per la username non è possibile usare il carattere jolly %. Tuttavia, è possibile specificare un nome utente vuoto, che sta ad indicare l'utente anonimo. Ad esempio:

Chiamiamo utenti reali le combinazioni username@hostname effettive di chi si connette a MySQL (ricavabile come abbiamo visto dalla funzione intrinseca USER) e utenti formali le combinazioni username@hostname specificate nei comandi CREATE USER. Al momento della connessione, MySQL fa corrispondere all'utente reale che si sta connettendo uno degli utenti formali di cui dispone. A questi ultimi, infatti, verranno concessi eventuali diritti di accesso. Nell'effettuare questa corrispondenza, MySQL sceglie sempre, tra tutti gli utenti formali disponibili che possono corrispondere a quello reale (in slang si dice che "matchano"), quello che ha il nome host più specifico.

Ad esempio, supponiamo siano disponibili gli utenti formali a@xyz.unich.it e a@`%.unich.it`. L'utente reale a@xyz.unich.it potrebbe corrispondere a entrambi, ma poiché a@xyz.unich.it ha la parte hostname più specifica, questo è quello che viene scelto. Al contrario, l'utente reale a@uvw.unich.it viene fatto corrispondere all'utente formale a@`%.unich.it`.

Per scoprire chi è l'utente formale attuale si può usare la funzione intrinseca CURRENT_USER(), come in:

mysql> SELECT CURRENT_USER();

+-----------------+
| CURRENT_USER()  |
+-----------------+
| amato@%         |
+-----------------+

Utenti e diritti di accesso

Una volta creato un utente formale (da qui in avanti chiamato semplicemente utente), questi può accede solo allo schema speciale information_schema. Per concedere diritti (chiamati anche privilegi) ad un utente si può utilizzare il comando GRANT. Con GRANT è possibile concedere diritti diversi ad un utente su tutti i dati di un server, su uno specifico schema, su un tabella o su specifiche colonne di una tabella.

Diritti a livello di server

La sintassi per concedere diritti a livello di server è la seguente I privilegi che è possibile concedere cambiano a seconda della versione di MySQL che si sta utilizzando. Per avere un elenco aggiornato, si può usare il comando:

Notare che è possibile concedere dei diritti anche ad utenti inesistenti. In tal caso l'utente verrà creato automaticamente, senza bisogno del comando CREATE USER.

Alcuni dei diritti che è possibile concedere sono:

Un diritto concesso con questa sintassi riguarda tutti gli schemi presenti in una macchina. Così il comando GRANT SELECT ON *.* TO pippo@localhost consente, all'utente pippo, quando si connette da localhost, di accedere in lettura a qualunque schema presente nel computer. Non consente tuttavia alcuna modifica dei dati.

Il comando GRANT non revoca mai privilegi già concessi, ma semplicemente aggiunge nuovi privilegi. Così dopo i comandi

GRANT SELECT ON *.* TO pippo@localhost
GRANT INSERT ON *.* TO pippo@localhost


l'utente pippo@localhost avrà sia il privilegio SELECT che INSERT. Per eliminare i diritti già concessi, invece, è possibile usare l'istruzione REVOKE, che ha una sintassi simile a quella del comando GRANT:
Infine, per esaminare i privilegi che sono stati concessi a un utente, si può usare il comando SHOW GRANTS.
Vengono visualizzati i comandi GRANT che sarebbero necessari per concedere all'utente, su un'altra installazione di MySQL, gli stessi diritti che ha attualmente.

Diritti a livello di schema

Si possono anche concedere diritti che non valgono su tutti i dati di un server, ma selettivamente a livello di un singolo schema. La sintassi è simile al caso precedente: Ad esempio, supponiamo di concedere all'utente pippo la possibilità di agire indiscriminatamente sullo schema airdb:

GRANT ALL PRIVILEGES ON airdb.* TO pippo@localhost

In questo modo pippo può accedere in lettura a tutti i (a seguito della istruzione GRANT della sezione precedente), ed ha pieno accesso in lettura e scrittura allo schema airdb (grazie all'ultima istruzione GRANT). Notare che i diritti a livello di schema non vengono influenzati quando si revoca un diritto a livello di server. Ovvero, se noi diamo il comando

REVOKE SELECT ON *.* FROM pippo@localhost

l'utente pippo conserva tutti i suoi diritti su airdb. Perde però tutti i diritti di lettura non esplicitamente concessi a livello di singolo schema.

GRANT option

Se concediamo dei diritti ad un utente, possiamo anche consentirgli, a sua volta, di cedere questi diritti ad altri utenti. Per far ciò basta aggiungere la clausola WITH GRANT OPTION alla fine del comando GRANT:

GRANT ALL PRIVILEGES ON airdb.* TO pippo@localhost WITH GRANT OPTION

In questo modo non solo pippo potrà utilizzare come vuole lo schema airdb, ma potrà a sua volta concedere diritti su questo schema ad altri utenti. Notare che un utente non può mai concedere diritti superiori di quelli di cui dispone.

Per revocare il diritto di grant, si usa REVOKE con il privilegio GRANT OPTION, ovvero:

REVOKE GRANT OPTION ON airdb.* FROM pippo@localhost

Diritti a livello di tabella e colonna

I diritti possono anche essere concessi a livello di singola tabella con I privilegi sono gli stessi possibili nel caso di diritti a livello di server o di schema. L'unica differenza è che i diritti CREATE o DROP a livello schema consentono di eseguire le istruzioni CREATE SCHEMA e DROP SCHEMA, mentre in un diritto a livello di singola tabella, è possibile solo utilizzare la CREATE TABLE e la DROP TABLE.

Infine, i diritti a livello di colonna si concedono con In questo caso, gli unici privilegi che si possono usare sono ALTER, DELETE, INSERT, SELECT e UPDATE. Ad esempio con

GRANT SELECT(id) ON airdb.aeroporti TO paperino@localhost

l'utente paperino potra accedere allo schema airdb e dare il comando

SELECT id FROM aeroporti

ma non il comando

SELECT * FROM aeroporti

Analogamente a quanto visto nelle sezioni precedenti, si può usare il comando REVOKE per revocare dei privilegi precedentemente concessi a livello di singola tabella o di colonna.

Interazioni tra utenti reali, formali e diritti di accesso

La maniera con cui MySQL fa corrispondere utenti reali a formali, e concede a questi ultimi i diritti di accesso, può generare della confusione e portare a risultati contro-intuitivi. Supponiamo che vengano dati i seguenti comandi:

CREATE USER a@xyz.unich.it;
CREATE USER a@'%.unich.it';
GRANT SELECT ON *.* TO a@xyz.unich.it;
GRANT ALL PRIVILEGES ON *.* TO a@'%.unich.it';

Ci si chiede se l'utente a, connesso dal computer xyz.unich.it, abbia o no i diritti UPDATE, INSERT, etc.. sui vari database del server. La risposta è negativa. Infatti l'utente a, connesso dal computer xyz.unich.it, è l'utente reale a@xyz.unich.it che, al momento della connessione, viene fatto corrispondere all'utente formale a@xyz.unich.it. Gli unici diritti di cui esso dispone sono quelli concessi esplicitamente all'utente formale in questione, e quindi solo il diritto SELECT.

In maniera un po' paradossale, se si cancella l'utente a@xyz.unich.it col comando DROP USER a@xyz.unich.it, accade che l'utente reale a@xyz.unich.it venga fatto corrispondere all'utente formale a@`%.unich.it` che invece dispone dei privilegi necessari.

Esercizi e Soluzioni

Esercizio 1

Supponiamo di avere i seguenti utenti formali:
  1. root@localhost
  2. andy@localhost
  3. ``@localhost
  4. andy@`%`
  5. tim@`%.imaginary.com`
  6. randy@`%`
A quali utenti formali vengono fatti corrispondere i seguenti utenti reali?

root@localhost
andy@localhost
george@localhost
andy@www.imaginary.com
randy@localhost
root@www.imaginary.com

Esercizio 2

Scrivere i comandi GRANT necessari per concedere i seguenti diritti di accesso:
Lezione Precedente Elenco Lezioni Lezione Successiva

Valid HTML 4.01 Transitional Valid CSS!