Wenn Sie eine Verbindung mit einem MySQL-Server herzustellen versuchen, kann dieser die Verbindungsanfrage basierend auf Ihrer Identität und darauf, ob Sie diese Identität durch Übermittlung nachgewiesen haben, annehmen oder abweisen. Im Falle der Abweisung verweigert Ihnen der Server jedweden Zugriff. Andernfalls akzeptiert der Server die Verbindung. Er schaltet dann auf Stufe 2 um und erwartet Ihre Anforderungen.
Ihre Identität basiert auf zwei Datenelementen:
dem Clienthost, von dem aus Sie die Verbindung herstellen
Ihrem MySQL-Benutzernamen
Die Identitätsprüfung wird mithilfe der drei
Gültigkeitsbereichsspalten (Host
,
User
und Password
) der
Tabelle user
durchgeführt. Der Server
akzeptiert die Verbindung nur dann, wenn die Werte in den
Spalten Host
und User
eines Datensatzes in der Tabelle user
mit dem
vom Client übermittelten Host- und Benutzernamen
übereinstimmen und der Client nachfolgend das Passwort für
diesen Datensatz sendet.
Die Host
-Werte in der Tabelle
user
können wie folgt angegeben werden:
Ein Host
-Wert kann ein Hostname oder eine
IP-Adresse oder aber 'localhost'
(zur
Bezeichnung des lokalen Hosts) sein.
Sie können die Jokerzeichen
‘%
’ und
‘_
’ in
Host
-Spaltenwerten benutzen. Sie haben
die gleiche Bedeutung wie bei Mustervergleichsoperationen,
die mit dem Operator LIKE
durchgeführt
werden. So stimmt etwa der Host
-Wert
'%'
mit allen Hostnamen überein,
während der Wert '%.mysql.com'
eine
Übereinstimmung mit allen Hosts der Domäne
mysql.com
bedingt.
Bei Host
-Werten, die als IP-Nummern
angegeben werden, können Sie ein Netzmaske angeben, die die
Anzahl der Bits definiert, die für die Netzwerknummer
verwendet werden. Zum Beispiel:
GRANT ALL PRIVILEGES ON db.* TO david@'192.58.197.0/255.255.255.0';
Hiermit kann david
von jedem Clienthost
aus eine Verbindung herstellen, der die IP-Nummer
client_ip
hat, sofern für diese die
folgende Bedingung wahr ist:
client_ip & netmask = host_ip
Das bedeutet für die gerade gezeigte
GRANT
-Anweisung:
client_ip & 255.255.255.0 = 192.58.197.0
IP-Nummern, die dieser Bedingung genügen und eine
Verbindung mit dem MySQL-Server herstellen können, sind
mithin diejenigen im Bereich zwischen
192.58.197.0
und
192.58.197.255
.
Hinweis: Die Netzmaske kann nur verwendet werden, um den Server anzuweisen, die ersten acht, 16, 24 oder alle 32 Bits der Adresse zu verwenden. Ein paar Beispiele:
192.0.0.0/255.0.0.0
: Alle Hosts im
Klasse-A-Netzwerk 192.
192.168.0.0/255.255.0.0
: Alle Hosts
im Klasse-B-Netzwerk 192.168.
192.168.1.0/255.255.255.0
: Alle Hosts
im Klasse-C-Netzwerk 192.168.1.
192.168.1.1
: Nur die angegebene
IP-Adresse.
Die folgende Netzmaske (28 Bits) wird hingegen nicht funktionieren:
192.168.0.1/255.255.255.240
Ein leerer Host
-Wert in einem Datensatz
der Tabelle db
bedeutet, dass die
Berechtigungen mit denen im Datensatz in der
host
-Tabelle kombiniert werden sollen,
der mit dem Hostnamen des Clients übereinstimmt. Diese
Berechtigungen werden mithilfe des logischen UND
(Schnittmenge), nicht des logischen ODER (Gesamtmenge)
verknüpft. Abschnitt 5.8.6, „Zugriffskontrolle, Phase 2: Anfrageüberprüfung“, beschreibt die
Verwendung der Tabelle host
im Detail.
Ein leerer Host
-Wert in den anderen
Grant-Tabellen entspricht '%'
.
Da es möglich ist, Jokerwerte in den IP-Adressen der
Host
-Spalte zu verwenden (z. B.
'144.155.166.%'
, um eine Übereinstimmung mit
jedem Host in einem bestimmten Subnetz zu erzielen), könnte
jemand versuchen, diese Funktionalität auszunutzen, indem er
einen Host 144.155.166.somewhere.com
nennt.
Um derartige Versuche zu durchkreuzen, verbietet MySQL
Mustervergleiche mit Hostnamen, die mit Ziffern und einem Punkt
beginnen. Das bedeutet, dass ,wenn Sie einen Host mit dem Namen
1.2.foo.com
oder ähnlich haben, dieser Name
niemals eine Übereinstimmung in der
Host
-Spalte der Grant-Tabellen finden wird.
Ein IP-Jokerwert kann nur mit IP-Adressen, nicht jedoch mit
Hostnamen übereinstimmen.
In der Spalte User
sind Jokerzeichen nicht
zulässig, Sie können jedoch einen leeren Wert angeben, der mit
jedem Namen übereinstimmt. Wenn der Datensatz in der Tabelle
user
, der mit einer eingehenden Verbindung
übereinstimmt, einen leeren Benutzernamen aufweist, dann wird
der Benutzer als anonymer Benutzer ohne Namen und nicht als
Benutzer mit dem Namen betrachtet, der eigentlich vom Client
übergeben wurde. Folglich wird ein leerer Benutzername für
alle weiteren Zugriffsüberprüfungen während der gesamten
Dauer der Verbindung (also während der zweiten Stufe)
verwendet.
Die Spalte Password
darf leer sein. Dies ist
kein Joker und bedeutet auch keine Übereinstimmung mit
beliebigen Passwörtern. Vielmehr besagt dies, dass der Benutzer
eine Verbindung ohne Angabe eines Passworts herstellen muss.
Nichtleere Password
-Werte in der Tabelle
user
stehen für verschlüsselte Passwörter.
MySQL speichert Passwörter nicht in unverschlüsselter,
problemlos ersichtlicher Form. Stattdessen wird das von einem
Benutzer, der eine Verbindung herstellen will, eingegebene
Passwort verschlüsselt (und zwar mit der Funktion
PASSWORD()
). Dieses verschlüsselte Passwort
wird dann während des Verbindungsaufbaus verwendet, um zu
überprüfen, ob das Passwort korrekt ist. (Dieser Vorgang
läuft ab, ohne dass das verschlüsselte Passwort jemals über
die Verbindung übermittelt wird.) Aus der Sicht von MySQL ist
das verschlüsselte Passwort das echte
Passwort, d. h. Sie sollten niemals jemandem den Zugriff darauf
ermöglichen. Insbesondere sollten Sie
Nichtadministratoren niemals Lesezugriff auf die
Tabellen in der mysql
-Datenbank
gewähren.
MySQL 5.1 verwendet eine stärkere, erstmals in
MySQL 4.1 implementierte Authentifizierungsmethode, die während
des Verbindungsvorgangs einen besseren Passwortschutz bietet als
frühere Versionen. Sie ist auch dann sicher, wenn TCP/IP-Pakete
abgefangen oder die mysql
-Datenbank
aufgezeichnet wird. Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“, enthält
eine eingehendere Beschreibung der Passwortverschlüsselung.
Die folgende Tabelle zeigt, wie verschiedene Kombinationen von
Host
- und User
-Werten in
der Tabelle user
auf eingehende Verbindungen
angewendet werden.
Host Wert
|
User Wert
|
Zulässige Verbindungen |
'thomas.loc.gov' |
'fred' |
fred , stellt Verbindung her über
thomas.loc.gov
|
'thomas.loc.gov' |
'' |
Beliebiger Benutzer, stellt Verbindung her über
thomas.loc.gov
|
'%' |
'fred' |
fred , stellt Verbindung her über beliebigen Host |
'%' |
'' |
Beliebiger Benutzer, stellt Verbindung her über beliebigen Host |
'%.loc.gov' |
'fred' |
fred , stellt Verbindung her über beliebigen Host in
der Domäne loc.gov
|
'x.y.%' |
'fred' |
fred , stellt Verbindung her über
x.y.net , x.y.com ,
x.y.edu und so weiter (dies ist
wahrscheinlich nicht sehr sinnvoll) |
'144.155.166.177' |
'fred' |
fred , stellt Verbindung her vom Host mit der
IP-Adresse 144.155.166.177
|
'144.155.166.%' |
'fred' |
fred , stellt Verbindung her über beliebigen Host im
Klasse-C-Subnetz 144.155.166
|
'144.155.166.0/255.255.255.0' |
'fred' |
wie oben |
Es kann durchaus vorkommen, dass für die Host- und
Benutzernamen einer eingehenden Verbindung mehrere passende
Datensätze in der Tabelle user
vorhanden
sind. Die obigen Beispiele demonstrieren dies: Mehrere der
angezeigten Einträge stimmen mit einer Verbindung von
fred
über thomas.loc.gov
überein.
Wenn mehrere Übereinstimmungen möglich sind, muss der Server ermitteln, welche davon er verwenden soll. Dieses Problem löst er wie folgt:
Wenn der Server die Tabelle user
in den
Speicher einliest, sortiert er die Datensätze.
Versucht nun ein Client eine Verbindung herzustellen, dann durchsucht der Server die Datensätze in der Sortierreihenfolge.
Der Server verwendet den ersten mit dem Host- und Benutzernamen des Clients übereinstimmenden Datensatz.
Um zu verstehen, wie dies funktioniert, nehmen wir einmal an,
dass die Tabelle user
wie folgt aussieht:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
Wenn der Server die Tabelle in den Speicher einliest, sortiert
er die Datensätze mit den spezifischsten
Host
-Werten nach oben. Literale Hostnamen und
IP-Nummern sind am spezifischsten. Das Muster
'%'
bedeutet „jeder Host“ und
ist am wenigsten spezifisch. Datensätze mit demselben
Host
-Wert werden nach den spezifischsten
User
-Werten sortiert (wobei ein leerer
User
-Wert die Bedeutung „beliebiger
Benutzer“ hat und am wenigsten spezifisch ist). Bei der
oben gezeigten Tabelle user
sieht das
Ergebnis nach der Sortierung wie folgt aus:
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
Wenn ein Client eine Verbindung herzustellen versucht,
durchsucht der Server die sortierten Datensätze und verwendet
die erste gefundene Übereinstimmung. Stellt
jeffrey
über localhost
eine Verbindung her, dann liegt bei zwei Datensätzen in der
Tabelle eine Übereinstimmung vor: zum einen der Datensatz mit
den Host
- und User
-Werten
'localhost'
und ''
, zum
anderen der Datensatz mit den Werten '%'
und
'jeffrey'
. Der Datensatz
'localhost'
taucht jedoch in der sortierten
Tabelle zuerst auf, wird also vom Server verwendet.
Es folgt ein weiteres Beispiel. Angenommen, die Tabelle
user
sähe so aus:
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
Die sortierte Tabelle hat dann folgendes Aussehen:
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
Für eine Verbindung von jeffrey
an
thomas.loc.gov
liegt eine Übereinstimmung
gleich beim ersten Datensatz vor; bei einer Verbindung von
jeffrey
an whitehouse.gov
trifft dies für den zweiten Datensatz zu.
Die Ansicht ist weitverbreitet, dass für einen gegebenen
Benutzernamen alle Datensätze, die diesen Namen ausdrücklich
angeben, zuerst verwendet werden, wenn der Server eine
Übereinstimmung für die Verbindung sucht. Dies ist allerdings
unzutreffend. Das obige Beispiel veranschaulicht dies: Eine
Verbindung von jeffrey
an
thomas.loc.gov
findet ihre erste
Übereinstimmung nicht bei dem Datensatz, der
'jeffrey'
als Wert in der Spalte
User
enthält, sondern beim Datensatz ohne
Benutzernamen. Hieraus folgt, dass jeffrey
als anonymer Benutzer authentifiziert wird, obwohl er bei der
Verbindungsherstellung einen Benutzernamen angegeben hat.
Wenn Sie eine Verbindung mit dem Server herstellen können, aber
Ihre Berechtigungen nicht dem entsprechen, was Sie erwarten,
dann wurden Sie wahrscheinlich über ein anderes Konto
authentifiziert. Um zu ermitteln, welches Konto der Server für
Ihre Authentifizierung verwendet hat, verwenden Sie die Funktion
CURRENT_USER()
. (Siehe auch
Abschnitt 12.10.3, „Informationsfunktionen“.) Sie gibt einen Wert im
Format
zurück, der die Werte user_name
@host_name
User
und
Host
des entsprechenden Datensatzes in der
Tabelle user
angibt. Angenommen,
jeffrey
hat eine Verbindung hergestellt und
setzt die folgende Abfrage ab:
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
Das hier gezeigte Ergebnis gibt an, dass der übereinstimmende
Datensatz in der Tabelle user
einen leeren
Wert in der Spalte User
aufweist. Mit anderen
Worten behandelt der Server jeffrey
als
anonymen Benutzer.
Ein anderer Schritt, den Sie zur Diagnose von
Authentifizierungsproblemen anwenden können, besteht darin, die
Tabelle user
auszudrucken und sie manuell zu
sortieren, um zu ermitteln, wo die erste Übereinstimmung
auftritt.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.