Мне интересно, почему вновь созданному пользователю разрешено создавать таблицу после подключения к базе данных. У меня есть одна база данных project2_core
:
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
Все идет нормально. Теперь я создаю пользователя:
postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER
Хорошо. Когда я пытаюсь подключиться к базе данных, пользователь не имеет права делать это:
$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich:
psql: FATAL: permission denied for database "project2_core"
DETAIL: User does not have CONNECT privilege.
Это то, что я ожидал. Теперь начинается странное. Я предоставляю пользователю CONNECT
:
postgres=# GRANT CONNECT ON DATABASE project2_core TO dietrich;
GRANT
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2+
| | | | | dietrich=c/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
И без каких-либо дополнительных разрешений, пользователь может создать таблицу:
$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich:
psql (9.2.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
project2_core=> create table adsf ();
CREATE TABLE
project2_core=> \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | adsf | table | dietrich
(1 row)
Я бы ожидал, что пользователю не разрешено ничего делать, прежде чем я сделаю это явно GRANT USAGE
для схемы, а затем GRANT SELECT
для таблиц.
Где моя ошибка? Что я делаю не так? Как я могу добиться того, чего хочу (чтобы новому пользователю не разрешалось ничего делать, прежде чем явно предоставить ему соответствующие права).
Я заблудился, и ваша помощь очень ценится :)
РЕДАКТИРОВАТЬ Следуя совету @ daniel-verite, теперь я отменил все сразу после создания базы данных. Пользователь dietrich больше не может создавать таблицы. Хорошо. НО : теперь владельцу базы данных project2 не разрешено создавать таблицы. Даже после выдачи GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2
и GRANT ALL PRIVILEGES ON SCHEMA public TO project2
я получаю ошибку ERROR: схема не была выбрана для создания , а когда я специально пытаюсь это сделать CREATE TABLE public.WHATEVER ();
, я получаю ERROR: разрешение отклонено для общедоступной схемы . Что я делаю не так?
источник
REVOKE ALL ON DATABASE project2_core FROM PUBLIC;
. почему это никак не отразилось?CREATE TABLE
. см. мое редактирование выше.Здесь важно понять, что привилегии не являются иерархическими и не наследуются от содержащихся объектов .
ALL
означает все привилегии для этого объекта, а не все привилегии для этого объекта и всех содержащихся в нем объектов .Когда вы даете
ALL
на базу данных, вы даетеCREATE, CONNECT, TEMP
. Это действия над объектом базы данных сами по себе:CONNECT
: Подключиться к БДCREATE
: Создать схему ( не таблицу)TEMP
: Создание временных объектов, в том числе временных таблицТеперь каждая база данных PostgreSQL по умолчанию имеет
public
схему, которая создается при ее создании. Эта схема имеет все права, предоставленные ролиpublic
, членом которой является каждый. Для схемыALL
означаетCREATE, USAGE
:CREATE
: Создание объектов (включая таблицы) в этой схемеUSAGE
: Список объектов в схеме и доступ к ним, если позволяют их разрешенияЕсли вы не укажете схему для создания объекта, подобного таблице, ядро базы данных будет использовать
search_path
, и по умолчаниюpublic
схема будет первой,search_path
поэтому таблица создается там. Каждый имеет праваpublic
по умолчанию, поэтому создание разрешено. Права пользователей на базу данных на данном этапе не имеют значения, так как пользователь не пытается ничего сделать с самим объектом базы данных, а только внутри него.Неважно, что вы не предоставили пользователю никаких прав, кроме предоставления
CONNECT
базы данных, посколькуpublic
схема позволяет всем пользователям создавать таблицы в ней по умолчанию. Даниэль уже объяснил, как отменить это право при желании.Если вы хотите явно делегировать все права, отзовите все у public или просто удалите публичную схему. Вы можете создать новую базу данных шаблонов с этим изменением, если хотите. Кроме того, вы можете применить его
template1
, но это, вероятно, сломает много стороннего кода, который предполагает, чтоpublic
существует и доступен для записи.Это может иметь больше смысла, если вы посмотрите на аналогию с файловой системой.
Если у меня есть структура каталогов (режим упрощен, чтобы показать только режим, который применяется к текущему пользователю):
тогда я не могу ничего создать внутри
/dir1
, потому что у меня нет разрешения на запись. Так что, если яtouch /dir1/somefile
получу разрешение отказано в ошибке.Тем не менее, у меня есть разрешение на просмотр
/dir1
и доступ к файлам и каталогам, в том числе/dir1/dir2
. У меня есть разрешение на записьdir2
. Такtouch /dir1/dir2/somefile
будет иметь успех , даже если у меня нет разрешения на записьdir1
.То же самое с базами данных и схемами.
источник
Если вы хотите только запретить новым пользователям создавать таблицы, вам нужно выполнить следующую команду:
Если вы
REVOKE ALL
(как подсказывают другие ответы) вы также запретите пользователям иметьUSAGE
разрешения.USAGE
означает, что пользователи могут использовать назначенные им разрешения, поэтому, если вы удалите их, ваши пользователи не смогут просматривать или получать доступ к таблицам, к которым у них есть доступ.В качестве альтернативы, вы могли бы также
REVOKE CREATE
для конкретного пользователя:Смотрите также: Как создать пользователя только для чтения с PostgreSQL .
источник