GRANT USAGE für alle Schemata in einer Datenbank?

12

Ich möchte GRANT USAGEeinen Benutzer / eine Rolle für eine bestimmte Datenbank. Die Datenbank hat viele Schemata.

Ich weiß, dass es eine gibt ON ALL TABLES IN SCHEMA, aber ich möchte "alle Schemata". Ich habe es versucht GRANT USAGE .. ON DATABASE, aber das ist offensichtlich falsch (es gibt es eigentlich nicht ).

Dies ist für Postgres 9.3 oder 9.4 ein Server, der sich in AWS RDS befindet.

tedder42
quelle

Antworten:

17

Sie haben mindestens zwei Möglichkeiten.

Die erste verwendet eine kleine Abfrage und einen Texteditor. Wir müssen die Schemata unseres Interesses sammeln:

SELECT nspname
  FROM pg_namespace;

Sie können eine WHEREKlausel hinzufügen , wenn Sie den Bereich einschränken möchten. Kopieren Sie die Ausgabe und ändern Sie sie, sodass Sie eine Reihe von GRANT USAGE ON SCHEMA ... TO your_role;Befehlen erhalten. Dann füttere es einfach psql, zum Beispiel:

psql -f multigrant.sql

Eine übliche Variante davon könnte ein Shell-Skript sein, das die gesammelten Namen und Aufrufe psqldurchläuft und die konstruierte GRANTAnweisung an die -cOption übergibt .

Die andere Lösung macht im Prinzip dasselbe in einem pl / pgsql-Block und erstellt eine dynamische Abfrage. Der Kern ist derselbe - wir müssen die Schemata sammeln. Dann durchlaufen wir alle und erteilen die Berechtigungen Schema für Schema:

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

Anmerkungen :

  • Im Gegensatz zu Tabellen, Sequenzen, Funktionen und Typen können für Schemata (ab 9.4) keine Standardberechtigungen festgelegt werden . Sie müssen dieses Privileg für jedes neu hinzugefügte Schema manuell erteilen.
  • hier benutze ich Dollar-Anführungszeichen beim Erstellen der dynamischen Abfrage. Dies ermöglicht mir die Verwendung der 'normalen' Syntax im Gegensatz zur Multiplikation von beispielsweise einfachen Anführungszeichen (in diesem Beispiel nicht vorhanden). Auf diese Weise werden die meisten Redakteure die Aussagen gut hervorheben.
  • Ich benutze auch format()mit dem%I Formatbezeichner, um den Objektnamen bei Bedarf korrekt in Anführungszeichen zu setzen. Dieser Ansatz ist weitaus lesbarer als das Erstellen der Abfrage mit Verkettung von Zeichenfolgenkonstanten und einigen quote_ident()Aufrufen.
  • pg_namespacefinden Sie im pg_catalogSchema. Schauen Sie sich die anderen Objekte dort an - sie speichern jeden Aspekt Ihrer Schemas, Tabellen usw.
dezso
quelle
1
Ich frage mich, ob Sie Standardberechtigungen für neu erstellte Schemas mithilfe eines Ereignisauslösers simulieren können, der die grant usagefür das neue Schema automatisch ausführt.
a_horse_with_no_name
@a_horse_with_no_name wenn ich darüber nachdenke, sehe ich derzeit keinen Grund, warum es nicht möglich war.
Dezso
0

Sie können auch verwenden.

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$;
Mateus Padua
quelle