Spec-Zone.ru › MySQL 9.2

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 user, применяемые ограничения привилегий — это ограничения для комбинации пользователь/роль, указанной в предложении, а не для пользователя, который выполняет оператор. Для получения информации о предложении AS см. Раздел 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 при наличии ограничений, необходимо сначала удалить эти ограничения:

  1. Определите, какие учетные записи имеют частичные отозвания:

    SELECT User, Host, User_attributes->>'$.Restrictions'
    FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
    
  2. Для каждой такой учетной записи удалите её ограничения на привилегии. Предположим, что на предыдущем шаге учетная запись 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.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/partial-revokes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API