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:
CREATE USER <username>@<hostname> [IDENTIFIED BY '<password>']
: crea un nuovo utente, eventualmente dotato di password.
DROP USER <username>@<hostname>
: cancella l'utente specificato;
SET PASSWORD [FOR <username>@<hostname>] = PASSWORD('<password>')
: modifica la password per l'utente specificato (o per l'utente corrente, se la clausola FOR
è omessa). Normalmente, solo l'utente root
può modificare le password per gli altri utenti.
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:
- pippo@`%` : l'utente
pippo, da qualunque macchina si colleghi;
- pippo@`%.unich.it` :
l'utente pippo, se si collega da un macchina dell'università
di Chieti;
- pippo@`192.176.24.%`:
l'utente pippo, purché si colleghi da una macchina il cui
indirizzo IP inizia con 192.167.24.
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:
- ``@localhost :
un utente locale anonimo. Corrisponde a tutti gli utenti che si collegano da
localhost e che non hanno dei privilegi specifici.
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
- GRANT <lista privilegi> ON *.* TO <utente formale>: concede dei diritti di accesso all'utente specificato.
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:
SHOW PRIVILEGES
: visualizza tutti i privilegi di accesso supportati dalla versione corrente di MySQL.
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:
- CREATE:
consente l'uso di CREATE TABLE
e CREATE
SCHEMA;
- DROP:
consente l'uso di DROP TABLE
e DROP
SCHEMA;
- ALTER: consente l'uso del comando ALTER TABLE (ma non è possible creare o eliminare indici);
- DELETE: consente l'uso
del comando DELETE;
- INSERT: consente l'uso
del comando INSERT;
- SELECT: consente l'uso
del comando SELECT;
- UPDATE: consente l'uso
del comando UPDATE;
- USAGE: non concede nessun
privilegio, serve unicamente a creare l'utente, come alternativa al comando
CREATE USER
;
- ALL PRIVILEGES: concede tutti i privilegi elencati qua sopra, più altri che per ora non consideriamo.
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
:
- REVOKE
<lista privilegi> ON *.* FROM <utente formale>:
revoca i privilegi indicati all'utente
Infine, per esaminare i privilegi che sono stati concessi a un utente,
si può usare il comando SHOW GRANTS.
- SHOW GRANTS FOR
<utente formale>:
visualizza i diritti che sono stati concessi all'utente. Di solito questo comando è accessibile solo all'utente
root
.
- SHOW GRANTS:
visualizza i diritti concessi all'utente corrente.
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:
-
GRANT
<lista privilegi> ON
<nome schema>.* TO <utente formale>: concede diritti di accesso solo allo schema specificato;
REVOKE <lista privilegi> ON <nome schema>.* FROM <utente formale>
: revoca i diritti di accesso allo schema specificato.
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
-
GRANT
<lista privilegi> ON
<nome schema>.<nome tabella> TO
<utente formale>
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
-
GRANT
<privilegio>(<lista
colonne>) ON <nome schema>.<nome
tabella> TO <utente formale>
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.
Esercizio 1
Supponiamo di avere i seguenti utenti formali:
- root@localhost
- andy@localhost
- ``@localhost
- andy@`%`
- tim@`%.imaginary.com`
- 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:
- l'accesso incondizionato a
tutti gli schemi per l'utente
abramo, quando si connette da localhost, senza bisogno di immettere
nessuna password;
- l'accesso incondizionato a
tutti gli schemi per l'utente
abramo anche quando si connette da qualunque altra macchina
in rete, purché con una password;
- l'acesso in lettura alle
sole tabelle aerei, voli e prenotazioni dello schema airdb
all'utente eva, da qualunque macchina, senza password.