PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Supprimer un rôle avec des privilèges

Exécutez ceci dans chaque base de données du même cluster où le rôle peut posséder quoi que ce soit ou avoir des privilèges accordés :

REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;

postgres étant le superutilisateur par défaut, vous pouvez en choisir un autre. Il va posséder des objets actuellement détenus par l'ancien rôle. Immédiatement après REASSIGN OWNED , il n'y a plus d'objets qui seraient possédés par le même utilisateur. Il peut sembler peu intuitif d'exécuter DROP OWNED . Le libellé de la commande est trompeur, car il également révoque tous les privilèges et privilèges par défaut pour le rôle dans la même base de données. Le manuel :

Bold accent mine.
Vous devez toujours l'exécuter dans chaque base de données où le rôle possède quoi que ce soit ou dispose de privilèges accordés. Le manuel :

Enfin, lancez (une fois) :

DROP role some_role_name;

Les rôles sont stockés dans un catalogue système à l'échelle du cluster, tandis que la propriété et les privilèges sur les objets sont stockés dans des catalogues système locaux de base de données.

Explication détaillée dans cette réponse connexe :

Il y a une page connexe dans le manuel avec des instructions .

Automatisation complète

Il n'y a pas de commande unique pour tout faire. Mais vous pouvez laisser Postgres générer un script psql complet pour vous.

Les dépendances des rôles sont stockées dans le catalogue système pg_shdepend :

Puisque nous avons (potentiellement) besoin de nous connecter à différentes bases de données, nous avons besoin d'une combinaison de méta-commandes psql (\c my_database ) et les commandes SQL DDL comme indiqué ci-dessus. Créez une fois cette fonction quelque part dans votre cluster de bases de données :

CREATE OR REPLACE FUNCTION f_generate_ddl_to_remove_role(dead_role_walking regrole)
  RETURNS text
  LANGUAGE sql AS
$func$
SELECT concat_ws(
   E'\n'
 ,(SELECT string_agg(format(E'\\c %I\nREASSIGN OWNED BY %2$s TO postgres; DROP OWNED BY %2$s;'
                          , d.datname, dead_role_walking)
                   , E'\n')
   FROM  (
      SELECT DISTINCT dbid
      FROM   pg_shdepend
      WHERE  refobjid = dead_role_walking
      ) s
   JOIN   pg_database d ON d.oid = s.dbid)
 , format(E'DROP role %s;\n', dead_role_walking)
   )
$func$;

Appel :

SELECT f_generate_ddl_to_remove_role('some_role_name');

Produit une chaîne comme :

\c my_db1
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
\c my_db2
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
DROP role some_role_name;

Ou, si le rôle ne possède rien et n'a aucun privilège, simplement :

DROP role some_role_name;

Si vous fournissez un nom de rôle inexistant, vous obtenez une erreur.

Copiez la chaîne (sans guillemets simples) dans une session psql ouverte avec un super-utilisateur comme postgres . Ou concaténez un script bash avec. Tout est fait.

Il existe plusieurs réponses associées avec plus d'explications sur le SQL dynamique :