FEHLER: Berechtigung für Sequenz city_id_seq mit Postgres verweigert

201

Ich bin neu bei postgres (und insgesamt bei Datenbankinformationssystemen). Ich habe folgendes SQL-Skript in meiner Datenbank ausgeführt:

create table cities (
id serial primary key,
name text not null
);

create table reports (
id serial primary key,
cityid integer not null references cities(id),
reportdate date not null,
reporttext text not null
);

create user www with password 'www';

grant select on cities to www;
grant insert on cities to www;
grant delete on cities to www;

grant select on reports to www;
grant insert on reports to www;
grant delete on reports to www;

grant select on cities_id_seq to www;
grant insert on cities_id_seq to www;
grant delete on cities_id_seq to www;

grant select on reports_id_seq to www;
grant insert on reports_id_seq to www;
grant delete on reports_id_seq to www;

Wenn der Benutzer www versucht:

insert into cities (name) values ('London');

Ich erhalte folgende Fehlermeldung:

ERROR: permission denied for sequence cities_id_seq

Ich verstehe, dass das Problem beim seriellen Typ liegt. Aus diesem Grund erteile ich www Auswahl-, Einfüge- und Löschrechte für die * _id_seq. Dies behebt jedoch nicht mein Problem. Was vermisse ich?

Vampnik
quelle
2
Das Einfügen / Löschen einer Sequenz ist für mich nicht sinnvoll. Ich bin überrascht, dass es sogar funktioniert.
a_horse_with_no_name

Antworten:

359

Seit PostgreSQL 8.2 müssen Sie Folgendes verwenden:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;

GRANT USAGE - Für Sequenzen ermöglicht dieses Privileg die Verwendung der Funktionen currval und nextval.

Wie von @epic_fil in den Kommentaren hervorgehoben, können Sie allen Sequenzen im Schema Berechtigungen erteilen mit:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
Kupson
quelle
52
Zu Ihrer Information wird auch die Syntax "... AUF ALLEN SEQUENZEN IN SCHEMA schema_name" unterstützt.
epic_fil
5
Interessant. Ich habe ein GRANT auf dem Tisch gemacht, in dem sich meine Sequenz befindet, aber dies scheint die Sequenz nicht abzudecken. Dies scheint auch sehr von OS.
Kinnard Hockenhull
41
Wie ist das eine echte Sache? Wann möchte ich einem Benutzer jemals erlauben, Daten in eine Tabelle einzufügen, aber NICHT zulassen, dass er die Tatsache nutzt, dass eine der Spalten automatisch inkrementiert wird?
Brett Widmeier
5
IST SELECTnotwendig? Sollte nicht USAGEabgedeckt werden, was benötigt wird?
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ
6
@BrettWidmeier Genau. Es ist für mich verblüffend, wie so etwas von den Entwicklern toleriert wird. Es ist, als wollten die Leute im Internet herumlaufen und bodenlose StackOverflow-Threads lesen, um Dinge zu reparieren, die sofort hätten funktionieren sollen.
Milosmns
67

Da @Phil einen Kommentar hat, der viele Upvotes enthält, die möglicherweise nicht bemerkt werden, verwende ich seine Syntax, um eine Antwort hinzuzufügen, die einem Benutzer Berechtigungen für alle Sequenzen in einem Schema gewährt (vorausgesetzt, Ihr Schema ist die Standardeinstellung "public"). )

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to www;
Tom Gerken
quelle
2
Beachten Sie, dass dies nur in PostgreSQL 9.0 und höher funktioniert. Um dasselbe in 8 zu erreichen, können Sie Folgendes tun: SELECT 'GRANT USAGE, SELECT ON' || quote_ident (schemaname) || '.' || quote_ident (relname) || 'TO www;' FROM pg_statio_all_sequences WHERE schemaname = 'public'; - Tom Gerken vor 2 Tagen
Tom Gerken
39

@Tom_Gerken, @epic_fil und @kupson sind mit ihren Anweisungen, die Berechtigungen zum Arbeiten mit vorhandenen Sequenzen zu erteilen, völlig korrekt. Der Benutzer erhält jedoch KEINE Zugriffsrechte auf in Zukunft erstellte Sequenzen. Dazu müssen Sie die Anweisung GRANT mit einer Anweisung ALTER DEFAULT PRIVILEGES wie folgt kombinieren:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE, SELECT ON SEQUENCES TO www;

Dies funktioniert natürlich nur unter PostgreSQL 9+.

Dadurch werden vorhandene Standardberechtigungen angehängt und nicht überschrieben. Dies ist in dieser Hinsicht recht sicher.

Asfand Qazi
quelle
-2

Führen Sie den folgenden Befehl in postgres aus.

Anmeldung bei postgres:

sudo su postgres;

psql dbname;

SEQUENZ ERSTELLEN public.cities_id_seq INCREMENT 1
MINVALUE 0
MAXVALUE 1
START 1 CACHE 1; ALTER TABLE public.cities_id_seq BESITZER VON pgowner;

pgowner wird Ihr Datenbankbenutzer sein.

Shreeram
quelle