2011-02-07 3 views
6

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

По существу a \l должен только перечислить его собственную базу данных.

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

+0

Почему бы просто не запустить сразу несколько экземпляров? –

+0

Мне нужно запустить их все в одном порту. – Kai

ответ

4

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

Во-первых, вы должны разрешить суперпользователям обновить системные каталоги, добавив в ваш 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 backends напрямую с помощью oid, а не по имени, поэтому перемещение его в сторону и изменение того, какие строки показаны в нем, должно быть невидимым им. В частности, вы не можете остановить сервер, отличающийся от пользователя, между существующей базой данных и отсутствием прав на подключение.

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

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

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

+0

Просто протестировал это. Похоже, он работает. Огромное спасибо. – Kai

+0

Хорошо, это что-то сломало :) pg_dump и pg_dumpall больше не работают. Ошибка: «Сообщение об ошибке с сервера: ERROR: столбец« tableoid »не существует» Команда была: SELECT tableoid, oid, (SELECT rolname FROM pg_catalog.pg_roles WHERE oid = datdba) AS dba, pg_encoding_to_char (кодирование) AS-кодирование, datcollate, datctype, datfrozenxid, (SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, shobj_description (oid, 'pg_database') AS description FROM pg_database WHERE datname = 'test_1' – Kai

+0

Было бы действительно здорово, если бы вы могли мне помочь чтобы исправить это, потому что кроме этого вы решаете работу просто отлично. – Kai

1

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

+0

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

+5

В зависимости от контекста, который может видеть другие базы данных, это большое дело. Это утечка данных. Я не понимаю, почему пользователь должен когда-либо видеть базу данных, в которой он не имеет бизнеса .... – harmv

+0

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

1

Я бы предположил, что это может иметь негативные последствия для пользователя, такие как невозможность подключения к базе данных, поскольку система не имеет доступа к таблицам систем, но не уверена. Но насколько выясняется, какая таблица отменяется - это хороший общий способ увидеть, что делают мета-команды 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 они не смогут использовать команду \ л.

Смежные вопросы