Weiter Zurück [Inhalt] Online Suche im Handbuch

28.22 GRANT und REVOKE

GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY 'password'] [, user_name [IDENTIFIED BY 'password'] ...] [WITH GRANT OPTION]

REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} FROM user_name [, user_name ...]

GRANT ist erst seit der Version MySQL 3.22.11 implementiert. MySQL hat ein fortschrittliches, aber vom Standard abweichendes Sicherheits/Rechte-System. Was kann das Rechte-System erledigen ?

Die grundlegende Funktion des MySQL-Rechte-Systems ist es, einem Usernamen auf einem Host die SELECT, INSERT, UPDATE und DELETE Rechte bzgl. einer Datenbank zu erteilen. Außerdem besteht die Möglichkeit, einem "anonymous"-User bestimmte Dinge zu erlauben, und eventuell auch Statements, wie z.B. LOAD DATA INFILE auszuführen. In der neuesten Version 3.23 ist auch die Vergabe von Rechten in Abhängigkeit der Hostadresse, der IP-Nummer oder der Netzwerk-Adresse möglich. Host Nummer und Userpasswort sind dabei unabhängig voneinander, was bedeutet, daß es z.B. zwei User mit demselben Usernamen geben darf, vorausgesetzt, daß diese sich stets aus anderen Netzwerken einloggen. Es sollte beachtet werden, daß die Usernamen für die MySQL - Datenbank nichts mit UNIX - Usern oder Microsoft Windows NT/98 Konten zu tun haben.

MySQL versteht die Kombination aus einem Hostname, einer Netzwerkadresse oder einer IP-Nummer in Verbindung mit einem einem User als eindeutige Identität. Aufgrund dieser Identität entscheidet das GRANT System dann welche Rechte ein Client erhält. Die Rechte können jederzeit mit dem Skript mysqlaccess getestet werden.

Alle Rechte werden in drei Tabellen: user, host und db gespeichert:

Tabellen Name           user            db              host 

Scope Felder            Host            Host            Host 
                        User            Db              Db 
                        Password        User            

Privileg Felder         Select_priv     Select_priv     Select_priv 
                        Insert_priv     Insert_priv     Insert_priv 
                        Update_priv     Update_priv     Update_priv 
                        Delete_priv     Delete_priv     Delete_priv 
                        Index_priv      Index_priv      Index_priv 
                        Alter_priv      Alter_priv      Alter_priv 
                        Create_priv     Create_priv     Create_priv 
                        Drop_priv       Drop_priv       Drop_priv 
                        Grant_priv      Grant_priv      Grant_priv 
                        Reload_priv 
                        Shutdown_priv 
                        Process_priv 
                        File_priv  

Jedes in der User-Tabelle erteilte Recht ist für alle Datenbanken gütig, die in der db-Tabelle nicht gefunden werden können. Deshalb sollte man einzelnen Usern (vom Supervisor abgesehen) Rechte nur auf Datenbank-Ebene zuteilen.

Die Host-Tabelle existiert hauptsächlich, um eine Liste "sicherer" Server zu verwalten. Bei TcX enthält die Host-Tabelle eine Liste aller Rechner im lokalen Netzwerk.

Die Rechte des sich gerade anmeldenden Users werden nach dem folgenden Algorithmus festgestellt:

Die Tabelle host wird nach Hosts ohne Wildcard, gefolgt von hosts mit einer Wildcard und Einträgen mit host="" sortiert. Innerhalb jedes hosts, wird nach den gleichen Regeln nach dem user sortiert. Die Tabelle db wird nach den gleichen Regeln sortiert. Bei den nachfolgenden Schritten wird in den so sortierten Datensätzen nachgesehen und der erste passende Datensatz verwendet.

