read only User erstellen

Hallo,

ich bin ein Einsteiger in PostgreSQL und hänge etwas in der Luft.

Vorab:
Postgre 9.2.2 x64 unter Debian 6

Ich habe eine bestehende Datenbank mit 750 Tabellen.
Für die Datenbank mit den Tabellen möchte ich einen Benutzer anlegen, der sich lediglich anmelden und select ausführen darf.
Also ein klassischer ready only User.

Hier meine Vorgehensweise:
Ich erstelle eine Rolle und weise dieser Rechte zu:
CREATE ROLE read_only;
GRANT CONNECT on DATABASE db01 to read_only;
GRANT USAGE on SCHEMA db01 to read_only;
GRANT SELECT on all tables in SCHEMA db01 to read_only;

Ich erstelle einen Benutzer und packe diesen in die Rolle.
create user raffnix LOGIN password ‘1234’;
grant read_only to raffnix;

Der User raffnix kann sich anmelden, sieht die Tabellen, kann aber keine Inhalte selectieren … relation “tabelle” does not exist.

Wo habe ich einen Denkfehler? Was muss ich anders mache?

Gruß
raffnix

Ich hab es ähnlich gemacht und es geht.

session1:

test=# create role read_only;
CREATE ROLE
Time: 0,131 ms
test=*# grant usage on schema public to read_only;
GRANT
Time: 0,192 ms
test=*# grant select on all tables in schema public to read_only;
GRANT
Time: 24,763 ms
test=*# create user raffnix in role read_only;
CREATE ROLE
Time: 0,173 ms
test=*# commit;
COMMIT

dann session2:

kretschmer@tux:~$ psql -U raffnix test
Timing is on.
psql (9.2.0)
Type "help" for help.

test=> select * from foo;
 c1 | c2 | c3 | c4
----+----+----+----
  1 |  2 |  3 |  4
  1 |  2 |  3 |  1
(2 rows)

Time: 0,623 ms
test=*> delete from foo;
ERROR:  permission denied for relation foo
Time: 0,244 ms

Deine Fehlermeldung hat, denke ich mal, nix mit Rechten zu tun, sondern daß der die Tabelle “tabelle” nicht findet. Vielleicht meinst Du ja “Tabelle” oder “tABELLE” oder “tAbElLe” …

Andreas

Hallo Andreas,
danke für Deine schnelle Antwort.

Nein, leider nicht.

Der Benutzer sieht alle Tabellen:

 select table_name from information_schema.tables where table_schema = 'db01';

Aber ein

 select * from tab01 limit 10

scheitert mit:

ERROR:  relation "tab01" does not exist
LINE 1: select * from mitarb limit 10;ERROR:  relation "tab01" does not exist
LINE 1: select * from tab01 limit 10;

Gruß
Steffen

Nochmals: die Fehlermeldung besagt, daß es eine Tabelle mit dem Namen “tab01” nicht gibt. Vielleicht gibt es ja “Tab01” oder “tAB01”.

Was sagt ein

select table_name from information_schema.tables where table_schema = 'db01' and table_name = 'tab01';

Oder anders:

test=*# create table "Tab01" (i int);
CREATE TABLE
Time: 1,122 ms
test=*# insert into "Tab01" values (1);
INSERT 0 1
Time: 0,346 ms
test=*# select * from tab01;
ERROR:  relation "tab01" does not exist
LINE 1: select * from tab01;

Hint: es wird auf Groß/Kleinschreibung geachtet. Und die Fehlermeldungen bei PG sind nicht wie bei Mircosoft oder so für den Allerwertesten.

Andreas

Ja, das habe ich schon verstanden - aber der Tabellenname heißt so - alles Kleinbuchstaben :frowning:
Ich sehe diese ja auch in der Liste. Die gleicher Fehlermeldung erhalte ich bei allen Tabellen auf die ich ein select mache möchte.

select table_name from information_schema.tables where table_schema = 'db01' and table_name = 'tab01';
 table_name
------------
tab01
(1 row)

Das Schema ‘db01’ ist im search_path?

Andreas

Jetzt hast Du mich und meine Unwissenheit erwischt …

show search_path;

bringt ein:

  search_path
----------------
 "$user",public
(1 row)

Wie kann ich den search_path auf db01 setzen?

Danke!
Steffen

DANKE ANDREAS!

ein:

ALTER USER raffnix SET search_path = db01,public;

brachte die ersehnte Lösung!

Wobei ich für mein Köpfchen doch noch eine Erklärung bräuchte, wieso andere User (z.B. der Owner) damit keine Probleme hat, obwohl bei diesem der Pfad auch nicht gesetzt ist?

THX
Steffen

Prüf das noch mal. Ich bezweifle es.

Andreas

User raffnix:

select count(id) from tab01;
 count
--------
 1504944
(1 row)

Der ro User kann jetzt lesen :slight_smile:

search_path beim Owner und auch beim User, unter dem die Postgre ausgeführt wird:

show search_path;
  search_path
----------------
 "$user",public
(1 row)

Soll ich bei den beiden Usern den search_path ebenfalls anpassen? Und wenn ja, soll ich dabei etwas beachten?