Справочное руководство по MySQL версии 4.1.1-alpha

       

Управление доступом, этап 1: верификация подсоединения


При попытке соединения с сервером MySQL он либо устанавливает соединение, либо отказывает в нем - на основе данных о вашей личности и того, можете ли вы подтвердить их соответствующим паролем. Если нет, сервер полностью отказывает вам в доступе. В противном случае сервер устанавливает соединение, затем переходит ко второму этапу и ожидает запросов.

Личность задается двумя порциями информации:

  • хостом, с которого вы подсоединяетесь

  • вашим именем пользователя MySQL

    Проверка личности осуществляется с помощью трех полей контекста таблицы user (Host, User и Password). Сервер устанавливает соединение только в том случае, если находит в таблице user запись, в которой имя хоста и имя пользователя совпадают с введенными вами, и вы указываете правильный пароль.

    Значения в полях контекста таблицы user могут задаваться следующим образом:

    • В поле Host может указываться имя хоста, либо его IP-адрес, либо 'localhost' для обозначения локального хоста.

    • В поле Host разрешается использовать шаблонные символы `%' и `_'.

    • Значение '%' в поле Host означает любое имя хоста.



    • Пустое значение в поле Host означает, что к этой привилегии должна быть добавлена запись в таблице host, совпадающая с заданным именем хоста. Дополнительную информацию по данной теме вы найдете в следующем разделе.

    • Начиная с версии MySQL 3.23 для значений в поле в поле Host, определенных в виде IP-адресов, можно задавать сетевую маску, указывающую, сколько разрядов адреса будет использоваться для указания номера сети. Например:

      mysql> GRANT ALL PRIVILEGES ON db.* -> TO david'192.58.197.0/255.255.255.0';

      В этом случае все IP-адреса, для которых выполняется следующее условие:

      user_ip & netmask = host_ip.

      являются разрешенными для подсоединения. В предыдущем примере все IP-адреса в диапазоне от 192.58.197.0 до 192.58.197.255 являются разрешенными для подсоединения к серверу MySQL.

    • В поле User запрещено использовать шаблонные символы, но пустое значение разрешено, и оно соответствует любому имени. Если запись в таблице user, соответствующая входящему подсоединению, содержит пустое имя пользователя, данный пользователь считается анонимным пользователем (пользователем без имени), а заданное клиентом имя пользователя игнорируется. Это означает, что при всех последующих проверках доступа, осуществляемых на протяжении данного соединения (т.е. на этапе 2), будет использоваться пустое имя пользователя.




    • Поле Password может быть пустым. Это не означает, что в данном случае подходит любой пароль. Если поле пароля пусто, пользователь должен быть подсоединен без указания какого либо пароля.

      Непустые значения в поле Password представляют собой зашифрованные пароли. В MySQL пароли не хранятся в виде открытого текста, который может прочитать кто угодно. Напротив, пароль, который вводится пользователем при попытке подсоединения, шифруется (с помощью функции PASSWORD()). В дальнейшем зашифрованный пароль используется клиентом/сервером в процессе проверки его правильности (это делается вообще без пересылки пароля во время подсоединения). Заметим, что с MySQL считает зашифрованный пароль РЕАЛЬНЫМ паролем, поэтому не следует допускать к нему кого бы то ни было! В частности, не разрешайте обычным пользователям доступ для чтения к таблицам в базе mysql!

      Примеры, приведенные ниже, показывают, каким входящим подсоединениям соответствуют различные комбинации значений, указанных в полях Host и User

      таблицы user:

      Значение в поле Host Значение в поле User Подсоединения, которым соответствует запись 'thomas.loc.gov' 'fred' fred, подключающийся с thomas.loc.gov 'thomas.loc.gov' '' Любой пользователь, подключающийся с thomas.loc.gov '%' 'fred' fred, подключающийся с любого хоста '%' '' Любой пользователь, подключающийся с любого хоста '%.loc.gov' 'fred' fred, подключающийся с любого хоста, принадлежащего домену loc.gov 'x.y.%' 'fred' fred, подключающийся с x.y.net, x.y.com,x.y.edu, и т.д. (это, по-видимому, бесполезный вариант) '144.155.166.177' 'fred' fred, подключающийся с хоста, имеющего IP-адрес 144.155.166.177 '144.155.166.%' 'fred' fred, подключающийся с любого хоста в подсети 144.155.166 класса C '144.155.166.0/255.255.255.0' 'fred' То же самое, что и в предыдущем примере Поскольку в IP-адресе, указываемом в поле Host, могут использоваться шаблонные символы (например '144.155.166.%' - данное значение соответствует всем без исключения хостам указанной подсети), возникает опасность, что кто-нибудь может попытаться воспользоваться этой возможностью, указав имя хоста, например, как 144.155.166.somewhere.com. Чтобы ``поставить заслон'' таким попыткам, в MySQL не разрешены имена хостов, начинающиеся с цифр и точки. Другими словами, имени хоста типа 1.2.foo.com, никогда не найдется соответствия в столбцах Host таблиц привилегий. IP-адресу с шаблонными символами может соответствовать только IP-адрес.



      Входящее подсоединение может совпадать с несколькими записями в таблице user. Например, как было показано выше, подсоединению с thomas.loc.gov by fred могут подходить разные записи. Каким образом сервер определяет, какую из записей использовать, при совпадении с более чем одной из них? Для этого после считывания таблицы user во время запуска сервер производит ее сортировку, а затем, когда пользователь пытается установить соединение, записи таблицы просматриваются в порядке их упорядочения,. Используется первая подошедшая запись.

      Сортировка таблицы user осуществляется следующим образом. Предположим, таблица user имеет следующий вид:

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

      При считывании этой таблицы сервер упорядочивает записи, начиная с наиболее конкретных значений в столбце Host ('%' в столбце Host означает ``любой хост'' и является наименее конкретным). Записи с одинаковым значением в столбце Host упорядочиваются между собой начиная с наиболее конкретных значений в столбце User (пустое значение в столбце User

      означает ``любой пользователь'' и является наименее конкретным). Окончательно отсортированная таблица user имеет следующий вид:

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

      При попытке подсоединения сервер просматривает отсортированные записи и использует первую подходящую запись. Для подсоединения с localhost

      пользователя jeffrey первыми подходящими записями являются записи со значением 'localhost' в столбце Host. Из них запись с пустым значением имени пользователя соответствует и имени подсоединяющегося хоста и имени пользователя. (запись '%'/'jeffrey' тоже подошла бы, но она -- не первая подходящая в этой таблице).

      Рассмотрим другой пример. Пусть таблица user имеет вид:



      +----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-

      Отсортированная таблица выглядит следующим образом:

      +----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-

      Для подсоединения пользователя jeffrey с thomas.loc.gov подходит первая запись, в то время как для подсоединения jeffrey с whitehouse.gov - вторая.

      Существует распространенное заблуждение: иногда думают, что при поиске записей для данного имени пользователя, соответствующих определенному подсоединению, сервер первыми будет использовать записи, в которых этот пользователь указан явно. Это абсолютно неверно, как и продемонстрировано в предыдущем примере: для подсоединения пользователя jeffrey с thomas.loc.gov первой подходящей записью является не запись, содержащая значение 'jeffrey' в поле User, а запись, не содержащая имени пользователя вовсе!

      Если у вас возникают проблемы с подсоединением к серверу, выведите таблицу user и отсортируйте ее вручную, чтобы увидеть, где происходит первое совпадение.

      Если соединение было успешно, но ваши привилегии - не те, что вы ожидали увижеть, вы можете использовать функцию CURRENT_USER() (новшество с MySQL 4.0.6) чтобы узнать, какой комбинации пользователь/компьютер ваше соединение соответствует. See section 6.3.6.2 Разные функции.


      Содержание раздела