Які ВИКОРИСТАННІ ВИКОРИСТАННЯ В СХЕМІ саме роблять?


121

Я вперше намагаюся створити базу даних Postgres, тому це, мабуть, дурне питання. Я призначив основні дозволи лише для читання ролі db, яка повинна отримувати доступ до бази даних з моїх скриптів php, і я маю цікавість: якщо я виконую

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

чи є також необхідність виконати

GRANT USAGE ON SCHEMA schema TO role;

?

З документації :

ВИКОРИСТАННЯ: Для схем надає доступ до об'єктів, що містяться у зазначеній схемі (при умові, що власні вимоги до привілеїв об'єктів також виконуються). По суті, це дозволяє отримувачеві "шукати" об'єкти в схемі.

Я думаю, що якщо я можу вибрати або маніпулювати будь-якими даними, що містяться у схемі, я можу отримати доступ до будь-яких об’єктів схеми. Я помиляюся? Якщо ні, для чого GRANT USAGE ON SCHEMAвикористовується? І що саме означає документація з "припущенням, що власні вимоги до об'єктів також виконуються"?

Відповіді:


126

GRANTs на різних об'єктах є окремими. GRANTING на базі даних не має GRANTправа на схему всередині. Аналогічно, GRANTсхема на схемі не надає прав на таблиці всередині.

Якщо ви маєте права на SELECTтаблицю, але не маєте права бачити її у схемі, яка містить її, ви не можете отримати доступ до таблиці.

Тести на права робляться для того, щоб:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

Ваша плутанина може виникнути через те, що в publicсхемі за замовчуванням GRANTє всі права на роль public, учасником якої є кожен користувач / група. Тож усі вже мають використання в цій схемі.

Фраза:

(якщо припускати, що власні вимоги до об'єктів також виконуються)

Це USAGEозначає, що ви повинні мати схему, щоб використовувати об'єкти всередині неї, але наявність USAGEсхеми сама по собі не є достатньою для використання об'єктів у схемі, ви також повинні мати права на самі об'єкти.

Це як дерево каталогів. Якщо ви створили каталог somedirз файлом somefileвсередині нього, то встановіть його таким чином, щоб тільки ваш власний користувач міг отримати доступ до каталогу чи файлу (режим rwx------у режимі dir, режим rw-------у файлі), тоді ніхто інший не може перелічити каталог, щоб побачити, що файл існує.

Якщо ви мали б надати права на читання у всьому світі на файл (режим rw-r--r--), але не змінювати дозволи довідок, це не мало би значення. Ніхто не міг побачити файл для того, щоб прочитати його, оскільки вони не мають права перелічити каталог.

Якщо ви замість цього встановите rwx-r-xr-xна каталог, встановивши його так, щоб люди могли перелічувати та переходити каталог, але не змінюючи дозволи файлу, люди могли перелічити файл, але не змогли прочитати його, оскільки вони не мали б доступу до файлу.

Потрібно встановити обидва дозволи для того, щоб люди могли переглядати файл.

Те саме в Pg. Вам потрібні як USAGEправа схеми, так і права на об'єкт для виконання дії над об'єктом, наприклад SELECTіз таблиці.

(Аналогія падає вниз трохи в тому , що PostgreSQL не має захисту на рівні рядків ще, так що користувач може по- , як і раніше «бачити» , що таблиця існує в схемі по SELECTІНГ від pg_classбезпосередньо. Вони не можуть взаємодіяти з ним яким - небудь чином , однак, так що це просто "список", який не зовсім однаковий.)


2
Зараз це дуже зрозуміло з прикладом каталогу :) Я мушу сказати, що це проблема, якщо ви вставляєте якусь таблицю або рядок із суперрусером, наприклад, коли ви додаєте postGIS за допомогою CREATE EXTENSION. Це більш-менш та сама проблема з файлами, створеними в Linux, поки ви знаходитесь su. Буде добре, якщо sudo -eв pqsl є така собі форма для тверджень.
Марко Сулла

Так чи інакше, я зрозумів, що GRANTзаяви, не конкретні для таблиць, - це не те, чого я хочу, оскільки вони впливають на всі бази даних ...: s
Marco Sulla

1
@LucasMalor Ер ... ні, вони ні. GRANTна схемі впливає на цю схему. GRANT ... ON ALL TABLES IN SCHEMA ...впливає на всі таблиці в схемі певної бази даних. Немає GRANTs, які впливають на всі бази даних (нормально, крім GRANTчленства ролі користувача).
Крейг Рінгер

Вибачте, я виконав заяви, коли мене зареєстрували як "postgres" суперрусера, і вони вплинули на базу даних "postgres". Я думав, що якщо ти працюєш psqlбез -d dbтого, що ти працюєш "поза" будь-якого db, але ти завжди підключений до db і за замовчуванням ти підключений до db з тим самим іменем своєї ролі. db = role = користувач = група ... це трохи заплутано: D
Marco Sulla

@LucasMalor Думай про це так. За замовчуванням ви підключаєтесь до БД з тим самим іменем, що і роль для входу ("користувач"), до якої ви підключаєтеся. "Користувачі" - це лише ролі, які є WITH LOGIN; по суті, все може бути групою, а групи можна налаштувати, щоб мати можливість увійти.
Крейг Рінгер

72

Для виробничої системи ви можете використовувати цю конфігурацію:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;

Не слід adminтакож надавати CREATEсхему?
Дан

2
Доступ розподіляється відповідно до ієрархічної моделі: BD -> SCHEMA -> TABLES . З GRANT USAGE ON SCHEMA, користувач адміністратор не може створити таблицю , але він може зробити це з ALL GRANT ALL ON SCHEMA....
bilelovitch

@bilelovitch: ти маєш на увазі grant all on schema public to admin? PS: Я також додав grant usage, select on all sequences in schema public to read_only/read_write; grant execute on all functions in schema public to read_only/read_write;
Marco Sulla

2

Ну, це моє остаточне рішення для простого db, для Linux:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D

1
Якого користувача потрібно використовувати для "# Створити всі таблиці та об'єкти, а після цього:"? Хто є власником таблиць та інших об’єктів у вашому випадку?
Крістоф

@ChristopheFurmaniak ви праві, я виправив процес. Власник db та його об'єктів - $ ROLE_LOCAL, і, створивши структуру db, ми повинні повернутися до суперресурсу postgres.
Марко Сулла

Я вважаю, у вас є проблеми у ваших командах "ПІДТРИМАТИ ПРИВИЛЕГИ ...". Ця команда використовується для запуску привілеїв надання одному користувачеві (ролі), коли інший користувач (роль) створює об'єкт. Для роз'яснення див. Сторінку 11, розділ 7.1 цього документа . Наразі ваш ROLE_REMOTE не матиме доступу до жодних об'єктів, які ROLE_LOCAL створив би. Команди ROLE_LOCAL дають лише приватні особи, які вже мають роль власника цих об'єктів. Те саме стосується і команд ROLE_REMOTE.
емісіонер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.