Die Rechte des sich anmeldenden Benutzers werden aus der Tabelle user entnommen. Dabei wird, wie bereits weiter oben beschrieben, der erste passende Datensatz aus der vorher sortierten Tabelle verwendet. Den so erhaltenen Satz an Rechten nennen wir einmal PRIV. Die Rechte des sich anmeldenden Benutzers werden aus der Tabelle db entnommen. Auch hier wird die vorher sortierte Tabelle, und der erste passende Datensatz verwendet.

Falls der in der db-Tabelle gefundene Datensatz den Eintrag host="" enthält, werden die ursprünglichen Rechte PRIV aus der user-Tabelle mit den Host-Rechten aus der host-Tabelle logisch UND verknüpft. D.h. im Klartext: Aus beiden Datensätzen werden alle Rechte entfernt. bei denen nicht in in beiden Fällen ein "Y" eingetragen ist. Falls host

"" ist , so werden die Rechte von PIV nicht verändert. In solchen Fällen muß der host-Eintrag zumindest teilweise mit dem Hostname des verbindenden Hosts übereinstimmen. Deshalb kann angenommen werden, daß die in dieser Zeile festgelegten Rechte dem Profil des sich anmeldenden hosts entsprechen.

Die Rechte des Users aus der Tabelle user werden anschließend mit dem PRIV Rechtesatz logisch ODER verknüpft. (d.h. alle Y-Rechte werden hinzugefügt).

Achtung: Falls in den Rechte-Tabellen etwas verändert wurde, muß das Kommando: mysqladmin reload durchgeführt werden, damit die Änderungen aktiv werden.

Der sich einloggende User erhält dann die PRIV Rechte zugewiesen. Nachfolgend ein Beispiel für das Sortieren und Auffinden der richtigen Datensätze. Angenommen, die user-Tabelle sieht folgendermaßen aus:

+-----------+---------+-
| Host      | User    | ...
+-----------+---------+-
| %         | root    | ...
| %         | jeffrey | ...
| localhost | root    | ...
| localhost |         | ...
+-----------+---------+-

Die Suchreihefolge sieht dann (nach erfolgter Sortierung) folgendermaßen aus:

 
localhost/root 
localhost/any 
any/jeffrey 
any/root

Jeffrey der sich via localhost anmeldet (also von der Arbeitsstation, auf der mysqld läuft), und wird deshalb mit den Rechten localhost/any und nicht mit den Rechten any/jeffrey ausgestattet, da immer der erste passende Eintrag verwendet wird !

Falls Sie also Probleme mit den Zugriffsrechten haben, lassen Sie sich den Inhalt der Tabelle user ausgeben, sortieren ihn von Hand und stellen den ersten passenden Datensatz fest.

