Temukan objek yang ditautkan ke peran PostgreSQL

12

Beberapa waktu lalu saya membuat pengguna PostgreSQL bernama user1 (PostgreSQL 9.4.9).

Saya ingin menjatuhkan pengguna ini. Jadi saya pertama-tama mencabut semua izin pada tabel, urutan, fungsi, hak istimewa default, dan kepemilikan juga:

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;

Namun tampaknya satu objek tetap tertaut ke pengguna ini dalam 2 basis data:

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

Bahkan tampaknya menjadi fungsi:

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

Tapi saya tidak bisa menentukan objek mana yang dimiliki atau terkait dengan user1.

Jika saya pg_dump -s db1 | grep user1tidak mendapat hasil! Mungkinkah itu menjadi objek global?

Bagaimana saya bisa mengidentifikasi objek yang hilang?

Saya telah menjalankan perintah di setiap basis data (db1 dan db2). Saya tidak ingin menjatuhkan objek yang dimiliki oleh user1, hanya ingin menetapkan kembali atau menghapus hibah untuk pengguna ini.

Nicolas Payart
sumber

Jawaban:

11

Jawaban atas pertanyaan yang diajukan

Untuk mencari fungsi dalam pesan kesalahan dan pemiliknya:

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

Terkait:

Masalah aktual

Pesan kesalahan mengatakan:

DETAIL: hak istimewa untuk teks fungsi (boolean)

Ini bukan tentang kepemilikan tetapi tentang hak istimewa .

Manual untuk DROP ROLE:

Sebelum menjatuhkan peran, Anda harus membuang semua objek yang dimilikinya (atau menetapkan kembali kepemilikannya) dan mencabut hak istimewa apa pun yang telah diberikan peran pada objek lain .

Dan untuk ALTER DEFAULT PRIVILEGES:

Jika Anda ingin menjatuhkan peran yang telah diubah hak-hak istimewanya, Anda perlu membalikkan perubahan dalam hak-hak istimewanya atau menggunakan DROP OWNEDOLEH untuk menyingkirkan entri hak-hak istimewa default untuk peran tersebut .

Sepertinya Anda hanya dieksekusi REASSIGN OWNEDdalam satu DB, tetapi manual menginstruksikan:

Karena REASSIGN OWNEDtidak mempengaruhi objek dalam database lain, biasanya perlu untuk mengeksekusi perintah ini di setiap database yang berisi objek yang dimiliki oleh peran yang akan dihapus.

Penekanan berani saya.

Dan Anda membatasi perintah Anda dengan IN SCHEMA public. Jatuhkan klausa itu untuk menargetkan seluruh DB. Tapi jangan repot-repot, ada ...

Solusi sederhana dengan DROP OWNED

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

Semua objek peran berubah kepemilikan postgresdengan perintah pertama dan aman sekarang. Kata-katanya DROP OWNEDsedikit menyesatkan, karena ia juga menghilangkan semua hak istimewa dan hak default. Manual untuk DROP OWNED:

DROP OWNEDmenjatuhkan semua objek dalam database saat ini yang dimiliki oleh salah satu peran yang ditentukan. Setiap hak istimewa yang diberikan kepada peran yang diberikan pada objek dalam database saat ini dan pada objek bersama (database, tablespace) juga akan dicabut.

Ulangi di semua DB yang relevan, lalu Anda bisa pindah untuk membunuh:

DROP ROLE user1;
Erwin Brandstetter
sumber
6

Kueri di bawah ini mencantumkan objek dengan pemilik. Untuk semua hak istimewa, kita sebenarnya membutuhkan lebih banyak.

--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
Sahap Asci
sumber
Saya masih tidak menemukan objek yang hilang dengan ini.
Nicolas Payart
@NicolasPayart: Apakah Anda menjalankan kueri di database yang benar?
Erwin Brandstetter
1

Anda harus terlebih dahulu terhubung ke database. Dalam contoh Anda itu akan menjadi

\c db1

dan

\c db2

Kemudian coba jalankan REVOKE SEMUA HAK ISTIMEWA dan REASSIGN OWNED / DROP pernyataan MILIK lagi.

Samuel Anyaele
sumber
1
Hei, terima kasih atas jawaban pertamamu. Namun, sebelum memposting, harap pikirkan tentang apa yang ditambahkan ke jawaban yang ada, dan jelaskan juga dalam jawaban Anda.
dezso