2011-02-07 35 views
6

Tôi đang sử dụng máy chủ postgresql và tôi muốn cấm người dùng của mình xem cơ sở dữ liệu khác trên cùng một máy chủ.Cho phép người dùng postgres chỉ liệt kê cơ sở dữ liệu của riêng mình

Về cơ bản, \l chỉ nên liệt kê cơ sở dữ liệu của riêng mình.

Tôi khá chắc chắn rằng có quyền mà tôi cần thu hồi từ người dùng nhưng tôi không thể tìm thấy nó trong tài liệu.

+0

Tại sao không chỉ có nhiều phiên bản chạy cùng một lúc? –

+0

Tôi cần phải chạy tất cả trên cùng một cổng. – Kai

Trả lời

4

Điều này dường như hoạt động nhưng có thể có hậu quả không lường trước được. Nó đòi hỏi mày mò với danh mục hệ thống, mà không thực sự là một ý tưởng tốt!

Trước hết, bạn phải cho phép superusers để cập nhật catalog hệ thống bằng cách thêm này để cấu hình postgresql của bạn:

allow_system_table_mods = on 

và khởi động lại.

Bây giờ, bạn có thể sử dụng câu lệnh DDL để sửa đổi danh mục hệ thống (bạn nên sợ). Kết nối với một trong những cơ sở dữ liệu người dùng (một thử nghiệm người ta sẽ là một ý tưởng tốt) và:

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; 

Bây giờ bạn sẽ thấy rằng nếu bạn kết nối với rằng cơ sở dữ liệu như một người dùng thấp priv, lệnh \l sẽ chỉ cần liệt kê các cơ sở dữ liệu mà người dùng có thể kết nối.

Vấn đề là bây giờ bạn cần đoán cơ sở dữ liệu mà người dùng kết nối ban đầu để tìm nạp danh sách cơ sở dữ liệu của họ từ đó. Nếu họ kết nối với cơ sở dữ liệu riêng của họ ban đầu, thì có thể bạn đã hoàn thành vào thời điểm này. Nếu họ kết nối với postgres hoặc template1 trước tiên, thì bạn cần thực hiện thay đổi này trên cơ sở dữ liệu đó thay thế. Dường như với tôi rằng điều này sẽ làm việc, vì danh mục pg_database được giới thiệu bởi postgres backends trực tiếp bởi oid, chứ không phải theo tên, do đó, di chuyển nó ra khỏi con đường và thay đổi những hàng được hiển thị trong nó sẽ là vô hình đối với họ. Đặc biệt, bạn không thể dừng máy chủ phân biệt với người dùng giữa một cơ sở dữ liệu không tồn tại và chúng không có đặc quyền kết nối.

Tôi sẽ không thực hiện bất kỳ lời hứa nào rằng loại thay đổi này không làm hỏng thứ gì đó khác. Nếu nó phá vỡ, bạn có thể giữ các mảnh.

Bạn có thể muốn thực hiện thay đổi này trong cơ sở dữ liệu mẫu và tạo cơ sở dữ liệu người dùng từ đó trong tương lai và tắt cài đặt allow_system_table_mods khi bạn hoàn tất (yêu cầu máy chủ khởi động lại, nhớ).

Ngoài ra, tôi đã thử nghiệm điều này trên 9,0: có vẻ như với tôi nó cũng hoạt động trên một số phiên bản cũ hơn, hãy báo trước emptor.

+0

Chỉ cần thử nghiệm điều này. Có vẻ như nó đang hoạt động. Cảm ơn bạn rât nhiêu. – Kai

+0

Ok, nó đã phá vỡ một cái gì đó :) pg_dump và pg_dumpall không hoạt động nữa. Lỗi là "Thông báo lỗi từ máy chủ: L ERI: cột" tableoid "không tồn tại" Lệnh này là: SELECT tableoid, oid, (SELECT rolname FROM pg_catalog.pg_roles WHERE oid = datdba) AS dba, pg_encoding_to_char (mã hóa) AS mã hóa, datcollate, datctype, datfrozenxid, (CHỌN spcname TỪ pg_tablespace t WHERE t.oid = dattablespace) AS vùng bảng, shobj_description (oid, 'pg_database') AS mô tả TỪ pg_database WHERE datname = 'test_1' – Kai

+0

Sẽ thật sự tuyệt vời nếu bạn có thể giúp tôi để khắc phục điều này, bởi vì ngoài việc này, giải pháp của bạn hoạt động rất tốt. – Kai

1

Không có cài đặt như vậy trong pgsql. Có các cài đặt để ngăn người dùng kết nối với cơ sở dữ liệu mà họ không nên (cấp/thu hồi kết nối). Có thể thấy có một cơ sở dữ liệu không phải là vấn đề lớn. Có thể kết nối/có quyền chỉnh sửa, v.v.

+0

Vâng, đó là một điều xấu nếu bạn có người chạy phần mềm giao diện người dùng trên cơ sở dữ liệu này, trong khi cấu hình, nhận danh sách tất cả cơ sở dữ liệu có sẵn và nhắc người dùng về cơ sở dữ liệu mà anh ấy không có quyền truy cập. Vấn đề là tôi không thể thay đổi hành vi đó và phải đối phó với nó theo một cách nào đó. – Kai

+5

Tùy thuộc vào bối cảnh ong có thể thấy cơ sở dữ liệu khác _is_ một việc lớn. Nó là một rò rỉ dữ liệu. Tôi không thấy lý do tại sao người dùng nên thấy cơ sở dữ liệu mà anh ta không có doanh nghiệp. – harmv

+0

Tuyên bố không nhất thiết làm cho đối số của bạn chính xác. Nếu người dùng không thể truy cập vào db thì thấy nó không phải là vấn đề lớn. Dữ liệu không bị rò rỉ. Dữ liệu là những gì bạn lưu trữ trong một db, không phải là tên của db. Nếu những gì bạn cần là để người dùng không biết những cơ sở dữ liệu nào khác trên một hệ thống thì bạn cần thiết lập một cụm cho mỗi người dùng để họ có cụm db riêng của họ để đăng nhập. –

1

Tôi tưởng tượng điều này có thể có hậu quả tiêu cực đối với người dùng, chẳng hạn như không thể kết nối với cơ sở dữ liệu vì hệ thống không có quyền truy cập vào bảng sytem, ​​không chắc chắn. Nhưng theo như tìm hiểu bảng nào cần thu hồi - đây là cách tổng quát tốt để xem lệnh meta psql đang làm gì:

Để xem những gì \l đang làm bạn cũng có thể sử dụng cờ -E từ dòng lệnh với 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; 
************************** 

Vì vậy, nếu người dùng không có quyền truy cập vào pg_database, họ sẽ không thể sử dụng lệnh \ l.

Các vấn đề liên quan