web-dev-qa-db-fra.com

GRANT USAGE sur tous les schémas d'une base de données?

Je veux GRANT USAGE à un utilisateur/rôle pour une base de données donnée. La base de données comporte de nombreux schémas.

Je sais qu'il y a un ON ALL TABLES IN SCHEMA, mais je veux "tous les schémas". J'ai essayé GRANT USAGE .. ON DATABASE, mais c'est évidemment faux (il n'existe pas réellement ).

C'est pour Postgres 9.3 ou 9.4, il se trouve que c'est un serveur qui est sur AWS RDS.

13
tedder42

Vous avez au moins deux options.

La première utilise une petite requête et un éditeur de texte. Nous devons collecter les schémas de notre intérêt:

SELECT nspname
  FROM pg_namespace;

Vous pouvez ajouter une clause WHERE si vous souhaitez limiter la portée. Copiez la sortie et modifiez-la pour obtenir un certain nombre de commandes GRANT USAGE ON SCHEMA ... TO your_role;. Ensuite, alimentez-le simplement dans psql, par exemple:

psql -f multigrant.sql

Une variante habituelle pourrait être un script Shell qui boucle sur les noms collectés et appelle psql, en passant l'instruction GRANT construite à l'option -c.

L'autre solution fait essentiellement la même chose dans un bloc pl/pgsql, créant une requête dynamique. Le noyau est le même - nous devons collecter les schémas. Ensuite, nous les parcourons tous, en accordant les autorisations schéma par schéma:

DO $do$
DECLARE
    sch text;
BEGIN
    FOR sch IN SELECT nspname FROM pg_namespace
    LOOP
        EXECUTE format($$ GRANT USAGE ON SCHEMA %I TO your_role $$, sch);
    END LOOP;
END;
$do$;

Remarques :

  • contrairement aux tableaux, séquences, fonctions et types, on ne peut pas définir privilèges par défaut pour les schémas (à partir de 9.4). Vous devrez accorder ce privilège pour tout schéma nouvellement ajouté manuellement.
  • ici j'utilise dollar quoting lors de la construction de la requête dynamique. Cela me permet d'utiliser la syntaxe "normale", par opposition à la multiplication de guillemets simples, par exemple (non présente dans cet exemple). De cette façon, la plupart des éditeurs mettront en valeur les déclarations.
  • J'utilise également format() avec le spécificateur de format %I Pour avoir le nom d'objet correctement cité si nécessaire. Cette approche est beaucoup plus lisible que la construction de la requête avec concaténation de constantes de chaîne et de certains appels quote_ident().
  • pg_namespace Se trouve dans le schéma pg_catalog . Découvrez les autres objets qui s'y trouvent - ils stockent tous les aspects de vos schémas, tableaux, etc.
18
dezso

Vous pouvez également utiliser.

DO $do$
DECLARE
    sch text;
BEGIN
    FOR sch IN SELECT nspname FROM pg_namespace where nspname != 'pg_toast' 
    and nspname != 'pg_temp_1' and nspname != 'pg_toast_temp_1'
    and nspname != 'pg_statistic' and nspname != 'pg_catalog'
    and nspname != 'information_schema'
    LOOP
        EXECUTE format($$ GRANT USAGE ON SCHEMA %I TO your_role $$, sch);
        EXECUTE format($$ GRANT USAGE ON SCHEMA %I to your_role $$, sch);
        EXECUTE format($$ GRANT SELECT ON ALL SEQUENCES IN SCHEMA %I TO your_role $$, sch);
        EXECUTE format($$ GRANT SELECT ON ALL TABLES IN SCHEMA %I TO backup_user $$, sch);

        EXECUTE format($$ ALTER DEFAULT PRIVILEGES IN SCHEMA %I GRANT SELECT ON TABLES TO your_role $$, sch);
        EXECUTE format($$ ALTER DEFAULT PRIVILEGES IN SCHEMA %I GRANT SELECT ON SEQUENCES TO your_role $$, sch);
    END LOOP;
END;
$do$;
0
Mateus Padua