这似乎有效,但可能会产生不可预见的后果。它需要修改系统目录,这并不是一个好主意!
首先,您必须通过将其添加到您的 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;
您现在应该发现,如果您连接到that作为低权限用户访问数据库,\l
命令只会列出该用户可以连接的数据库。
问题是您现在需要猜测用户最初连接到哪个数据库以从中获取数据库列表。如果他们最初连接到自己的数据库,那么此时您可能已经完成了。如果他们连接到postgres
or template1
首先,您需要在该数据库上进行此更改。
在我看来这应该可行,因为pg_database
目录由 postgres 后端直接通过 oid 而不是通过名称引用,因此将其移开并更改其中显示的行对它们来说应该是不可见的。特别是,您无法阻止服务器向用户区分数据库不存在和没有连接权限。
我不会做出任何承诺,说这种改变不会把其他事情搞砸。如果它破裂了,你可以保留碎片。
您可能希望在模板数据库中进行此更改,并在将来从中创建用户数据库,并停用allow_system_table_mods
完成后进行设置(记住,这需要重新启动服务器)。
另外,我在 9.0 上对此进行了测试:在我看来,它也应该适用于某些早期版本,买者自负。