Tìm các đối tượng được liên kết với vai trò PostgreSQL


12

Cách đây một vài lần, tôi đã tạo một người dùng PostgreSQL có tên user1 (PostgreQuery 9.4.9).

Tôi muốn bỏ người dùng này. Vì vậy, trước tiên tôi thu hồi tất cả các quyền trên bảng, trình tự, hàm, đặc quyền mặc định và quyền sở hữu:

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM user1;

REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM user1;

REASSIGN OWNED BY user1 TO postgres;

Tuy nhiên, dường như một đối tượng vẫn được liên kết với người dùng này trong 2 cơ sở dữ liệu:

postgres=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  1 object in database db1
1 object in database db2

Nó thậm chí có vẻ là một chức năng:

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for function text(boolean)
1 object in database db2

Nhưng tôi không thể xác định đối tượng nào được sở hữu hoặc liên quan đến user1.

Nếu tôi pg_dump -s db1 | grep user1không nhận được kết quả! Nó có thể là một đối tượng toàn cầu?

Làm thế nào tôi có thể xác định các đối tượng mất tích?

Tôi đã thực hiện các lệnh trong mỗi cơ sở dữ liệu (db1 và db2). Tôi không muốn bỏ các đối tượng thuộc sở hữu của user1, chỉ muốn gán lại hoặc xóa trợ cấp cho người dùng này.

Câu trả lời:


11

Trả lời câu hỏi

Để tìm chức năng trong thông báo lỗi và chủ sở hữu của nó:

SELECT oid::regprocedure AS function
     , pg_get_userbyid(proowner) AS owner
FROM   pg_proc
WHERE  oid = 'text(boolean)'::regprocedure;

Liên quan:

Vấn đề thực tế

Thông báo lỗi cho biết:

CHI TIẾT: đặc quyền cho văn bản hàm (boolean)

Đó không phải là về quyền sở hữu mà là về đặc quyền .

Hướng dẫn cho DROP ROLE:

Trước khi bỏ vai trò, bạn phải loại bỏ tất cả các đối tượng mà nó sở hữu (hoặc gán lại quyền sở hữu của chúng) và thu hồi bất kỳ đặc quyền nào mà vai trò đã được cấp cho các đối tượng khác .

Và cho ALTER DEFAULT PRIVILEGES:

Nếu bạn muốn loại bỏ một vai trò mà các đặc quyền mặc định đã bị thay đổi, cần phải đảo ngược các thay đổi trong các đặc quyền mặc định của nó hoặc sử dụng DROP OWNEDBY để loại bỏ mục đặc quyền mặc định cho vai trò đó .

Có vẻ như bạn chỉ thực hiện REASSIGN OWNEDtrong một DB, nhưng hướng dẫn sử dụng:

Do REASSIGN OWNEDkhông ảnh hưởng đến các đối tượng trong các cơ sở dữ liệu khác, nên thường phải thực thi lệnh này trong mỗi cơ sở dữ liệu có chứa các đối tượng thuộc sở hữu của một vai trò sẽ bị xóa.

Nhấn mạnh đậm của tôi.

Và bạn đã hạn chế các lệnh của bạn với IN SCHEMA public. Bỏ mệnh đề đó để nhắm mục tiêu toàn bộ DB. Nhưng đừng bận tâm, có một ...

Giải pháp đơn giản với DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;

Tất cả các đối tượng của vai trò đã thay đổi quyền sở hữu thành postgresvới lệnh đầu tiên và hiện đã an toàn. Từ ngữ của DROP OWNEDmột chút sai lệch, vì nó cũng được loại bỏ tất cả các đặc quyền và đặc quyền mặc định. Hướng dẫn cho DROP OWNED:

DROP OWNEDloại bỏ tất cả các đối tượng trong cơ sở dữ liệu hiện tại được sở hữu bởi một trong các vai trò được chỉ định. Bất kỳ đặc quyền nào được cấp cho các vai trò nhất định trên các đối tượng trong cơ sở dữ liệu hiện tại và trên các đối tượng được chia sẻ (cơ sở dữ liệu, không gian bảng) cũng sẽ bị thu hồi.

Lặp lại trong tất cả các DB có liên quan, sau đó bạn có thể chuyển sang tiêu diệt:

DROP ROLE user1;

6

Các truy vấn dưới đây liệt kê các đối tượng với chủ sở hữu. Đối với tất cả các đặc quyền chúng tôi thực sự cần nhiều hơn.

--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT 
    n.nspname AS schema_name,
    c.relname AS rel_name,
    c.relkind AS rel_kind,
    pg_get_userbyid(c.relowner) AS owner_name
  FROM pg_class c
  JOIN pg_namespace n ON n.oid = c.relnamespace

UNION ALL

-- functions (or procedures)
SELECT
    n.nspname AS schema_name,
    p.proname,
    'p',
    pg_get_userbyid(p.proowner)
  FROM pg_proc p
  JOIN pg_namespace n ON n.oid = p.pronamespace

Tôi vẫn không tìm thấy đối tượng mất tích với điều này.
Nicolas Payart

@NicolasPayart: Bạn đang thực hiện truy vấn trong cơ sở dữ liệu phù hợp?
Erwin Brandstetter

1

Trước tiên bạn cần kết nối với cơ sở dữ liệu. Trong trường hợp của bạn đó sẽ là

\c db1

\c db2

Sau đó, hãy thử chạy lại các câu lệnh REVOKE ALL PRIVILEGES và REASSIGN OWNED / DROP OWNED.


1
Hey, cảm ơn câu trả lời đầu tiên của bạn Tuy nhiên, trước khi đăng, xin vui lòng suy nghĩ về những gì nó thêm vào câu trả lời hiện có, và mô tả điều này trong câu trả lời của bạn, quá.
dezso
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.