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


12

Il y a quelques temps, j'ai créé un utilisateur PostgreSQL nommé user1 (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 user1n'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 veux pas supprimer les objets appartenant à user1, je veux juste réaffecter ou supprimer des subventions pour cet utilisateur.

Réponses:


11

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)

Il ne s'agit pas de propriété mais de privilèges .

Le manuel pour 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 OWNEDBY pour supprimer l'entrée de privilèges par défaut pour le rôle .

Il semble également que vous n'ayez exécuté que REASSIGN OWNEDdans une seule base de données, mais le manuel indique:

Étant donné que REASSIGN OWNEDcela 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 contenant des objets appartenant à un rôle à supprimer.

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 postgresavec la première commande et sont désormais en sécurité. Le libellé de DROP OWNEDest un peu trompeur, car il supprime également tous les privilèges et privilèges par défaut. Le manuel pour DROP OWNED:

DROP OWNEDsupprime 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;

6

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

Je ne trouve toujours pas l'objet manquant avec ça.
Nicolas Payart

@NicolasPayart: exécutez-vous la requête dans la bonne base de données?
Erwin Brandstetter

1

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
Hé, merci pour votre première réponse. Cependant, avant de publier, pensez à ce que cela ajoute aux réponses existantes et décrivez-le également dans votre réponse.
dezso
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.