Как предоставить выполнение функции pgcrypto digest пользователю

Использование postgresql 9.6

Я включил pgcrypto, используя создание расширения pgcrypto, используя пользователя postgres. Теперь я хочу предоставить права на выполнение другому пользователю БД. К сожалению, я не могу это сделать. Это возможно, или вы должны быть суперпользователем, чтобы использовать функцию дайджеста из pgcrypto.

postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR:  syntax error at or near "digest"
LINE 1: GRANT EXECUTE ON FUNCTION digest TO another_user;

Используя ответ ниже, я смог успешно предоставить разрешение на выполнение функции. Однако другой_пользователь не может выполнить функцию. Есть ли другие разрешения, которые мне нужны для выполнения этой функции с использованием another_user?

another_user=> SELECT digest('whatisgoingon'::text, 'sha256'::text);
ERROR:  function digest(text, text) does not exist
LINE 1: SELECT digest('whatisgoingon'::text, 'sha256'::text);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

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

postgres=# select has_function_privilege('another_user', 'digest(text, text)', 'execute');
 has_function_privilege 
------------------------
 t
(1 row)

Спасибо

1 ответ

Решение

Postgres поддерживает перегрузку, то есть несколько функций с одним и тем же именем, но с разными списками аргументов.

При вызове функции в SQL она выясняет, какую версию вы имели в виду, основываясь на количестве параметров и их типах. Но при ссылке на функцию в команде DDL (DROP, ALTER, GRANT и т. д.), вам нужно точно указать, какую версию вы имели в виду, включая список типов аргументов после имени функции.

Это весьма актуально в случае digest потому что на самом деле есть две версии, и вам нужно уточнить, о какой вы говорите. Так что либо:

GRANT EXECUTE ON FUNCTION digest(text,text) TO another_user

...или же:

GRANT EXECUTE ON FUNCTION digest(bytea,text) TO another_user

(...или оба.)


Начиная с Postgres 10, вы можете опускать список аргументов, когда функция не перегружена. Это не очень поможет вам в случае digest, но по крайней мере вы получите более информативное сообщение об ошибке:

postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR:  function name "digest" is not unique
HINT:  Specify the argument list to select the function unambiguously.

Что касается вашего последующего вопроса относительно function does not exist ошибка, попробуйте указать схему с именем функции, например SELECT my_schema.digest(...),

  • Если это работает, это проблема поиска пути. Вы можете либо продолжить вызывать его с явным именем схемы, либо обновить свой search_path,

  • Если он отвечает ERROR: permission denied for schema my_schema тогда вам просто нужно GRANT USAGE ON SCHEMA my_schema TO another_user,

  • Если это все еще говорит function my_schema.digest(text, text) does not exist, то вы, вероятно, подключились к неправильной базе данных по ошибке.

Другие вопросы по тегам