8.2.12 Ограничение привилегий с помощью частичных лишений
Можно предоставить привилегии, которые применяются глобально, если переменная системы partial_revokes включена. В частности, для пользователей, имеющих привилегии на глобальном уровне, partial_revokes позволяет лишать привилегий для определённых схем, сохраняя их для других схем. Такое ограничение привилегий может быть полезно для управления учётными записями, имеющими глобальные привилегии, но не имеющими права доступа к определённым схемам. Например, можно разрешить учётной записи изменять любые таблицы, кроме тех, которые находятся в схеме системы mysql.
Для краткости, CREATE USER операторы, показанные здесь, не включают пароли. Для использования в рабочей среде всегда устанавливайте пароли учётных записей.
Использование частичных отзывов
Системная переменная partial_revokes управляет возможностью установки ограничений прав доступа для учетных записей. По умолчанию, partial_revokes отключена, и попытки частично отозвать глобальные привилегии приводят к ошибке:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT ON *.* TO u1;
mysql> REVOKE INSERT ON world.* FROM u1;
ERROR 1141 (42000): There is no such grant defined for user 'u1' on host '%'
Чтобы разрешить операцию REVOKE, включите partial_revokes:
SET PERSIST partial_revokes = ON;
SET
PERSIST устанавливает значение для работающего экземпляра MySQL. Она также сохраняет значение, что приводит к его сохранению после последующих перезапусков сервера. Чтобы изменить значение для работающего экземпляра MySQL без сохранения его после последующих перезапусков, используйте ключевое слово GLOBAL вместо PERSIST. См. Раздел 15.7.6.1, «Синтаксис SET для присваивания переменных».
С включенной partial_revokes, частичный отзыв выполняется успешно:
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+------------------------------------------+
| Grants for u1@% |
+------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `world`.* FROM `u1`@`%` |
+------------------------------------------+
SHOW GRANTS перечисляет частичные отзывы как инструкции REVOKE в своем выводе. Результат указывает, что u1 имеет глобальные привилегии SELECT и INSERT, за исключением того, что INSERT не может быть использована для таблиц в схеме world. То есть, доступ u1 к таблицам world является только для чтения.
Сервер записывает ограничения прав доступа, реализованные с помощью частичных отзывов, в системной таблице mysql.user. Если учетная запись имеет частичные отзывы, значение столбца User_attributes имеет атрибут Restrictions:
mysql> SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
+------+------+------------------------------------------------------+
| User | Host | User_attributes->>'$.Restrictions' |
+------+------+------------------------------------------------------+
| u1 | % | [{"Database": "world", "Privileges": ["INSERT"]}] |
+------+------+------------------------------------------------------+
Хотя частичные отзывы могут быть наложены для любой схемы, ограничения прав доступа на системной схеме mysql в частности, полезны в рамках стратегии предотвращения изменения системных учетных записей обычными учетными записями. См. Защита системных учетных записей от манипулирования обычными учетными записями.
Операции частичного отзыва подчиняются следующим условиям:
Можно использовать частичные отзывы для установки ограничений на несуществующие схемы, но только если отозванная привилегия предоставлена глобально. Если привилегия не предоставлена глобально, ее отзыв для несуществующей схемы приводит к ошибке.
Частичные отзывы применяются только на уровне схемы. Нельзя использовать частичные отзывы для привилегий, которые применяются только глобально (например,
FILEилиBINLOG_ADMIN), или для привилегий таблиц, столбцов или процедур.При назначении привилегий включение
partial_revokesзаставляет MySQL интерпретировать вхождения неэкранированных символов SQL-шаблонов_и%в именах схем как литеральные символы, точно так же, как если бы они были экранированы как\_и\%. Поскольку это изменяет способ интерпретации привилегий MySQL, рекомендуется избегать неэкранированных символов подстановки в назначениях привилегий для установок, гдеpartial_revokesможет быть включена.
Как упоминалось ранее, частичные отзывы привилегий уровня схемы отображаются в выводе SHOW GRANTS как инструкции REVOKE. Это отличается от того, как SHOW GRANTS представляет привилегии уровня схемы “без ограничений”:
-
При предоставлении привилегии уровня схемы представляются собственными инструкциями
GRANTв выводе:mysql>
CREATE USER u1;mysql>GRANT UPDATE ON mysql.* TO u1;mysql>GRANT DELETE ON world.* TO u1;mysql>SHOW GRANTS FOR u1;+---------------------------------------+ | Grants for u1@% | +---------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | | GRANT UPDATE ON `mysql`.* TO `u1`@`%` | | GRANT DELETE ON `world`.* TO `u1`@`%` | +---------------------------------------+ -
При отзыве привилегии уровня схемы просто исчезают из вывода. Они не отображаются как инструкции
REVOKE:mysql>
REVOKE UPDATE ON mysql.* FROM u1;mysql>REVOKE DELETE ON world.* FROM u1;mysql>SHOW GRANTS FOR u1;+--------------------------------+ | Grants for u1@% | +--------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | +--------------------------------+
Когда пользователь предоставляет привилегию, любое ограничение, которое имеет грантодатель на привилегию, наследуется получателем, если только получатель уже не имеет привилегии без ограничения. Рассмотрим следующие двух пользователей, один из которых имеет глобальную привилегию SELECT:
CREATE USER u1, u2;
GRANT SELECT ON *.* TO u2;
Предположим, что административный пользователь admin имеет глобальную, но частично отозванную привилегию SELECT:
mysql> CREATE USER admin;
mysql> GRANT SELECT ON *.* TO admin WITH GRANT OPTION;
mysql> REVOKE SELECT ON mysql.* FROM admin;
mysql> SHOW GRANTS FOR admin;
+------------------------------------------------------+
| Grants for admin@% |
+------------------------------------------------------+
| GRANT SELECT ON *.* TO `admin`@`%` WITH GRANT OPTION |
| REVOKE SELECT ON `mysql`.* FROM `admin`@`%` |
+------------------------------------------------------+
Если admin предоставляет SELECT глобально u1 и u2, результат отличается для каждого пользователя:
-
Если
adminпредоставляетSELECTглобальноu1, который изначально не имеет привилегииSELECT,u1наследует ограничение привилегииadmin:mysql>
GRANT SELECT ON *.* TO u1;mysql>SHOW GRANTS FOR u1;+------------------------------------------+ | Grants for u1@% | +------------------------------------------+ | GRANT SELECT ON *.* TO `u1`@`%` | | REVOKE SELECT ON `mysql`.* FROM `u1`@`%` | +------------------------------------------+ -
С другой стороны,
u2уже имеет глобальную привилегиюSELECTбез ограничений.GRANTможет только добавлять к существующим привилегиям получателя, а не уменьшать их, поэтому, еслиadminпредоставляетSELECTглобальноu2,u2не наследует ограничениеadmin:mysql>
GRANT SELECT ON *.* TO u2;mysql>SHOW GRANTS FOR u2;+---------------------------------+ | Grants for u2@% | +---------------------------------+ | GRANT SELECT ON *.* TO `u2`@`%` | +---------------------------------+
Если инструкция GRANT включает в себя предложение AS , применяются ограничения прав доступа, наложенные на комбинацию пользователь/роль, указанную в предложении, а не на пользователя, который выполняет инструкцию. Информация о предложении userAS приведена в Разделе 15.7.1.6, «Инструкция GRANT».
Ограничения на новые привилегии, предоставленные учетной записи, добавляются к любым существующим ограничениям для этой учетной записи:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql> REVOKE INSERT ON mysql.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
mysql> REVOKE DELETE, UPDATE ON db2.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE UPDATE, DELETE ON `db2`.* FROM `u1`@`%` |
| REVOKE INSERT ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
Агрегация ограничений прав доступа применяется как при явном частичном отзыве привилегий (как показано выше), так и при неявном наследовании ограничений от пользователя, который выполняет инструкцию, или пользователя, упомянутого в предложении AS
. user
Если учетная запись имеет ограничение прав доступа на схему:
Учетная запись не может предоставлять другим учетным записям привилегии на ограниченной схеме или любом объекте внутри нее.
-
Другая учетная запись, которая не имеет ограничения, может предоставлять привилегии ограниченной учетной записи для ограниченной схемы или объектов внутри нее. Предположим, что неограниченный пользователь выполняет следующие инструкции:
CREATE USER u1; GRANT SELECT, INSERT, UPDATE ON *.* TO u1; REVOKE SELECT, INSERT, UPDATE ON mysql.* FROM u1; GRANT SELECT ON mysql.user TO u1; -- grant table privilege GRANT SELECT(Host,User) ON mysql.db TO u1; -- grant column privileges
Результирующая учетная запись имеет следующие привилегии, со способностью выполнять ограниченные операции в пределах ограниченной схемы:
mysql>
SHOW GRANTS FOR u1;+-----------------------------------------------------------+ | Grants for u1@% | +-----------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` | | REVOKE SELECT, INSERT, UPDATE ON `mysql`.* FROM `u1`@`%` | | GRANT SELECT (`Host`, `User`) ON `mysql`.`db` TO `u1`@`%` | | GRANT SELECT ON `mysql`.`user` TO `u1`@`%` | +-----------------------------------------------------------+
Если учетная запись имеет ограничение на глобальную привилегию, ограничение снимается любым из следующих действий:
Предоставление привилегии глобально учетной записи учетной записью, которая не имеет ограничений на привилегию.
Предоставление привилегии на уровне схемы.
Отзыв привилегии глобально.
Рассмотрим пользователя u1, который имеет несколько привилегий глобально, но с ограничениями на INSERT, UPDATE и DELETE:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql> REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+----------------------------------------------------------+
| Grants for u1@% |
+----------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE INSERT, UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` |
+----------------------------------------------------------+
Предоставление привилегии глобально u1 от учетной записи без ограничений снимает ограничение привилегии. Например, чтобы снять ограничение INSERT:
mysql> GRANT INSERT ON *.* TO u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
Предоставление привилегии на уровне схемы u1 снимает ограничение привилегии. Например, чтобы снять ограничение UPDATE:
mysql> GRANT UPDATE ON mysql.* TO u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE DELETE ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
Отзыв глобальной привилегии удаляет привилегию, включая любые ограничения на нее. Например, чтобы снять ограничение DELETE (ценой удаления всего доступа DELETE):
mysql> REVOKE DELETE ON *.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+-------------------------------------------------+
| Grants for u1@% |
+-------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` |
+-------------------------------------------------+
Если учетная запись имеет привилегию как на глобальном, так и на уровне схемы, ее необходимо отозвать на уровне схемы дважды, чтобы произвести частичное отозвать. Предположим, что u1 обладает этими привилегиями, где INSERT удерживается как на глобальном уровне, так и на схеме world:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT ON *.* TO u1;
mysql> GRANT INSERT ON world.* TO u1;
mysql> SHOW GRANTS FOR u1;
+-----------------------------------------+
| Grants for u1@% |
+-----------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| GRANT INSERT ON `world`.* TO `u1`@`%` |
+-----------------------------------------+
Отмена INSERT на world отменяет привилегию на уровне схемы (SHOW GRANTS больше не отображает оператор GRANT на уровне схемы):
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+-----------------------------------------+
| Grants for u1@% |
+-----------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
+-----------------------------------------+
Отмена INSERT на world повторно выполняет частичную отмену глобальной привилегии (SHOW GRANTS теперь включает оператор REVOKE на уровне схемы):
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+------------------------------------------+
| Grants for u1@% |
+------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `world`.* FROM `u1`@`%` |
+------------------------------------------+
Частичные отмены по сравнению с явными схемами
Чтобы предоставить доступ учетным записям к некоторым схемам, но не к другим, частичные отмены предлагают альтернативу подходу к явному предоставлению доступа на уровне схемы без предоставления глобальных привилегий. Эти два подхода имеют свои преимущества и недостатки.
Предоставление привилегий на уровне схемы, а не глобальных:
Добавление новой схемы: схема по умолчанию недоступна для существующих учетных записей. Для любой учетной записи, к которой должна быть доступна схема, администратор базы данных должен предоставить доступ на уровне схемы.
Добавление новой учетной записи: администратор базы данных должен предоставить доступ на уровне схемы для каждой схемы, к которой учетная запись должна иметь доступ.
Предоставление глобальных привилегий в сочетании с частичными отчислениями:
Добавление новой схемы: схема доступна для существующих учетных записей, обладающих глобальными привилегиями. Для любой такой учетной записи, к которой схема должна быть недоступна, администратор базы данных должен добавить частичную отмену.
Добавление новой учетной записи: администратор базы данных должен предоставить глобальные привилегии, а также частичную отмену для каждой ограниченной схемы.
Подход с явным предоставлением на уровне схемы удобнее для учетных записей, доступ к которым ограничен несколькими схемами. Подход с частичными отчислениями удобнее для учетных записей с широким доступом ко всем схемам, за исключением нескольких.
Отключение частичных отмений
После активации partial_revokes не может быть отключено, если у какой-либо учетной записи есть ограничения привилегий. Если такая учетная запись существует, отключение partial_revokes завершается ошибкой:
При попытке отключить
partial_revokesпри запуске сервер записывает сообщение об ошибке и включаетpartial_revokes.При попытке отключить
partial_revokesво время работы происходит ошибка, и значениеpartial_revokesостается неизменным.
Чтобы отключить partial_revokes при наличии ограничений, сначала необходимо удалить эти ограничения:
-
Определите, какие учетные записи имеют частичные отмены:
SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
-
Для каждой такой учетной записи удалите ее ограничения привилегий. Предположим, что на предыдущем шаге учетная запись
u1имеет эти ограничения:[{"Database": "world", "Privileges": ["INSERT", "DELETE"]Удаление ограничений может быть выполнено различными способами:
-
Предоставьте привилегии глобально без ограничений:
GRANT INSERT, DELETE ON *.* TO u1;
-
Предоставьте привилегии на уровне схемы:
GRANT INSERT, DELETE ON world.* TO u1;
-
Отмените привилегии глобально (если они больше не нужны):
REVOKE INSERT, DELETE ON *.* FROM u1;
-
Удалите саму учетную запись (если она больше не нужна):
DROP USER u1;
-
После удаления всех ограничений привилегий можно отключить частичные отмены:
SET PERSIST partial_revokes = OFF;
Частичные отмены и репликация
В сценариях репликации, если partial_revokes включено на любом узле, оно должно быть включено на всех узлах. В противном случае операторы REVOKE для частичной отмены глобальной привилегии не имеют одинакового эффекта на всех узлах репликации, что может привести к несоответствиям или ошибкам в репликации.
Когда partial_revokes включено, в двоичный журнал записывается расширенный синтаксис для операторов GRANT, включая текущего пользователя, который выпустил оператор, и его активные роли. Если пользователь или роль, записанные таким образом, не существуют на реплике, поток репликации останавливается на операторе GRANT с ошибкой. Убедитесь, что все учетные записи пользователей, которые выдают или могут выдавать операторы GRANT на сервере источника репликации, также существуют на реплике и имеют тот же набор ролей, что и на источнике.
© 2025 Oracle
Licensed under the GPLv2 License.