Trova oggetti collegati a un ruolo PostgreSQL


12

Alcune volte fa ho creato un utente PostgreSQL chiamato user1 (PostgreSQL 9.4.9).

Voglio eliminare questo utente. Quindi prima revoco tutte le autorizzazioni su tabelle, sequenze, funzioni, privilegi e proprietà predefiniti:

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;

Tuttavia sembra che un oggetto rimanga collegato a questo utente in 2 database:

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

Sembra anche essere una funzione:

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

Ma non riesco a determinare quale oggetto è di proprietà o correlato a user1.

Se non pg_dump -s db1 | grep user1ottengo alcun risultato! Potrebbe essere un oggetto globale?

Come posso identificare l'oggetto mancante?

Ho eseguito i comandi in ciascun database (db1 e db2). Non voglio rilasciare oggetti di proprietà user1, voglio solo riassegnare o rimuovere le sovvenzioni per questo utente.

Risposte:


11

Risposta alla domanda posta

Per cercare la funzione nel messaggio di errore e il suo proprietario:

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

Relazionato:

Problema reale

Il messaggio di errore dice:

DETTAGLIO: privilegi per il testo della funzione (booleano)

Non si tratta di proprietà ma di privilegi .

Il manuale per DROP ROLE:

Prima di abbandonare il ruolo, è necessario eliminare tutti gli oggetti di proprietà (o riassegnarne la proprietà) e revocare tutti i privilegi che il ruolo è stato concesso su altri oggetti .

E per ALTER DEFAULT PRIVILEGES:

Se si desidera eliminare un ruolo per il quale sono stati modificati i privilegi predefiniti, è necessario annullare le modifiche ai privilegi predefiniti o utilizzare DROP OWNEDBY per eliminare la voce privilegi predefiniti per il ruolo .

Sembra anche che tu sia eseguito REASSIGN OWNEDin un solo DB, ma il manuale indica:

Poiché REASSIGN OWNEDnon influisce sugli oggetti all'interno di altri database, in genere è necessario eseguire questo comando in ciascun database che contiene oggetti di proprietà di un ruolo che deve essere rimosso.

Enorme enfasi sulla mia.

E hai limitato i tuoi comandi con IN SCHEMA public. Eliminare quella clausola per indirizzare l'intero DB. Ma non preoccuparti, c'è un ...

Soluzione semplice con DROP OWNED

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

Tutti gli oggetti del ruolo hanno cambiato proprietà postgrescon il primo comando e ora sono al sicuro. La formulazione di DROP OWNEDè un po 'fuorviante, poiché elimina anche tutti i privilegi e i privilegi predefiniti. Il manuale per DROP OWNED:

DROP OWNEDelimina tutti gli oggetti nel database corrente che appartengono a uno dei ruoli specificati. Verranno inoltre revocati tutti i privilegi concessi a determinati ruoli sugli oggetti nel database corrente e sugli oggetti condivisi (database, tablespace).

Ripeti in tutti i DB rilevanti, quindi puoi spostarti per l'uccisione:

DROP ROLE user1;

6

La query seguente elenca gli oggetti con i proprietari. Per tutti i privilegi abbiamo effettivamente bisogno di più.

--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

Non trovo ancora l'oggetto mancante con questo.
Nicolas Payart,

@NicolasPayart: stai eseguendo la query nel database giusto?
Erwin Brandstetter,

1

Devi prima connetterti al database. Nel tuo caso sarebbe

\c db1

e

\c db2

Quindi provare a eseguire di nuovo le istruzioni REVOKE ALL PRIVILEGES e REASSIGN OWNED / DROP OWNED.


1
Ehi, grazie per la tua prima risposta. Tuttavia, prima di pubblicare, ti preghiamo di pensare a cosa si aggiunge alle risposte esistenti e descriverlo anche nella tua risposta.
dezso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.