Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 31 di 58
  • livello intermedio
Indice lezioni

Gestire gli utenti

Conoscere i meccanismi alla base della gestione degli utenti che si interfacciano con un database MySQL.
Conoscere i meccanismi alla base della gestione degli utenti che si interfacciano con un database MySQL.
Link copiato negli appunti

Il sistema dei permessi di MySQL è un sistema piuttosto avanzato ma non standard, basato sul contenuto del database mysql che troverete preinstallato sul vostro server dopo l'esecuzione dello script mysql_install_db (se avete seguito il nostro tutorial per l'installazione nella lezione 2 lo script sarà già stato eseguito automaticamente).

Il primo concetto essenziale da tener presente è che l'identificazione dell'utente non avviene semplicemente attraverso il suo nome utente, ma dalla combinazione di questo con la macchina da cui l'utente si collega. Quindi due utenti che si collegano con lo stesso nome ma da due indirizzi diversi, per MySQL sono due utenti diversi.

La prima ad essere consultata quando un utente cerca di connettersi al server è la tabella user. Il server cerca infatti di riconoscere l'utente in base ai valori contenuti nelle colonne 'Host' e 'User' di tale tabella: una volta che l'utente è stato "riconosciuto", gli sarà consentito l'accesso se digiterà la password specificata sulla tabella per quella combinazione di utente e host.

La colonna 'Host' della tabella user può contenere nomi host (ad es. www.mysql.com) oppure indirizzi ip. È possibile utilizzare caratteri "wild card" che rappresentano un carattere (_) o "n" caratteri (%). Quindi ad esempio il valore '%.mysql.com' sarà considerato valido per qualsiasi dominio di terzo livello appartenente a mysql.com.

Nel caso venga utilizzato l'indirizzo ip, sarà possibile anche indicare una maschera per specificare quanti bit devono essere utilizzati per trovare la corrispondenza nell'indirizzo; è da notare però che il numero di bit deve essere necessariamente multiplo di 8 (8, 16, 24, 32). Ad esempio il valore '151.42.62.0/255.255.255.0' significa che la riga è valida per gli IP da 151.42.62.0 a 151.42.62.255.

Nella colonna 'User' sono contenuti evidentemente i nomi degli utenti che si possono collegare. Qui non è consentito l'utilizzo delle wildcard; è consentito però lasciare vuoto il valore: in questo caso tutti gli utenti che si collegheranno dal nome host (o indirizzo IP) corrispondente saranno riconosciuti, qualsiasi nome utilizzino.

In questo caso però saranno considerati da MySQL come 'utenti anonimi': questo significa che il nome utente col quale si sono presentati non sarà valido quando verranno fatti i controlli relativi ai permessi per le varie operazioni.

È evidente che con questo sistema può capitare che un utente, quando cerca di collegarsi, possa essere riconosciuto in base al contenuto di più righe della tabella user: vediamo infatti un esempio:

+-----------+----------+-
| Host      | User     |
+-----------+----------+-
| %         | paolo    |
| %         | luca     |
| localhost | paolo    |
| localhost |          |
+-----------+----------+-

In questa situazione, se l'utente paolo si collega da localhost, sia la prima riga che la terza sono in grado di riconoscerlo, in quanto il valore '%' vale per qualsiasi host. Allo stesso modo, se si presenta luca (sempre da localhost), sarà riconosciuto dalla seconda riga ma anche dalla quarta, in quanto il nome utente vuoto corrisponde a qualsiasi utente.

Tuttavia MySQL determina una sola riga da utilizzare per riconoscere l'utente (e quindi assegnargli poi i relativi privilegi).

Tale riga viene scelta riconoscendo l'utente prima in base al nome host, e fra i nomi host viene privilegiato quello più specifico (quindi senza wildcard); di seguito viene cercato il nome dell'utente, e anche in questo caso il nome esatto ha la precedenza sull'utente anonimo. La prima riga che corrisponde al nome utente sulla base di questi criteri è quella che verrà utilizzata per l'autenticazione. Quindi, nel nostro esempio precedente, quando paolo si collega da localhost verrà riconosciuto dalla terza riga (nome host più specifico), mentre la prima riga sarà usata quando si collega da altri indirizzi.

Per quanto riguarda luca invece la situazione può facilmente trarre in inganno, perchè quando si collega da localhost sarà riconosciuto in base alla quarta riga e non alla seconda: infatti il riconoscimento del nome host ha la precedenza su quello del nome utente, e quindi la prima riga che soddisfa le credenziali di luca@localhost è quella con utente anonimo e localhost: di conseguenza la connessione di luca avverrà come utente anonimo e non con il suo nome utente!

Naturalmente, una volta riconosciuto l'utente, questi dovrà fornire la password corretta, che il server confronterà con quella contenuta nell'omonima colonna della tabella user.

Ci soffermeremo fra poco sul modo in cui la password viene memorizzata; per il momento vogliamo citare il caso in cui la colonna password della tabella sia vuota. Infatti si potrebbe pensare che in questo caso all'utente venga sempre concesso l'accesso, ma non è così: infatti l'assenza di password significa che l'utente non deve digitare una password; in caso contrario l'accesso gli verrà sempre negato!

Possiamo utilizzare due funzioni di MySQL per sapere con quale utente ci siamo presentati, e con quale siamo stati autenticati:

SELECT USER();
-> mario@localhost
SELECT CURRENT_USER();
-> @localhost