Es folgt nun ein Beispiel um den user "custom" hinzuzufügen der sich von den Hosts "localhost", "server.domain" und "whitehouse.gov" anmelden darf. Er möchte das Password "stupid" haben. Die Datenbank "bankaccount" möchte er nur via "localhost", die Datenbank "customer" von allen drei hosts aus erreichen können:

 
shell> mysql mysql.
mysql> insert into user (host,user,password)
       values('localhost','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('server.domain','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('whitehouse.gov','custom',password('stupid'));

mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('%','customers','custom','Y','Y','Y','Y','Y','Y');

Sie können selbstverständlich xmysqladmin, mysql_webadmin, mysqladmin und xmysql oder PHPmyAdmin verwenden, um in den Rechte-Tabellen Datensätze einzufügen oder abzuändern. Sie finden diese Utilities u.a. im Support Verzeichnis unter http://www.rent-a-database.de/support/.

Die Rechtevergabe-Tabellen

Name                    tables_priv     columns_priv 
Scope Felder            Host            Host 
                        Db              Db 
                        User            User 
                        Table_name      Table_name 
                                        Column_name 
Privileg Rechte         Table_priv      Column_priv 
                        Column_priv 
Andere Rechte           Timestamp       Timestamp 
                        Grantor
Der "SCOPE" ist immer der Wirkungsbereich, daher werden in der Rechtevergabe-Tabelle genau festgelegt, auf welche Felder ein User zugreifen darf.

Die für Tabellen relevanten Rechte sind select, insert, update und delete. Die Rechte für Tabellen und Datenbanken sind create und drop. "create" und "drop"-Recht gelten für beides - Tabellen und Datenbanken.

Falls ein User nämlich alle Tabellen einer Datenbank löschen darf, kann er auch gleich das Recht erhalten, die ganze Datenbank zu löschen.

Die Zeile Andere Rechte vergeben die Berechtigung um Dateien zu benutzen (für LOAD DATA INFILE und SELECT INTO OUTFILE) und Administrations-Kommandos wie shutdown, reload, refresh und process auszuführen.

Das Rechtevergabesystem basiert auf 3 Tabellen:

user Tabelle

Sie beinhaltet alle host+user Kombinationen, die das Recht haben, sich an dem MySQL - Server anzumelden, und enthält gegebenenfalls noch deren Paßwort. Die user-Tabelle hat die folgenden Datenfelder:

Datenfeld       Datentyp        Schlüssel       Standardwert
Host            char(60)        PRI             ""  
User            char(16)        PRI             ""  
Password        char(16)        -               ""  
        
Select_priv     enum('N','Y')   -               N  
Insert_priv     enum('N','Y')   -               N  
Update_priv     enum('N','Y')   -               N  
Delete_priv     enum('N','Y')   -               N  
Create_priv     enum('N','Y')   -               N  
Drop_priv       enum('N','Y')   -               N  
Reload_priv     enum('N','Y')   -               N  
Shutdown_priv   enum('N','Y')   -               N  
Process_priv    enum('N','Y')   -               N  
File_priv       enum('N','Y')   -               N  

Die db-Tabelle legt fest, welche Datenbanken host+user benutzen kann, und was er mit den Tabellen in jeder Datenbank machen darf. Die db-Tabelle hat die folgenden Datenfelder:

Datenfeld       Typ             Schlüssel       Standardwert  
Host            char(60)        PRI             ""  
Db              char(64)        PRI             ""  
User            char(16)        PRI             ""  
Select_priv     enum('N','Y')   -               N  
Insert_priv     enum('N','Y')   -               N  
Update_priv     enum('N','Y')   -               N  
Delete_priv     enum('N','Y')   -               N  
Create_priv     enum('N','Y')   -               N  
Drop_priv       enum('N','Y')   -               N  

Die host-Tabelle wird nur in großen Netzwerken benutzt, um bei leeren host-Einträgen in der db-Tabelle nachzuschauen. D.h. falls sie einem User gestatten wollen, Datenbanken von jedem Host in ihrem Netzwerk zu benutzen, sollten Sie "" als Hostname in der db-Tabelle eintragen. In diesem Fall sollte die host-Tabelle für jeden Host ihres Netzwerks einen Eintrag aufweisen. Die host-Tabelle hat die folgenden Datenfelder:

Datenfeld       Typ             Schlüssel       Standardwert  
Host            char(60)        PRI             ""  
Db              char(64)        PRI             ""  
Select_priv     enum('N','Y')   -               N  
Insert_priv     enum('N','Y')   -               N  
Update_priv     enum('N','Y')   -               N  
Delete_priv     enum('N','Y')   -               N  
Create_priv     enum('N','Y')   -               N  
Drop_priv       enum('N','Y')   -               N  

Die host und db Spalten können eine Zeichenkette mit der SQL-Wildcard % und _ enthalten. Wenn irgendeine dieser Spalten leer gelassen wird, so ist das gleichbedeutend mit dem Eintrag '%'.

Ein host kann localhost, ein Hostname, eine IP-Nummer, eine Netzwerknummer oder eine Zeichenkette mit Wildcards sein. Ein leerer Host in der db-Tabelle ist gleichbedeutend mit alle Hosts in der host-Tabelle. Ein leerer Host in der host- oder user-Tabelle besagt, daß alle Hosts eine TCP-Verbindung zu ihrem MySQL-Server herstellen können.

db ist der Name einer Datenbank oder ein SQL regulärer Ausdurck (regexp). Eine leere user Spalte bedeutet, daß jeder Username gültig ist. Wildcards im Feld Username sind nicht zulässig.

Ein user, auf den nichts in der user-Tabelle paßt, wird wie ein no-name user oder anonymous User behandelt.

Die Rechte der user-Tabelle werden mit der db-Tabelle über ODER verknüpft. Das bedeutet, daß der Superuser einfach nur einen Eintrag in der user-Tabelle haben muß, in dem alle Rechte-Flags auf Y gesetzt sind.

Sie können einen Eintrag wie 123.444.444.% in der host-Tabelle verwenden um jedem User eines IP-Klasse-C-Netzes Zugriff zu ermöglichen.

Um zu verhindern, daß jemand durch Benennung seines Hosts als 123.444.444.somewhere.com in das System eindringt, verbietet MySQL alle Hostnamen, die mit Zahlen oder einem Punkt beginnen.

Falls also der Rechner 1.2.foo.com oder ähnlich heißt, wird er durch Namensüberprüfung keinen Zugang erhalten.

Verwenden sie in diesem Fall seine IP-Nummer in der Rechtevergabe.

Hinzufügen neuer User-Rechte zu MySQL

Dies setzt voraus, daß der gegenwärtige User INSERT-Rechte für die mysql Datenbank und auch die RELOAD-Rechte besitzt. Der DB-Server (mysqld) muß gestartet sein. Falls er noch nicht gestartet ist, starten sie ihn mit dem Befehl safe_mysqld --log &:

 
> mysql mysql
  insert into user values
('%','monty',password('something'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
;
  insert into user (host,user,password) values('localhost','dummy',") ;
  insert into user values
('%','admin',",'N','N','N','N','N','N','Y','N','Y','Y') ;
  quit
> mysqladmin reload

Dies erzeugt drei neue User:

Monty - Voller superuser, muß aber ständig ein Passwort bei der Arbeit mit MySQL benutzen.

admin - Braucht kein Passwort, kann aber nur mysqladmin reload, mysqladmin refresh und mysqladmin processlist ausführen. Es können ihm individuelle Datenbank-Rechte durch die db-Tabelle eingeräumt werden.

dummy - Ihm müssen individuelle Datenbank-Rechte durch die db-Tabelle eingerichtet werden.

Default Rechte

Die default Rechte (wurden durch "Scripts/mysql_install_db" gesetzt) erlauben dem User root alles. Jeder User kann mit jeder Datenbank, deren Name 'test' ist oder mit 'test_' beginnt, alles tun. Ein normaler User kann mysqladmin shutdown oder mysqladmin processlist nicht benutzen. Sehen Sie sich das Skript (Scripts/mysql_install_db') als Beispiel an, und sehen Sie, wie man weitere User hinzufügt. Die Rechte-Tabellen werden mit mysqladmin reload eingelesen. MySQL benutzt also einfache Tabellenstrukturen, um die Rechte zu vergeben, eine naheliegende Variante.

Ein Beispiel für die Rechte-Vergabe

Ein üblicher Fehler ist es, zu vergessen, daß Paßworte verschlüsselt abgespeichert werden. Dies führt zum Beispiel zu folgendem Problem:

INSERT INTO user VALUES
('%','jeffrey','bLa81m0','Y','Y','Y','N','N','N','N','N', 'N','N'); 

Danach muß mysqladmin reload ausgeführt werden, um die Änderung zu aktivieren. Es folgt ein Versuch sich beim Server anzumelden:

$ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test
Access denied

Versuchen sie stattdessen folgendes:

INSERT INTO user VALUES
('%','jeffrey',password('bLa81m0'),'Y','Y','Y','N','N','N','N','N','N','N');

Nun sollte es wie gewünscht funktionieren.

Lösungen bei Access denied - Fehlern

Haben sie die MySQL-Rechte-Tabellen mit dem Skript mysql_install_db installiert? Testen sie dies, indem Sie den Befehl mysql -u root test ausführen. Hier dürfte kein Fehler erscheinen.

Bei einer Erstinstallation sollten sie 'mysql -u root mysql' benutzen, um Zugang zu den Rechte-Tabellen zu erhalten.

Für Testzwecke sollten sie den mysqld - Dämon mit der Option --without-grant-tables starten. Nun können sie die MySQL-Rechte-Tabellen ändern und mit Hilfe des Skripts mysqlaccess überprüfen, ob ihre Einstellungen funktionieren. mysqladmin reload sagt dann dem mysqld-Dämon, daß er die neuen Rechte-Tabellen benutzen soll.

Selbst wenn sie mit Perl, Python, oder ODBC Zugriffsprobleme haben, sollten sie immer mit mysql -u user database oder mysql -u user -password database ihre Probleme mit Rechten testen.

Man kann auch die Option --password=your_password beim Start von MySQLD verwenden, um das Passwort zu übergeben.

Falls sie bei einer Anmeldung mit mysql -u user database die Fehlermeldung 'Access denied' erhalten, dann haben sie ein Problem mit der 'user'-Tabelle.

Überprüfen sie dies durch mysql -u root mysql und select * from user. Sie sollten einen Eintrag mit 'hostname' und 'user' erhalten der auf ihren Rechnername und ihren Usernamen paßt.

Die Fehlermeldung "Access denied" sagt ihnen, wer sie sind, von welchem Host aus sie sich anmelden und ob sie ein Passwort benutzt haben oder nicht. Sie sollten normalerweise einen Eintrag in der user-Tabelle haben, der genau wie in der Fehlermeldung angegeben, auf ihren Rechner- und Username paßt.

Falls sie die Fehlermeldung 'Host ... is not allowed to connect to this MySQL server' erhalten, wenn sie versuchen sich an einem MySQL-Server auf einer anderen Maschine anmelden, dann haben sie keinen Datensatz in der User-Tabelle, die auf die Remote-Maschine paßt. Sie können dies beheben, indem sie das Kommandozeilen-Tool 'mysql' benutzen, und für die Maschinen/User-Kombination mit der sie sich anmelden wollen, einen Datensatz zur user-Tabelle hinzufügen. Falls sie nicht MySQL 3.22 installiert haben, und nicht genau wissen, mit welcher IP/Hostname-Kombination sie sich anzumelden versuchen, dann sollten sie einen Eintrag mit '%' als Host in der user-Tabelle einfügen und mysqld mit der Option --log neu starten. Nach einem Anmeldeversuch finden sie dann Informationen im MySQL Log, wie sie sich tatsächlich angemeldet haben.

Falls mysql -u root test funktioniert, aber mysql -h your_hostname -u root test die Fehlermeldung 'Access denied' erzeugt, dann haben sie nicht den richtigen Namen für ihren Rechner in der user-Tabelle.

Falls sie z.B. einen Eintrag mit host 'tcx' in der 'user'-Tabelle haben, ihr DNS aber dem MySQL-Server sagt, daß ihr Hostname 'tcx.subnet.se' ist, dann wird dieser Eintrag nicht funktionieren. Probieren sie es mit einem Datensatz, der die IP-Nummer ihres Hosts in der 'user'-Tabelle enthält.

Sie können natürlich auch einen Host mit einer Wildcard (z.B. 'tcx%') zur 'user'-Tabelle hinzufügen. Beachten sie aber bitte, daß Hostnamen die mit '%' aufhören, eine Sicherheitslücke darstellen !

Falls es ihnen nicht gelingt, festzustellen, warum sie die Fehlermeldung 'Access denied' erhalten, dann entfernen sie alle Einträge, die Wildcards (Einträge die % oder _ enthalten) im Hostnamen enthalten, aus der user-Tabelle ! Ein häufiger Fehler ist es, daß man einen neuen User hinzufügt der host='%' und user='some user' hat und glaubt, daß man sich auch vom demselben Rechner, also localhost anmelden darf.

Der Grund, warum das nicht funktioniert, ist, daß der Eintrag mit host='localhost' und user="" gegenüber dem neuen Eintrag bevorzugt wird, wenn man sich von 'localhost' anmeldet. Die richtige Vorgehensweise ist es dann, eine zweiten Datensatz mit host='localhost' und user='some_user' vorzunehmen, oder den Eintrag mit user="" zu entfernen.

Bei der Benutztung der MIT-pthreads, wird localhost nie benutzt. Alle Verbindungen zum mysql-Daemon laufen über TCP/IP und sie müssen ihren richtigen Hostnamen in 'user' eingetragen haben, selbst wenn sie den Client auf dem gleichen Rechner benutzen, auf dem auch der Server läuft.

Falls sie die Fehlermeldung 'Access to database denied' erhalten, dann haben sie ein Problem mit der db-Tabelle. Falls der benutzte Eintrag in der db-Tabelle einen leeren Hostnamen hat, dann überprüfen sie auch den zughörigen Eintrag in der 'host'-Tabelle.

Falls mysql -u user database auf dem Server-Rechner funktionert, mysql -u host -u user database aber nicht auf einem anderen Client-Host funktioniert, dann haben sie diesen Client-Rechner nicht in der 'user'- oder 'db'-Tabelle eingetragen.

Falls das Paßwort abgelehnt wird, dann denken sie daran, daß Paßworte mit der PASSWORD-Funktion eingefügt werden müssen. Schauen sie im Abschnitt Ein Beispiel für die Rechte-Vergabe nach.

Falls mysql -u user test funktioniert, mysql -u user other_database hingegen nicht, dann ist die other_database nicht in der 'db'-Tabelle aufgeführt.

Falls Sie die Fehlermeldung 'Access to database denied' bei der Benutzung von SELECT ... INTO OUTFILE oder LOAD DATA INFILE Befehlen erhalten, dann ist wahrscheinlich das File_priv - Recht für Sie selber nicht in der 'user'-Tabelle aufgeführt.

Falls alles fehlschlägt, dann starten sie den mysqld Daemon mit: --debug=d,general,query. Dadurch werden Informationen über den Host und User ausgegeben, der sich anzumelden versucht, und außerdem erhalten sie Informationen über jedes Kommando.

Lesen Sie hierzu auch das Kapitel Debuggen von MySQL

Falls sie irgendwelche weiteren Probleme mit den MySQL-Rechte-Tabellen, und das Gefühl haben, diese auf der Mailing-Liste zu veröffentlichen, dann fügen sie immer einen Dump der MySQL-Rechte-Tabellen hinzu. Sie können diesen Tabellendump mit dem Befehl mysqldump mysql durchführen. Wie immer, mailen sie ihr Problem mit dem mysqlbug-Skript.

Falls sie die Fehlermeldung Can't connect to local mySQL server oder Can't connect to MySQL server on some_hostname erhalten, so bedeutet dies, daß der mysqld-Daemon nicht gestartet ist, oder daß sie versuchen, sich an dem falschen Port anzumelden. Stellen sie sicher, daß der MYSQLD auf dem richtigen Port läuft:

telnet hostname 3306
Alternativ sollten Sie bei neueren Versionen den Port 3333 ausprobieren.

Unbedingt sollte Sie sich das Kapitel Wie sichere ich MySQL gegen Hacker ab ? durchlesen.


Weiter Zurück [Inhalt] Online Suche im Handbuch