Laboratorio
di Sistemi Informativi
Gestione Utenti
Utenti di un DBMS
Una installazione di MySQL a regime può contenere vari
database
e varie tabelle in ogni database. In generale, nasce il problema che
non
tutti gli utenti di MySQL possono 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 dei database, 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.
Mentre siamo in argomento, esaminiamo altre tipice figure professionali
che sono correlate al mondo dei DBMS:
- progettista di un database:
è colui che si occupa dello
sviluppo di un database, ovvero della creazione delle tabelle,
individuazione degli indici e dei vincoli di integrità. Egli
parte da una raccolta di requisiti e arriva allo sviluppo della
struttura del database più adatta a soddisfarli;
- sviluppatore
dell'applicazione:
si occupa di scrivere i programmi
che poi gli utenti finali utilizzeranno per interagire con il database.
Non si può pensare di insegnare SQL a tutto il personale di
una
azienda, per cui occorre sviluppare delle applicazioni, con le quali il
personale può accedere alle applicazioni in maniera semplice;
- utenti delle applicazioni:
sfruttano le applicazioni per ricavare
informazioni dal database e aggiungere nuove informazioni, ognuno
secondo i propri specifici compiti;
- gruppo di testing:
di
solito sviluppatori o utenti avanzati che
controllano la validità delle applicazioni e del database
prima
che questi vengano utilizzati su larga scala nell'impresa.
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:
SELECT
user();
+-----------------+
|
user()
|
+-----------------+
|
amato@localhost |
+-----------------+
Abbiamo visto che possiamo specificare il nome utente con cui ci
vogliamo collegare
facendo partire il client mysql
con l'opzione -u
mysql
-u pippo
Ricordiamo anche che è possibile usare l'opzione -h per
indicare
il server a cui collegarsi. Ad esempio:
mysql
-h 172.272.11.34 -u pippo
si collega al computer il cui numero IP è 172.272.11.34 con
il
nome utente pippo.
N.B.
Le opzione -u e -h possono
essere usate anche con il programma mysqldump, che abbiamo esaminato
nelle lezioni precedenti.
GRANT e REVOKE
Il comando principale che SQL mette a disposizione per concedere
diritti e creare nuovi utenti
è GRANT. Con GRANT è possibile concedere diritti
ad un
utente su tutti i dati di un server, su uno specifico database, su un
tabella o su specifiche colonne di una tabella.
Diritti a livello di server
La sua sintassi è la seguente
- GRANT
<lista
privilegi> ON
*.* TO <utente>:
concedere dei diritti di accesso all'utente
Alcuni dei privilegi che è possibile concedere sono:
- ALTER:
consente l'uso del
comando ALTER TABLE
(ma
non è possible creare o eliminare indici);
- CREATE:
consente l'uso di CREATE TABLE
e CREATE
DATABASE;
- DELETE:
consente l'uso
del comando DELETE;
- DROP:
consente l'uso di DROP TABLE
e DROP
DATABASE;
- INSERT:
consente l'uso
del comando INSERT;
- SELECT:
consente l'uso
del comando SELECT;
- UPDATE:
consente l'uso
del comando UPDATE;
- INDEX:
consente la
creazione ed eliminazione di indici con il comando ALTER TABLE.
Un po' particolari sono i seguenti:
- ALL PRIVILEGES:
concede
tutti i privilegi possibili
- USAGE:
non concede nessun
privilegio (ma crea l'utente... vedremo dopo che conseguenze può
avere)
Un privilegio concesso con questa sintassi riguarda tutti i database
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 database 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 comandoi GRANT
:
- REVOKE
<lista privilegi> ON
*.* FROM <utente>:
revoca i privilegi indicati all'utente
Infine, per esaminare i privilegi che
sono stati concessi a un utente,
su può usare il comando SHOW GRANTS.
- SHOW GRANTS FOR
<utente>:
visualizza i diritti che sono stati concessi all'utente <user>.
- SHOW GRANTS:
visualizza i diritti concessi all'utente corrente.
In pratica, vengono visualizzati i comandi GRANT
che sarebbero necessari
per concedere all'utente, su un'altra installazione di MySQL, gli
stessi diritti che ha attualmente.
Autenticazione tramite password
Abbiamo visto che con il comando GRANT
SELECT ON *.* TO pippo@localhost
l'utente pippo ha accesso in
lettura a tutti i dati memorizzati nel
server. Tuttavia, chiunque abbia accesso fisico alla macchina
server può spacciarsi per pippo,
poichè non viene effettuato nessun controllo sulla persona
fisica che esegue il comando mysql
-u pippo. Se poi avessimo
concesso l'accesso all'utente pippo
anche da altre macchine con GRANT
SELECT ON *.* TO pippo@xyz.unich.it,
allora chiunque
avesse accesso alla
macchina xyz.unich.it
potrebbe collegarsi al nostro server MySQL con nome utente pippo
e leggere il contenuto di tutti i database.
Servirebbe
poter immettere una password da richiedere al momento in cui qualcuno
si vuole connettere con il nome utente pippo. Questo si
può fare con il comando GRANT,
come segue:
GRANT
SELECT ON *.* TO
pippo@localhost IDENTIFIED
BY
'miapassword'
Da quel momento in poi, per
collegarsi col nome di utente
"pippo" dalla macchina locale, occorrerà fornire la password
di
accesso. A tale scopo,
si può invocare mysql in questo modo:
mysql
-u <username> -p
che chiede la password in maniera interattiva o con
mysql
-u <username>
-p<passwd>
che consente di specificarla dalla linea di comando.
ATTENZIONE!
La
prima cosa che un DBA deve fare quando installa MySQL (o un qualunque
altro database) su una macchina condivisa tra più utenti,
è assicurarsi che l'acceso al database con
l'account root sia protetto da password! Questo è
possibile, ad esempio, con il comando:
GRANT USAGE ON *.* TO root@localhost IDENTIFIED BY
'<password>';
Notare l'uso di GRANT USAGE
per settare una password senza alterare i privilegi di un utente.
Questo non è stato fatto sulle macchine in laboratorio visto
che
MySQL
è installato solo a scopo didattico.
Diritti a livello di database
Si possono anche concedere diritti che non valgolo su tutti i dati di
un server,ma
selettivamente a livello di un singolo database. La sintassi
è
simile al caso precedente:
GRANT
<lista privilegi> ON
<nome database>.* TO <utente formale>
Analogamente per REVOKE.
Ad esempio supponiamo di concedere all'utente pippo la
possibilità di agire indiscriminatamente sul database airdb:
GRANT
ALL PRIVILEGES ON airdb.*
TO pippo@localhost
In questo modo pippo può accedere in lettura a tutti i
database,
ed ha pieno accesso in lettura e scrittura su airdb. Notare che i
diritti a livello database 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 conserve tutti i suoi diritti su airdb. Perde
però tutti i diritti di lettura non esplicitamente concessi
a livello di singolo database.
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
il database airdb, ma potrà a sua volta concedere diritti su
questo database 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 database>.<nome tabella> TO
<utente formale>
I privilegi sono gli stessi possibili nel caso di
diritti a livello di server o di database. L'unica differenza
è
che i
diritti CREATE
o DROP
a livello database consentono
di eseguire le
istruzioni CREATE DATABASE
e DROP
DATABASE, 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 database>.<nome
tabella> TO <lista
utenti>
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 al database airdb
e dare il comando
SELECT
id FROM aeroporti
ma non il comando
SELECT
* FROM aeroporti
Caratteri jolly e utenti formali
Finora abbiamo visto come si concedono dei diritti a degli utenti,
specificando sia il nome utente che l'hostname. Ma come si fa, ad
esempio, a concedere ad un utente il diritto di collegarsi al
database ovunque si trovi nel mondo? Si può
usare
il carattere jolly %
come hostname (che però va
racchiuso
tra accenti).
Il % sta a indicare una stringa generica. 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.
Per i nomi utenti 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.
Con il comando GRANT SELECT ON
*.* TO pippo@`%` l'utente
pippo può collegasi da
qualunque macchina al server e avere accesso in lettura a tutti i
database. Invece con GRANT
SELECT ON *.* TO ``@localhost
l'accesso in lettura viene
garantito a tutti gli utenti locali che non hanno dei diritti
più specifici.
Quando si usano comandi GRANT con caratteri jolly, spesso il sistema si
comporta in modo inaspettato. Ad esempio, se diamo i comandi
GRANT
ALL PRIVILEGES ON airdb.*
TO a@`%.unich.it`
GRANT
USAGE ON *.* TO
a@`xyz.unich.it`
e dalla macchina xyz.unich.it
ci colleghiamo con nome utente a,
avremo o no l'accesso al database airdb?
La risposta è no, non avremo accesso al database airdb. Se
invece ci colleghiamo, sempre con nome utente a
ma dalla macchina uvw.unich.it,
allora avremo
l'accesso desiderato.
Tentiamo di spiegare perchè. Indichiamo come utente reale la combinazione username@host
effettiva di chi si connette a MySQL (ricavabile dalla funzione
intrinseca USER
) e utente
formale la combinazione username@host
indicata nei
comandi GRANT e REVOKE (e che, a differenza dell'utente reale,
può contenere caratteri jolly). Al momento della connessione,
MySQL deve
scegliere,
a partire dall'utente reale che si sta connettendo, a quale utente
formale farlo corrispondere, e quindi quale diritti concedergli. MySQL
sceglie sempre, tra tutti gli utente formali disponibili che possono
corrispondere a quello reale (in slang si dice che "matchano"), quello
che ha il nome host più specifico. Per cui, siccome l'utente
a@xyz.unich.it
potrebbe
corrispondere sia ad a@`%.unich.it`
che ad a@`xyz.unich.it`,
viene
scelto ques'ultimo, perchè ha il nome host più
specifico. Quando invece ci colleghiamo come a@uvw.unich.it,
soltanto a@`%.unich.it`
può
essere utilizzato, e quindi l'utente avrà i privilegi
desiderati.
Per scoprire chi è l'utente formale attuale si può usare
la funzione intrinseca
- CURRENT_USER():
determina l'utente formale corrente.
Se ci
colleghiamo da xyz.unich.it
il risultato sarà a@xyz.unich.it
ma se ci colleghiamo da uvw.unich.it
il risultato sarà a`@%.unich.it`. La
cosa più strana è forse che, se
aggiungiamo il comando
GRANT
USAGE ON *.* to
``@`uvw.unich.it`
allora neanche l'utente a
collegato da uvw.unich.it
avrà il diritto di accesso al database airdb.
Questo perchè il
nome utente vuoto (quello dell'utente anonimo),
può
"matchare" con qualunque altro nome utente. Pertanto, sia a@`%.unich.it` che
``@`uvw.unich.it`
sono utenti
formali che "matchano" con a@uvw.unich.it,
ma il secondo ha il nome di host più specifico. Tutti gli
utenti
che si collegano da uvw.unich.it
hanno, a questo punto, solo i privilegi concessi da
quest'ultimo
comando GRANT.
Per ripristinare la situazione che si aveva prima del comando GRANT
USAGE ON *.* to
``@`uvw.unich.it` , non si può usare il comando REVOKE
,
perchè non ha alcun effetto. Occorre eliminare del tutto
l'utente ``@`uvw.unich.it`
con il comando DROP USER
.
- DROP USER
<utente>: rimuove
l'utente indicato.
Funziona solo se l'utente non ha nessun privilegio corrente, tranne il
privilegio USAGE.
Ad esempio drop DROP USER ``@`uvw.unich.it`
l'utente a@uvw.unich.it potrà di nuovo accedere al database.
Esercizio 1
Scrivere i comandi GRANT necessari per concedere i seguenti diritti di
accesso:
- l'accesso incondizionato a
tutti i database per l'utente
abramo, quando si connette da localhost, senza bisogno di immettere
nessuna password;
- l'accesso incondizionato a
tutti i database 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
all'utente eva, da qualunque macchina, senza password.
Controllare di aver dato i comandi giusti invitando un vicino a
collegarsi al proprio server. A tal scopo, ricordatevi che si
può usare il comando /sbin/ifconfig
per determinare l'indirizzo IP di una macchina.
Esercizio 2
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