Кажется, это работает, но может иметь непредвиденные последствия. Требуется возиться с системными каталогами, что не очень хорошая идея!
Прежде всего, вы должны разрешить суперпользователям обновлять системные каталоги, добавив это в вашу конфигурацию 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: мне кажется, это должно работать и на некоторых более ранних версиях, будьте осторожны.