MySQL: установка, настройка, описание - Права доступа
ОГЛАВЛЕНИЕ
Права доступа
Аутентификация пользователя производится по имени (до 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 - передавать свои привилегии другим, два пользователя с различными привилегиями могут объединить их ;)
- references - не реализовано
- 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)(или 64?),PRI. Не м.б. пустым или содержать шаблоны.
- Grantor: CHAR(77)
- Timestamp: timestamp(14)
- Table_priv: set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter')
- Column_priv: set('Select','Insert','Update','References')
- culumns_priv
- Host: CHAR(60),PRI. '%' или пустое поле означает - любой хост.
- DB: CHAR(60),PRI. Не м.б. пустым или содержать шаблоны.
- User: CHAR(16),PRI. Пустое поле - анонимный пользователь.
- Table_name: CHAR(64)(или 60?),PRI. Не м.б. пустым или содержать шаблоны.
- Column_name: CHAR(64)(или 60?),PRI. Не м.б. пустым или содержать шаблоны.
- Timestamp: timestamp(14)
- Column_priv: set('Select','Insert','Update','References')
Проверка права на подсоединение к серверу: 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. Изменения в доступе к таблицам и колонкам - при следующем запросе.
Все команды, введенные в клиенте mysql (а в других?) попадают в .mysql_history (того unix-пользователя, который запускал mysql). А также в различные журналы сервера и в выдачу команды SHOW PROCESSLIST.
Изменение пароля: set password for имя=password('новый пароль').
GRANT тип-привилегии [(список-столбцов)] [, тип-привилегии [(список-столбцов)] ...] ON { имя-таблицы | * | *.* | имя-БД.* } TO имя-пользователя [ IDENTIFIED BY 'пароль' ] [, имя-пользователя [ IDENTIFIED BY 'пароль ] ... ] WITH GRANT OPTION
REVOKE тип-привилегии [(список-столбцов)] [, тип-привилегии [(список-столбцов)] ...] ON { имя-таблицы | * | *.* | имя-БД.* } FROM имя-пользователя [, имя-пользователя ... ]
Типы привилегий:
- ALL PRIVILEGES (aka ALL)
- ALTER
- CREATE
- DELETE
- DROP
- FILE
- GRANT OPTION (только для REVOKE)
- INDEX
- INSERT
- PROCESS
- REFERENCES (не реализовано)
- RELOAD
- SELECT
- SHUTDOWN
- UPDATE
- USAGE (никаких - просто место застолбить)
Для столбцов можно задавать только INSERT, SELECT и UPDATE. Для таблиц - INSERT, SELECT, UPDATE, CREATE, DROP, DELETE, GRANT, INDEX, ALTER. Использование "*.*" означает задание глобальных привилегий. Использование "*" означает задание привилегий для текущей БД (если текущей БД нет, то глобальные).
SHOW GRANTS FOR имя@хост;
Если привилегии на уровне таблиц и колонок используются хотя бы для одного пользователя, то проверки делаются для всех запросов всех пользователей, что очень сильно замедляет работу.
Для упрощения жизни можно использовать утилиты mysqladmin и mysqlaccess, xmysqladmin, mysql_webadmin из директории Contrib.
Посмотрев на это безобразие, ORACLE может перестать волноваться ;) Зря они различают пользователей с одним именем, пришедших с разных хостов (наверное, когда-то mysql-имя совпадало с unix-именем и этой информации м.б. доверять :). Не говоря об отсутствии шифровки при передаче данных по сети и возможность подсовывать перехваченный зашифрованный пароль
Не храните пароли и тому подобную информацию в БД в открытом виде.