Online Suche im Handbuch |
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/.
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.
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.
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 ü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.
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.
Online Suche im Handbuch |