MySQL erlaubt eine sehr fein strukturierte Rechtevergabe für Benutzer. Somit ist es möglich, einem Benutzer nur die Rechte für ein einzelnes Datenbankschema, eine einzelne Tabelle, einer Tabellenspalte oder einer Routine einzuräumen.
Diese Rechte werden mit dem GRANT-Befehl erteilt und werden im Schema “mysql” gespeichert.
Die dazugehörigen Berechtigungstabellen lauten:
columns_priv | (Tabellenspalten) |
tables_priv | (Tabellen) |
procs_priv | (Routinen) |
db | (Datenbankschemen) |
Diese Rechte bleiben auch dann erhalten, wenn die dazugehörigen Datenbankobjekte gelöscht werden. Mit der Zeit können sich so eine Menge Berechtigungen ansammeln, die nicht mehr benötigt werden, da die Datenbankobjekte nicht mehr existieren oder zum Beispiel umbenannt wurden. Dies ist insbesondere auf Datenbankservern der Fall, die von verschiedenen Programmierern während des Softwareentwickungsprozesses genutzt werden.
Um die Übersicht nicht zu verlieren, muss von Zeit zu Zeit in der Berechtigungsstruktur aufgeräumt werden. Um nicht jedes berechtigte Objekt von Hand zu überprüfen, empfiehlt es sich, die nicht mehr vorhandenen Objekte mit Hilfe des “information_schema” abzugleichen.
Beispiel:
Zeige alle Benutzerprivilegien an (und das dazugehörige REVOKE-Statement), die sich auf eine Tabelle beziehen, die nicht mehr existiert:
SELECT REPLACE(tp.db,"\\","") AS database_schema , tp.table_name , tp.user , tp.table_priv , CONCAT("REVOKE ",tp.table_priv," ON ", REPLACE(tp.db,"\\",""),".",tp.table_name," FROM `", tp.user,"`@`",tp.host,"`;") AS revoke_statement FROM mysql.tables_priv tp LEFT JOIN information_schema.TABLES t ON t.TABLE_NAME = tp.Table_name AND t.TABLE_SCHEMA = REPLACE(tp.Db,"\\","") WHERE t.table_name IS NULL\G
Ergebnis:
*************************** 1. row *************************** database_schema: test table_name: stocks user: developer table_priv: Select revoke_statement: REVOKE Select ON test.stocks FROM `developer`@`%`; 1 row in set (0.00 sec)
In diesem Fall hat der Benutzer Developer das SELECT-Recht auf die Tabelle “stocks” aus dem Datenbank-Schema “test”, die aber nicht mehr existiert. Das Select-Statement erzeugt weiterhin gleich die passenden Revoke-Befehle. Damit lassen sich die überflüssigen Rechte komfortabel entfernen.
Anbei findet ihr noch die restlichen Statements:
Tabellenspalte
SELECT REPLACE(cp.db,"\\","") AS database_schema , cp.table_name , cp.column_name , cp.user , cp.column_priv , CONCAT("REVOKE ",cp.column_priv,"(",cp.column_name,") ON ", REPLACE(cp.db,"\\",""),".",cp.table_name," FROM `", cp.user,"`@`",cp.host,"`;") AS revoke_statement FROM mysql.columns_priv cp LEFT JOIN information_schema.columns c ON cp.TABLE_NAME = c.Table_name AND REPLACE(cp.Db,"\\","") = c.table_schema and cp.Column_name=c.column_name WHERE c.column_name IS NULL\G
Datenbankschemen
SELECT REPLACE(db.db,"\\","") AS database_schema , db.user , CONCAT("REVOKE ALL ON ",REPLACE(db.db,"\\",""),".* FROM `", db.user,"`@`",db.host,"`;") AS revoke_statement FROM mysql.db db LEFT JOIN information_schema.schemata s ON REPLACE(db.Db,"\\","") = s.schema_name WHERE s.schema_name IS NULL\G
Routinen
Beim Löschen der Routinen werden auch die entsprechenden Privilegien gelöscht.
!!! Achtung: Nicht immer sind die Privilegien ohne dazugehörige Objekte überflüssig. Oft werden die Objekte auch nur gelöscht, um sie anschließend mit mysqldump wieder herzustellen. Also lieber einmal mehr prüfen, bevor man die Rechte entfernt. !!!