Безопасность
Проверка запроса
Каждый раз при получении запроса сервер проверяет в таблицах разрешений, обладает ли отправивший запрос пользователь достаточными полномочиями для его исполнения. Для этих целей таблицы user, db, tables_priv и column_priv просматриваются в установленном порядке до тех пор, пока не будет определено, что доступ разрешен, либо не будут проверены все таблицы разрешений. Более подробно этот процесс выглядит следующим образом.
-
При первоначальном подключении сервер проверяет записи таблицы user, пытаясь определить глобальные привилегии подключающегося пользователя. Если таковые имеются и, более того, являются достаточными для выполнения запроса, сервер обрабатывает запрос.
-
Если имеющихся глобальных привилегий недостаточно, сервер ищет дополнительные привилегии в таблице db. Если найденные привилегии позволяют выполнить запрос, сервер его обрабатывает.
Как хранятся пароли в таблице user
Пароли представлены в этой таблице в виде зашифрованных строк, поэтому узнать их не может даже пользователь, имеющий права доступа к этой таблице. Довольно широко распространено мнение, что функция password () применяет методы кодирования, используемые и для шифрования паролей UNIX, однако оно ошибочно.
Эти два способа кодирования действительно подобны в том отношении, что являются односторонними, т.е. необратимыми. Однако сервер MySQL использует иной алгоритм шифрования, чем UNIX. Это означает, что даже если UNIX-пароль является одновременно и паролем MySQL, зашифрованные строки пароля совпадать не будут. Чтобы использовать для приложения средства шифрования UNIX, вместо password запустите функцию CRYPT().
-
Если набора глобальных привилегий и привилегий баз данных недостаточно, сервер продолжает поиск сначала в таблице tables_priv, a потом и в columns_priv.
-
Если после проверки всех таблиц разрешений достаточных полномочий не найдено, сервер отклоняет попытку выполнения запроса.
Говоря на языке булевой алгебры, привилегии таблиц разрешений используются сервером следующим образом: user OR db OR tables_priv OR columns_priv
Некоторые читатели уже, возможно, задаются вопросом, почему в этой записи указывается четыре таблицы разрешений, хотя на самом деле их пять. Совершенно верно. Правильней было бы переписать ее следующим образом: user OR (db AND host) OR tables_pnv OR columns_priv
Упрощенный вариант был представлен исключительно для того, чтобы показать, что таблица host не подвержена влиянию операторов grant и REVOKE. Администраторы, управляющие привилегиями пользователей с помощью операторов grant и revoke, могут забыть о таблице host по следующим причинам.
-
Проверяя привилегии уровня базы данных, сервер ищет запись для клиента в таблице db. Пустое значение столбца Host означает примерно следующее: проверьте таблицу host, чтобы определить, какие компьютеры могут получать доступ к базе данных.
-
Сервер ищет в таблице host записи с таким же значением столбца Db, как и в записи таблицы db. Если компьютер подключающегося клиента не указан ни в одной записи таблицы host, то, следовательно, привилегии для работы с таблицами этому пользователю не предоставлены. Если значение столбца Host хотя бы одной записи этой таблицы соответствует компьютеру подключающегося пользователя, записи таблиц db и host объединяются, что приводит к определению реальных привилегий уровня баз данных клиента.
Привилегии объединяются посредством логического оператора and. Это означает, что пользователь будет иметь привилегии только в том случае, когда записи о нем будут представлены в обеих таблицах. Таким образом, пользователю может присваиваться базовый набор привилегий в записи таблицы db. Согласно записям таблицы host, получить их можно будет только с определенных компьютеров. Так, например, можно предоставить доступ к базам данных со всех компьютеров домена, но убрать эти привилегии для пользователей компьютеров, расположенных в менее защищенной области.
Из всего этого можно сделать вывод, что проверка привилегий — достаточно сложный процесс, особенно если учесть, что сервер проверяет привилегии при каждом получении запроса. Однако, на самом деле реализуется он весьма быстро, поскольку сервер не ищет информацию в таблицах разрешений для каждого запроса. Вместо этого содержимое таблиц записывается в память при загрузке, а данные затем быстро проверяются с помощью занесенных в память копий. Такая организация работы повышает производительность операций проверки доступа, хотя имеет и обратную сторону "медали" — сервер не замечает изменения привилегий при непосредственном изменении таблиц разрешений.
Например, если новый пользователь создается администратором путем добавления новой записи в таблицу user с помощью оператора insert, он не сможет сразу же подключиться к серверу. Начинающих администраторов (а иногда и вполне опытных) это зачастую весьма сильно раздражает, хотя решение этой проблемы предельно просто: достаточно указать серверу перезагрузить таблицы разрешений сразу после внесения изменений. Это можно осуществить с помощью оператора FLUSH PRIVILEGES или команды mysqladmin flush-privileges (либо mysqladmin reload, если используется более старая версия, не поддерживающая flush-privileges ).