Какие привилегии необходимы для выполнения триггерной функции в PostgreSQL 8.4?

11

Какие привилегии необходимы для выполнения триггерной функции в PostgreSQL 8.4?

Кажется, что привилегии, установленные для роли, не имеют значения для выполнения триггерной функции. Я думаю, что однажды я видел, что привилегии, необходимые для выполнения функции триггера, являются привилегией EXECUTE, но для владельца таблицы, а не для фактической роли, выполняющей действие, запускающее триггер, который вызывает функцию триггера.

Я не могу найти часть документации, которая объясняет этот вопрос, какую-либо помощь?

Эрвин Брандштеттер
источник

Ответы:

10

Функции триггера ведут себя так же, как и другие функции, что касается привилегий. За небольшим исключением:

Чтобы создать триггер для таблицы, пользователь должен иметь TRIGGER привилегию для таблицы. Пользователь также должен иметь EXECUTEпривилегию на функцию триггера.

ОБНОВЛЕНИЕ После обратной связи в комментариях я провел небольшое исследование. В Вики Postgres есть открытый пункт TODO:

Затянуть проверки разрешений триггеров

Связанный с этой темой на хакерах Postgres . В настоящее время EXECUTEпривилегии для функции триггера проверяются только во время создания триггера , но не во время выполнения. Таким образом, отмена EXECUTE для функции триггера не влияет на триггер после его создания. Ваше наблюдение кажется правильным.

Это не дает никаких дополнительных привилегий для манипулирования объектами. Если вызывающая роль не имеет привилегий, необходимых для выполнения (части) тела функции, возникает обычное исключение. Чтобы проложить путь, вы можете сделать привилегированного пользователя OWNERфункции и использовать

SECURITY DEFINER

пункт, как указано в руководстве здесь . Это вызывает запуск функции с разрешениями владельца вместо invoker (по умолчанию).

Если владелец является суперпользователем, вам нужно быть очень осторожным с тем, кому вы предоставляете EXECUTEпривилегию, и что может сделать функция, чтобы избежать злоупотреблений. Вы можете захотеть

REVOKE ALL ON FUNCTION foo() FROM public;

для начала и использовать SET search_pathдля функции.
Обязательно прочитайте главу о безопасном написании SECURITY DEFINERфункций .

Найдите пример кода в этом связанном ответе на SO.

Эрвин Брандштеттер
источник
Нет, я не хочу SECURITY DEFINER, я хочу SECURITY INVOKER. Но кажется (для функции триггера, а не для обычной функции), что при использовании опции по умолчанию ( SECURITY INVOKER), это не действует так.
1
@EtienneRouxel: триггерные функции - это функции, подобные другим функциям, если речь идет о привилегиях. Что заставляет вас думать иначе?
Эрвин Брандштеттер
@EtienneRouxel: я добавил цитату из руководства, чтобы документировать незначительное исключение.
Эрвин Брандштеттер
1
Тестирование: я создал простую триггерную функцию, которая вызывает NOTICE. Я удалил ALLпривилегии от PUBLICи от владельца функции. Затем, если я использую владельца или любую другую роль, у которой нет никаких привилегий для этой функции, я должен ожидать ошибку из-за отсутствия привилегий, но все работает успешно.
2
@EtienneRouxel: интересно. Я тоже проверял. Вы не можете создать триггер, если у вас нет привилегии выполнения для функции триггера. Но вы все равно можете отозвать эту привилегию выполнения после создания триггера, и триггер не перестанет работать. Я провел некоторое исследование. Добавление ссылок на вопрос ...
Эрвин Брандштеттер