Журнал Начинающего Программиста 27, 2010-10-30 19:35
Здравствуйте,
Помните что:
Правильно заданный вопрос значительно ускорит и упростит решение проблемы.
Администрирование
БД
Распределение прав доступа
Аутентификация пользователя производится по имени (до 16 символов),
паролю (м.б. пустым)
и хосту или его IP. Большинство клиентских программ по умолчанию
используют mysql-имя, совпадающее
с unix-именем, но это можно изменить с помощью ключа --user=. Пароль
можно задать:
прямо в командной строке после ключа -p (без пробела, очень
опасно)
указав ключ -p без пароля (программа запросит пароль с
клавиатуры, наиболее безопасно)
в файле .my.cnf (права к этому файлу должны быть только у
собственника),
секция [client], поля host, user и password
с помощью переменной окружения MYSQL_PWD (очень опасно) и
MYSQL_HOST
Вся информация о правах хранится в БД с именем mysql. Никто не должен
иметь к ней доступа на чтение (см. про пароли).
Используются таблицы:
user (используется чтобы понять - пускать/не пускать; данные
здесь права действуют на все БД; административные привилегии и операции
с файлами определяются только здесь)
Host: CHAR(60),PRI, нечувствителен к регистру. Может
содержать имя хоста,
IP адрес или localhost. Можно использовать шаблоны с символами '%'
(любое количество
любых символов) и '_' (любой символ). Пустое поле означает,
что производится логическое "И" привилегий в данной строке и привилегий
в соответствующей строке таблицы host.
При использовании IP-адреса можно задавать сетевую маску (в виде -
/255.255.255.0 или /24).
User: CHAR(16),PRI. Пустое поле соответствует любому имени, в
данном случае
пользователь рассматривается как анонимный и предоставленное им имя
заменяется на пустое для дальнейших проверок прав доступа.
Password: CHAR(16), зашифрован, но не так как в Unix, знание
даже зашифрованного пароля позволяет выдать себя
за данного пользователя - пароль шифруется на стороне клиента! Может
быть пустым -
пользователь также должен предъявить пустой пароль.
привилегии: enum('N','Y'), по умолчанию - 'N'
select - выборка из строк таблицы
insert - вставка строки в таблицу
update - изменение строки таблицы
delete - удаление строки таблицы
create - создавать БД/таблицу
drop - удалять БД/таблицу
reload - позволяет выполнять административные команды
(reload, refresh, flush-*)
shutdown - позволяет остановить mysqld
process - позволяет выполнить processlist (можно смотреть
текст команд,
выполняемых другими пользователями (в т.ч. SET PASSWORD)), kill
file - читать файлы (LOAD DATA INFILE) и писать файлы
(SELECT ... INTO OUTFILE), с точки зрения Unix используются права, с
которыми запущен mysqld (в частности, он может прочитать /etc/passwd,
любую БД и т.п., записать файл в /tmp и т.п., но не может
переписать уже существующий файл)
grant - передавать свои привилегии другим, два
пользователя с различными привилегиями могут объединить их ;)
index - создавать/удалять индексы таблицы
alter - изменять формат таблицы, в том числе
переименовать ее, что позволяет обмануть
систему прав доступа
host
Host: CHAR(60),PRI. '%' или пустое поле означает - любой хост.
DB: CHAR(64),PRI. '%' или пустое поле означает - любая БД.
привилегии: enum('N','Y'), по умолчанию - 'N'
select
insert
update
delete
create
drop
grant
references
index
alter
db
Host: CHAR(60),PRI. Строка '%' означает - при доступе с
любого хоста. Пустое
поле означает необходимость посмотреть в таблицу host.
DB: CHAR(64),PRI. '%' или пустое поле означает - любая БД.
User: CHAR(16),PRI. Пустое поле - анонимный пользователь.
привилегии: enum('N','Y'), по умолчанию - 'N'
select
insert
update
delete
create
drop
grant
references
index
alter
tables_priv
Host: CHAR(60),PRI. '%' или пустое поле означает - любой хост.
DB: CHAR(60),PRI. Не м.б. пустым или содержать шаблоны.
User: CHAR(16),PRI. Пустое поле - анонимный пользователь.
Table_name: CHAR(60),PRI. Не м.б. пустым или содержать
шаблоны.
Проверка права на подсоединение к серверу: mysql-клиент предъявляет имя
пользователя,
сервер определяет имя (или IP) хоста клиента (или localhost для
обращения через
unix-socket). По данной паре (адрес/имя) ищется строка в таблице user.
Предварительно
таблица сортируется по полям (Host/User) так, что наиболее специфичные
строки оказываются первыми, наименее специфичные - последними. Если
строка не найдена,
то соединение отвергается. Если - найдена, то сверяется пароль.
Проверка прав при исполнении каждого запроса: таблица db сортируется
по полям Host,
Db и User, таблица host по полям Host и Db, таблицы tables_priv и
columns_priv по полям Host, Db и User от наиболее специфичного к
наименее. Для административных
запросов и доступа к файлам проверяется только таблица user. Для прочих
запросов
в начале проверяется таблица user - а нет ли у данного пользователя
прав доступа
на "глобальном" уровне. Если есть - операция разрешается. Если нет, то
проверяются
права доступа к конкретной БД с конкретного хоста (по пересечению
таблиц Db и Host с учетом шаблонов и пустых полей).
Если их достаточно, то доступ дается. Если недостаточно, то к
объединению
"глобальных" прав и прав БД/хост добавляются права, извлеченные из
таблиц tables_priv и columns_priv. Если и этого не хватает, то увы...
Права доступа читаются mysqld (и не читаются при "ручном"
изменении БД mysql):
при запуске
при выполнении команд GRANT, REVOKE и SET PASSWORD
при выполнении команды FLUSH PRIVILEGES
при выполнении mysqladmin flush-privileges/reload
"Глобальные" привилегии и изменения пароля вступают в силу только
при следующем
соединении. Изменения в доступе к БД - при следующей команде use.
Изменения
в доступе к таблицам и колонкам - при следующем запросе.
Изменение пароля: set password for имя=password('новый пароль').
GRANT тип-привилегии [(список-столбцов)] [, тип-привилегии
[(список-столбцов)] ...] ON { имя-таблицы | * | *.* | имя-БД.* } TO
имя-пользователя [ IDENTIFIED BY 'пароль' ] [, имя-пользователя [
IDENTIFIED BY 'пароль ] ... ] WITH GRANT OPTION
Для столбцов можно задавать только INSERT, SELECT и UPDATE. Для таблиц
- INSERT, SELECT, UPDATE, CREATE, DROP, DELETE, GRANT, INDEX, ALTER.
Использование "*.*" означает задание глобальных
привилегий. Использование "*" означает задание привилегий для текущей
БД (если текущей БД нет, то глобальные).
SHOW GRANTS FOR имя@хост;
Если привилегии на уровне таблиц и колонок используются хотя бы для
одного
пользователя, то проверки делаются для всех запросов всех
пользователей,
что очень сильно замедляет работу.