поиск:
Полезные ссылки

  • Форум по MySQL

  • Статьи по MySQL

  • Вопросы по MySQL

  • MySQL.com


  • Базы данных

  • MySQL

  • PostgreSQL


  • PHP конференция 2005
    Подробности!

    4.2.9. Управление доступом, этап 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 Раздел 6.3.6.2, «Разные функции».

     
    © 1997-2005 PHP Club Team
    Rambler's Top100