Con USER otteniamo il nome utente e host con i quali abbiamo richiesto l'accesso, mentre CURRENT_USER ci indica quale utente ha usato MySQL per autenticarci.
Nell'esempio l'utente si è presentato come 'mario', ma è stato autenticato come utente anonimo.

Una volta ottenuto l'accesso al server, l'utente deve avere i permessi necessari per lavorare sui vari database. La tabella user contiene numerose colonne relative ai permessi ('Select_priv', 'Insert_priv', 'Update_priv' ecc.) ciascuna delle quali può contenere il valore 'Y' o 'N'. La presenza di 'Y' significa che l'utente è autorizzato a compiere quell'operazione: il fatto di avere il permesso sulla tabella user implica che il permesso è valido per tutti i database del server. In sostanza, un utente 'normale' non dovrebbe avere permessi di questo tipo sulla tabella user.

La tabella db contiene invece i permessi relativi ai singoli database. La chiave di questa tabella è formata da User, Host e Db: quindi ogni riga specifica quali permessi ha un determinato utente su un determinato database. Anche in questo caso possiamo trovare le wildcard per host e db; la colonna db può anche essere vuota per indicare tutti i database. La colonna user invece, se vuota, vale solo per gli utenti anonimi.

Un caso particolare è quando il campo Host della tabella db è vuoto: in questo caso infatti entra in gioco la tabella host, che specifica i permessi sui vari database per i diversi host. Qui la chiave Host e Db, e ancora una volta è possibile avere le wildcard su entrambe le colonne. Il valore vuoto corrisponde alla wildcard '%'.

Quando viene usata la tabella host, i permessi per l'utente derivano dall'intersezione dei permessi trovati sulla tabella db con quelli concessi dalla tabella host: questo significa che l'operazione richiesta è consentita solo se il valore relativo è 'Y' su entrambe le tabelle, nelle righe corrispondenti. Vediamo un esempio:

Tabella db

Host Db User Select_priv Insert_priv
192.168.0.% acquisti paolo Y N
vend% paolo Y N

Tabella Host

Host Db Select_priv Insert_priv
192.168.0.11 % N N
192.168.0.% % Y Y

Ovviamente per semplicità abbiamo indicato solo due delle colonne relative ai privilegi.

Supponendo che l'utente paolo sia collegato dalla macchina 192.168.0.11 e che non abbia nessun permesso sulla tabella user, ipotizziamo che voglia lavorare sul database acquisti: in questo caso verrà riconosciuto dalla prima riga della tabella db, che gli consentirà di fare le select ma non le insert.

Quando invece paolo cercherà di lavorare sul database vendite, verrà riconosciuto dalla seconda riga, che però non riporta un indirizzo host, per cui il server andrà a verificare i permessi sulla tabella host. Su questa tabella la riga che gli compete è la prima, in quanto coincide esattamente con l'indirizzo della sua macchina ed è valida per qualsiasi database.

Questa riga però gli nega i permessi sia sulla insert che sulla select, per cui paolo, nonostante la tabella db lo autorizzi alle select, non è in grado di effettuare alcuna operazione sul database vendite. Se si fosse collegato da un'altra macchina con indirizzo 192.168.0.%, sarebbe riuscito almeno a fare le select (non le insert, che gli vengono comunque negate dalla tabella db).

Anche per queste tabelle quindi vale il principio che i valori di host, database e user vengono riconosciuti preferenzialmente in base alla maggiore specificità del contenuto dei campi, quando ci sono più righe che coincidono con la richiesta. Per questo paolo non può lavorare sul database vendite quando si collega da 192.168.0.11: la seconda riga della tabella host gli consentirebbe di farlo, ma la prima ha un indirizzo più specifico e quindi prevale.

Esistono poi le tabelle tables_priv e columns_priv, che contengono privilegi ancora più specifici in quanto relativi ad una singola tabella (nel primo caso) e addirittura ad una singola colonna (nel secondo caso).

Queste tabelle vengono consultate quando i privilegi assegnati dalle tabelle user, db e host non sono sufficienti a garantire il permesso di effettuare l'operazione richiesta. Entrambe contengono nella chiave i campi Host, Db e User, oltre ad una colonna Table_name che identifica la tabella interessata; la tabella columns_priv contiene un'ulteriore colonna Column_name che specifica a quale colonna si riferiscono i permessi. In queste tabelle solo il campo host può contenere wildcard od essere vuoto (in questo caso la riga vale per tutti gli indirizzi), mentre il database deve sempre essere specificato. Inoltre queste tabelle non contengono una colonna per ogni permesso come le precedenti, bensì le colonne Table_priv e Column_priv che contengono tutti i permessi assegnati dalla riga.

Riassumendo: quando il server MySQL deve decidere se un determinato utente ha il permesso di compiere l'operazione che sta richiedendo, il controllo viene fatto per passi successivi: prima si controlla la tabella user, poi la combinazione di db e host, infine tables_priv e columns_priv.

Da notare che ad ogni passaggio i permessi trovati vengono sommati a quelli precedenti: infatti una singola istruzione può richiedere più permessi, e un utente potrebbe averli "sparsi" sui vari livelli. Ovviamente quando tutti i permessi necessari sono stati trovati la ricerca si interrompe e l'istruzione viene eseguita; se invece si arriva in fondo senza averli trovati tutti l'istruzione verrà negata.

Ti consigliamo anche