Разрешить пользователю postgres указывать только свою базу данных - PullRequest
6 голосов
/ 07 февраля 2011

Я использую сервер postgresql и хочу запретить своим пользователям видеть, какие другие базы данных находятся на том же сервере.

По существу \l должен указывать только свою собственную базу данных.

Я почти уверен, что есть право, которое мне нужно отозвать у пользователя, но я не могу найти его в документации.

Ответы [ 3 ]

4 голосов
/ 07 февраля 2011

Кажется, это работает, но может иметь непредвиденные последствия. Требуется возиться с системными каталогами, что не очень хорошая идея!

Прежде всего, вы должны разрешить суперпользователям обновлять системные каталоги, добавив это в вашу конфигурацию postgresql:

allow_system_table_mods = on

и перезагрузите.

Теперь вы можете использовать операторы DDL для изменения системных каталогов (вам следует опасаться). Подключитесь к одной из пользовательских баз данных (хорошей идеей будет тестовая) и:

alter table pg_catalog.pg_database rename to pg_database_catalog;
create view pg_catalog.pg_database as
  select oid, 1262::oid as tableoid, pg_database_catalog.*
  from pg_catalog.pg_database_catalog
  where has_database_privilege(pg_database_catalog.oid, 'connect');    
grant select on pg_catalog.pg_database to public;

Теперь вы должны обнаружить, что если вы подключитесь к этой базе данных как пользователь с низким уровнем привилегий, команда \l просто выведет список баз данных, к которым этот пользователь может подключиться.

Проблема в том, что теперь вам нужно угадать, к какой базе данных пользователи подключаются изначально, чтобы получить список своих баз данных. Если они подключаются к своей собственной базе данных изначально, то вы, вероятно, на этом закончите. Если они сначала подключаются к postgres или template1, вам нужно вместо этого внести изменения в эту базу данных.

Мне кажется, что это должно сработать, поскольку каталог pg_database упоминается бэкэндами postgres напрямую по oid, а не по имени, поэтому удаление его с пути и изменение отображаемых в нем строк должно быть невидим для них. В частности, вы не можете остановить сервер, различающий пользователя между несуществующей базой данных и не имеющей привилегии подключения.

Я не собираюсь делать никаких обещаний, что такого рода изменения не приведут к чему-то еще. Если он сломается, вы можете оставить себе кусочки.

Возможно, вы захотите внести это изменение в базу данных шаблонов, и создадите пользовательские базы данных из этого в будущем, и отключите настройку allow_system_table_mods, когда закончите (что требует перезагрузки сервера, помните).

Кроме того, я протестировал это на 9.0: мне кажется, это должно работать и на некоторых более ранних версиях, будьте осторожны.

1 голос
/ 07 февраля 2011

Я мог бы предположить, что это может иметь негативные последствия для пользователя, такие как невозможность подключения к базе данных, поскольку система не имеет доступа к таблицам систем, хотя не уверен. Но что касается определения таблицы, которую нужно отозвать - это хороший общий способ узнать, что делают метакоманды psql:

Чтобы увидеть, что делает \l, вы также можете использовать флаг -E из командной строки с psql.

~$ psql -E -c '\l'
********* QUERY **********
SELECT d.datname as "Name",
       pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
       pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
       d.datcollate as "Collation",
       d.datctype as "Ctype",
       pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
**************************

Таким образом, если пользователь не имеет доступа к базе данных pg_database, он не сможет использовать команду \ l.

1 голос
/ 07 февраля 2011

В pgsql такой настройки нет. Существуют настройки, запрещающие пользователям подключаться к базам данных, которые они не должны (разрешить / отменить подключение). Возможность увидеть базу данных не имеет большого значения. Возможность подключения / иметь права редактирования и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...