web-dev-qa-db-fra.com

Rechercher des objets liés à un rôle PostgreSQL

Il y a quelques temps, j'ai créé un utilisateur PostgreSQL nommé ser1 (PostgreSQL 9.4.9).

Je souhaite supprimer cet utilisateur. J'ai donc d'abord révoqué toutes les autorisations sur les tables, les séquences, les fonctions, les privilèges par défaut et la propriété:

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;

Cependant il semble qu'un objet reste lié à cet utilisateur dans 2 bases de données:

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

Cela semble même être une fonction:

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

Mais je ne peux pas déterminer quel objet appartient ou est lié à user1.

Si je pg_dump -s db1 | grep user1 Je n'obtiens aucun résultat! Serait-ce un objet global?

Comment identifier l'objet manquant?

J'ai exécuté les commandes dans chaque base de données (db1 et db2). Je ne souhaite pas supprimer d'objets appartenant à user1, je souhaite simplement réaffecter ou supprimer des autorisations pour cet utilisateur.

12
Nicolas Payart

Réponse à la question posée

Pour rechercher la fonction dans le message d'erreur et son propriétaire:

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

En relation:

Problème réel

Le message d'erreur dit:

DÉTAIL: privilèges pour le texte de fonction (booléen)

C'est pas sur la propriété mais sur privilèges.

Le manuel de DROP ROLE:

Avant de supprimer le rôle, vous devez supprimer tous les objets qu'il possède (ou réaffecter leur propriété) et révoquer tous les privilèges accordés au rôle sur d'autres objets .

Et pour ALTER DEFAULT PRIVILEGES:

Si vous souhaitez supprimer un rôle pour lequel les privilèges par défaut ont été modifiés, il est nécessaire d'annuler les modifications de ses privilèges par défaut ou d'utiliser DROP OWNED BY pour se débarrasser de l'entrée de privilèges par défaut pour le rôle .

Il semble également que vous n'ayez exécuté que REASSIGN OWNED dans une DB, mais le manuel indique:

Parce que REASSIGN OWNED n'affecte pas les objets dans d'autres bases de données, il est généralement nécessaire d'exécuter cette commande dans chaque base de données qui contient des objets appartenant à un rôle qui doit être supprimé.

Accentuation sur moi.

Et vous avez limité vos commandes avec IN SCHEMA public. Supprimez cette clause pour cibler l'ensemble de la base de données. Mais ne vous embêtez pas, il y a un ...

Solution simple avec DROP OWNED

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

Tous les objets du rôle ont changé de propriétaire en postgres avec la première commande et sont désormais en sécurité. Le libellé de DROP OWNED est un peu trompeur, car il supprime également tous les privilèges et privilèges par défaut. Le manuel de DROP OWNED:

DROP OWNED supprime tous les objets de la base de données actuelle appartenant à l'un des rôles spécifiés. Tous les privilèges accordés aux rôles donnés sur les objets de la base de données actuelle et sur les objets partagés (bases de données, espaces disque logiques) seront également révoqués.

Répétez dans toutes les bases de données pertinentes, puis vous pouvez vous déplacer pour la mise à mort:

DROP ROLE user1;
11
Erwin Brandstetter

La requête ci-dessous répertorie les objets avec des propriétaires. Pour tous les privilèges, nous avons réellement besoin de plus.

--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
6
Sahap Asci

Vous devez d'abord vous connecter à la base de données. Dans votre cas, ce serait

\c db1

et

\c db2

Essayez ensuite d'exécuter à nouveau les instructions REVOKE ALL PRIVILEGES et REASSIGN OWNED/DROP OWNED.

1
Samuel Anyaele