У якому порядку PostgreSQL перевіряє дозволи об’єкта?


16

Враховуючи роль бази даних, user1функцію, something()визначену як збережена процедура, та представлення, створене як:

CREATE VIEW view1 AS select * from something()

І, враховуючи ці дозволи:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Коли я бігаю SELECT * FROM view1, я отримую помилку permission denied for function something().

Моє запитання полягає в тому, що якщо я відкликаю дозволи на вибір для подання, чому функція викликається? Я очікував отримати щось на кшталт:

permission denied for relation view1

Дякую!


2
AFAIK немає визначеного порядку, в якому перевіряються дозволи.
Крейг Рінгер

@CraigRinger Дякую! Я думаю, що тоді очікувана поведінка. Коли я відкриваю подання в api, я намагався уникати деталей реалізації представлення даних (враховуючи повідомлення про помилку, яке скаржиться на дозволи функції замість перегляду).
santios

1
Я б підозрював, що дозволи доцільно оцінюватись у тих самих планах запитів мод (наприклад, знизу вгору), і як такий спочатку оцінюється найнижчий об'єкт, що у вашому випадку є something()функцією. Швидкий тест полягав би в тому, щоб змінити запит, щоб ви отримали інший план роз'яснення, відповідно скоригувавши дозволи, а потім побачите, чи викинута помилка дозволу на something()функцію чи випливає, як переоцінюється новий план виконання.
Джон Ейсбренер

Якщо ви надаєте дозволи на функцію та відкликаєте їх на перегляд, слід пропустити будь-яку згадку про основну функцію
ffflabs

Відповіді:


3

Проблема в цьому випадку полягає не зовсім у дозволі на дозвіл, а в порядку виконання.

В резюме для PostgreSQL:

1- Перегляди, які є таблицями, що переходять на зміну, перекриють дозвіл таблиць

2- Перегляди доступних функцій, потрібно буде оцінити всі функції, перш ніж перевірятись - тому функції повинні бути виконані перед тим, як перейти до перегляду, навіть якщо представлення не має дозволу на вибір ...

Як ми можемо це довести?

У postgresql представлення даних може надати вам дозволи на вибір у таблиці, навіть якщо користувач не має цих прав.

Наприклад:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Увійдіть як користувач 1:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

У цьому випадку користувач зможе вибрати view2, навіть не маючи дозволу на вибір таблиці.

Але що робити, якщо ми робимо те ж саме з функцією ? Поведінка НЕ однакова. Дозволяє створити функцію, яка чекає 5 секунд перед поверненням 1 (тому ми можемо налагоджувати, якщо postgresql виконує функцію кожного разу, коли ми називаємо представлення)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Увійдіть як користувач 1:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

Дозвіл на вибір на перегляді не перекриває дозвіл на функцію, і навіть гірше, якщо ми скасуємо дозволи з view1, повідомлення все одно показує, що postgresql зупинив наш запит через функцію, незалежно від дозволу перегляду .. (саме це відбувається в питанні)

Але чи справді функція перевіряється спочатку? Якщо ми надаємо функції "всі" для функції, але відкликаємо дозвіл на перегляд ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Як ви бачите, postgresql ЗАЧЕКАЮТЬ 5 секунд, перш ніж сказати, що ми не маємо дозволу на вигляд подання , показуючи, що функція "щось ()" виконується. Отже повернення даних про функцію повинно існувати до перевірки перегляду.

Отже, з цього тестування ми тепер знаємо, що PostgreSQL, необхідний для того, щоб спочатку оцінити всі функції, перш ніж продовжувати наш запит, подібно до того, як запит досі не існує, поки всі залучені функції не будуть повністю завершені, тому перегляд не може бути вирішений для postgresql до знати, маємо чи не маємо дозвіл на його вибір

Я думаю, що це відповідає на ваше запитання в термінах "дозволу на замовлення", але чому postgresql повинен оцінювати всі функції, перш ніж продовжувати, це вже інше питання ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.