Что именно делает ГРАНТ ИСПОЛЬЗОВАНИЯ ПО СХЕМЕ?

123

Я впервые пытаюсь создать базу данных 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 для чего? И что именно означает документация под «предположением, что собственные требования к привилегиям объектов также выполнены»?

Марко Сулла
источник

Ответы:

128

GRANTs на разных объектах разделены. GRANTРабота с базой данных не имеет 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------, режим rw-------в файле), тогда никто другой не сможет перечислить каталог, чтобы убедиться, что файл существует.

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

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

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

То же самое на стр. Вам нужны как USAGEправа схемы, так и права объекта, чтобы выполнить действие над объектом, например SELECTнад таблицей.

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

Крэйг Рингер
источник
2
Теперь это очень ясно с примером каталога :) Я должен сказать, что это проблема, если вы вставляете какую-то таблицу или строку с суперпользователем, например, когда вы добавляете postGIS с помощью CREATE EXTENSION. Это более или менее та же проблема с файлами, созданными в Linux, пока вы su. Будет хорошо, если sudo -eв pqsl будет что-то вроде операторов for.
Марко Сулла
В любом случае, теперь я понял, что GRANTутверждения, не относящиеся к таблицам, - это не то, что я хочу, поскольку они влияют на все базы данных ...: s
Марко Сулла
1
@LucasMalor Э ... нет, они этого не делают. GRANTв схеме влияет на эту схему. GRANT ... ON ALL TABLES IN SCHEMA ...влияет на все таблицы в схеме в конкретной базе данных. Нет никаких GRANTs, которые влияют на все базы данных (хорошо, кроме GRANTчленства в роли для пользователя).
Craig Ringer
Извините, я выполнил операторы, когда был зарегистрирован как суперпользователь postgres, и они повлияли на базу данных postgres. Я думал, что если вы работаете psqlбез, -d dbвы работаете "вне" любой базы данных, но вы всегда подключены к базе данных, и по умолчанию вы подключены к базе данных с тем же именем, что и ваша роль. db = role = user = group ... это немного сбивает с толку: D
Марко Сулла
@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;
Марко Сулла
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
Какого пользователя нужно использовать для «# Создать все таблицы и объекты, а затем:»? Кто в вашем случае является владельцем столов и других предметов?
Christophe
@ChristopheFurmaniak, ты прав, я поправил процесс. Владелец db и его объектов - $ ROLE_LOCAL, и после создания структуры db мы должны вернуться к суперпользователю postgres.
Марко Сулла
Я считаю, что у вас есть проблема с командами «ALTER DEFAULT PRIVILEGES ...». Эта команда используется для запуска предоставления привилегий одному пользователю (роли), когда другой пользователь (роль) создает объект. См. Стр. 11, раздел 7.1, этого документа для разъяснения. В настоящее время ваш ROLE_REMOTE не будет иметь доступа ни к каким объектам, которые может создать ROLE_LOCAL. Команды ROLE_LOCAL предоставляют только те привилегии, которые у роли уже есть как Владелец этих объектов. То же самое и с командами ROLE_REMOTE.
Emispowder