Няма "привилегия за SELECT ". Всичко, от което се нуждаете, е привилегията да ИЗПЪЛНЯВАТЕ функции. Съответната функция може да се изпълнява с SECURITY ДЕФИНИТОР
да наследи всички привилегии на собственика. За да ограничите възможната ескалация на привилегии до минимум a priori, направете ролята на демон да притежава съответните функции само с необходимите привилегии - не суперпотребител!
Рецепта
Като суперпотребител...
Създайте роля, която не е суперпотребител myuser .
CREATE ROLE myuser PASSWORD ...;
Създайте групова роля mygroup и направете myuser член в него.
CREATE ROLE mygroup;
GRANT mygroup TO myuser;
Може да искате да добавите още потребители точно като myuser по-късно.
Не предоставяйте никакви привилегии до myuser .
Предоставяйте ги само на mygroup :
ПРЕДОСТАВЯНЕ НА СВЪРЗВАНЕ НА БАЗА ДАННИ mydb КЪМ mygroup;ПРЕДОСТАВЯНЕ НА ИЗПОЛЗВАНЕ НА SCHEMA public TO mygroup;ПРЕДОСТАВЯНЕ НА ИЗПЪЛНЕНИЕ НА ФУНКЦИЯ foo() НА mygroup;
Премахване на всички привилегии за public този myuser не е трябвало.
REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;
Може да има и повече. Цитирам ръководството:
Създайте роля на демон да притежавам подходящи функции.
CREATE ROLE mydaemon;
Дайте само привилегии, необходими за изпълнение на тези функции на mydaemon , (включително ИЗПЪЛНЕНИЕ НА ФУНКЦИЯ за да позволи извикването на друга функция). Отново можете да използвате групови роли, за да групирате привилегии и да ги предоставяте на mydaemon
GRANT bundle1 TO mydaemon;
Освен това можете да използвате ПРИВИЛЕГИИ ПО ПОДРАЗБИРАНЕкод>
за автоматично предоставяне на определени привилегии за бъдещи обекти на пакет или директно на демона:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE ON SEQUENCES TO bundle1;
Това се отнася само за ролята, за която се изпълнява. Съгласно документацията:
За да покриете и вече съществуващи обекти в схемата (вижте коментар на rob ):
GRANT SELECT ON ALL TABLES IN SCHEMA public TO bundle1;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bundle1;
Направете mydaemon собствени съответни функции. Може да изглежда така:
CREATE OR REPLACE FUNCTION foo()
...
SECURITY DEFINER SET search_path = myschema, pg_temp;
ALTER FUNCTION foo() OWNER TO mydaemon;
REVOKE EXECUTE ON FUNCTION foo() FROM public;
GRANT EXECUTE ON FUNCTION foo() TO mydaemon;
GRANT EXECUTE ON FUNCTION foo() TO mygroup;
-- possibly others ..
###Забележка
Поради този бъг
в текущата версия 1.16.1 на pgAdmin
необходимата команда
REVOKE EXECUTE ON FUNCTION foo() FROM public;
липсва в DDL скрипта с обратно проектиране. Не забравяйте да го добавите, когато създавате отново.
Тази грешка е коригирана в текущата версия pgAdmin 1.18.1.