Особенности триггеров в MySQL (SHOW TRIGGERS и SUPER PRIVELEGES)

На сервере возникла проблема такого плана. От имени пользователя root выполняем скрипт, который добавляет в БД триггеры. Потом другой пользователь выполняет команду SHOW TRIGGERS; и… ничего не видит. Но триггеры есть, мы можем посмотреть таблицу information_schema.TRIGGERS и увидеть их. Как же так получилось, что триггеры для пользователя стали невидимыми?

Сначала я подумал, что дело в DEFINER для триггера, и если я определю его как другого пользователя, то он его увидит.

Предложение DEFINER определяет логин MySQL, который нужно использовать при проверке привилегий доступа в вызове триггера. Это было добавлено в MySQL 5.0.17. Если дано значение user, это должно быть логином MySQL в формате ‘user_name’@’host_name’ (как в команде GRANT). Требуются переменные user_name и host_name. CURRENT_USER также может быть дан как CURRENT_USER(). Заданное по умолчанию значение DEFINER: пользователь, который выполняет инструкцию CREATE TRIGGER. Это также, как DEFINER = CURRENT_USER.
Если Вы определяете предложение DEFINER, Вы не можете устанавливать значение к любому логину, кроме Вашего собственного, если Вы не имеете привилегию SUPER. Эти правила определяют допустимые значения пользователя в DEFINER:
Если Вы не имеете привилегии SUPER, единственное допустимое значение user: Ваш собственный логин, определенный буквально или используя CURRENT_USER. Вы не можете устанавливать DEFINER к некоторому другому логину.
Если Вы имеете привилегию SUPER, Вы можете определять любое синтаксически допустимое имя пользователя. Если такого логина фактически не существует, будет сгенерировано предупреждение.
Хотя возможно создать триггер с несуществующим значением DEFINER, делать этого не следует, поскольку триггер не будет активизирован, пока DEFINER фактически не существует. Иначе, поведение относительно проверки привилегии неопределенно.
Обратите внимание: так как MySQL в настоящее время требует, чтобы была привилегия SUPER для использования CREATE TRIGGER, только второе из предшествующих правил применяется. MySQL 5.1.6 вводит право TRIGGER и требует, чтобы эта привилегия наличествовала для создания триггера, так что с этой версии оба правила работают, а SUPER требуется только для определения значения DEFINER другого, чем Ваш собственный логин.

Предложение DEFINER определяет логин MySQL, который нужно использовать при проверке привилегий доступа в вызове триггера. Это было добавлено в MySQL 5.0.17. Если дано значение user, это должно быть логином MySQL в формате ‘user_name’@’host_name’ (как в команде GRANT). Требуются переменные user_name и host_name. CURRENT_USER также может быть дан как CURRENT_USER(). Заданное по умолчанию значение DEFINER: пользователь, который выполняет инструкцию CREATE TRIGGER. Это также, как DEFINER = CURRENT_USER.

  • Если Вы определяете предложение DEFINER, Вы не можете устанавливать значение к любому логину, кроме Вашего собственного, если Вы не имеете привилегию SUPER. Эти правила определяют допустимые значения пользователя в DEFINER:
  • Если Вы не имеете привилегии SUPER, единственное допустимое значение user: Ваш собственный логин, определенный буквально или используя CURRENT_USER. Вы не можете устанавливать DEFINER к некоторому другому логину.
  • Если Вы имеете привилегию SUPER, Вы можете определять любое синтаксически допустимое имя пользователя. Если такого логина фактически не существует, будет сгенерировано предупреждение. Хотя возможно создать триггер с несуществующим значением DEFINER, делать этого не следует, поскольку триггер не будет активизирован, пока DEFINER фактически не существует. Иначе, поведение относительно проверки привилегии неопределенно.

Обратите внимание: так как MySQL в настоящее время требует, чтобы была привилегия SUPER для использования CREATE TRIGGER, только второе из предшествующих правил применяется. MySQL 5.1.6 вводит право TRIGGER и требует, чтобы эта привилегия наличествовала для создания триггера, так что с этой версии оба правила работают, а SUPER требуется только для определения значения DEFINER другого, чем Ваш собственный логин.

Но определение DEFINER не помогло. Триггеры всё также были невидимы для пользователя. А на самом деле проблема была вот в чём, в мануале четко сказано:

SHOW TRIGGERS lists the triggers currently defined on the MySQL server. This statement requires the SUPER privilege.

А это значит, что юзеру нужно дать SUPER привелегии. После того, как мы это сделали, всё заработало. Вообще очень странно, что для создания и удаления триггеров необходимы привелегии “TRIGGER”, а для просмотра триггеров “SUPER”. Ведь они дают кое-что еще:

The SUPER privilege enables an account to use CHANGE MASTER TOKILL or mysqladmin kill to kill threads belonging to other accounts (you can always kill your own threads), PURGE BINARY LOGS, configuration changes via SET GLOBAL to modify global system variables, the mysqladmin debug command, enabling or disabling logging, performing updates even if the read_only system variable is enabled, starting and stopping replication on slave servers, specification of any account in the DEFINER attribute of stored programs and views, and enables you to connect (once) even if the connection limit controlled by the max_connections system variable is reached.

To create or alter stored functions if binary logging is enabled, you may also need the SUPER privilege, as described in Section 19.7, “Binary Logging of Stored Programs”.

Вообщем пока я вижу это как дырку в безопасности, но триггеры использовать всё равно приходится, так что мы ограничили хосты в этих правах. Если у френдов есть идеи, как можно смотреть триггеры без SUPER PRIVELEGES, с удовольствием их послушаю.

UPD. Как вариант можно сделать хранимку, которая будет вызывать SHOW TRIGGERS и выдавать из пользователю.

1 Comment

Leave a Comment