der ein oder andere wird sich evtl. noch daran erinnern, ich interessiere mich für Rechte auf Spalten. Hehe, nun ist die neue PG Version 8.4 draussen und voila… es soll gehen. Rechte spaltenweise vergeben. Ok mein kurzes Testszenario:
TestTabelle->public darf alles
col1->testUser darf lesen
col2->testUser darf lesen
col3->testUser darf nur einfügen
Ok, nun wie nicht anderst zu erwarten sieht man als testUser die Werte in col3 natürlich trotzdem. Das will ich aber nicht. Wie kann man das machen? Wenn ich public von der Tabelle wegnehme geht gar nichts mehr… was auch logisch ist…
CREATE TABLE testtabelle
(
id integer NOT NULL,
eins character varying,
zwei character varying,
drei character varying,
CONSTRAINT testtabelle_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE testtabelle OWNER TO postgres;
GRANT ALL ON TABLE testtabelle TO postgres;
GRANT INSERT(eins) ON testtabelle TO "testR";
GRANT SELECT(zwei) ON testtabelle TO "testR";
ich weis nicht direkt was du meinst. Auf die Tabelle an sich sind gar keine Privilegien gesetzt.
Also wenn ich der rolle Public nur insert gebe, bekomme ich en fehler wenn ich die tabelle abfragen will. Wenn ich die Roll Public nur leer lasse dann passiert gar nichts.
Dein Buch habe ich leider im Moment nicht zur Hand Ich spiele aber mit dem Gedanken es zu kaufen weil darin anscheinend steht wie man Rechte zeilenweise vergibt… HUI
test=# create user "testR";
CREATE ROLE
test=*# CREATE TABLE testtabelle
test-# (
test(# id integer NOT NULL,
test(# eins character varying,
test(# zwei character varying,
test(# drei character varying,
test(# CONSTRAINT testtabelle_pkey PRIMARY KEY (id)
test(# )
test-# WITH (
test(# OIDS=FALSE
test(# );
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "testtabelle_pkey" for table "testtabelle"
CREATE TABLE
test=*# ALTER TABLE testtabelle OWNER TO postgres;
ALTER TABLE
test=*# GRANT ALL ON TABLE testtabelle TO postgres;
GRANT
test=*# revoke all on testtabelle from "testR";
REVOKE
test=*# GRANT INSERT(eins) ON testtabelle TO "testR";
GRANT
test=*# GRANT SELECT(zwei) ON testtabelle TO "testR";
GRANT
test=*# commit;
COMMIT
test=# \q
kretschmer@tux:~$ psql test -U testR
psql (8.4.0)
Type "help" for help.
test=> insert into testtabelle (eins) values(1);
ERROR: null value in column "id" violates not-null constraint
test=!> rollback;
ROLLBACK
test=> insert into testtabelle (id,eins) values(1,1);
ERROR: permission denied for relation testtabelle
test=!> \q
kretschmer@tux:~$ psql test
psql (8.4.0)
Type "help" for help.
test=# GRANT INSERT(id) ON testtabelle TO "testR";
GRANT
test=*# commit;
COMMIT
test=# \q
kretschmer@tux:~$ psql test -U testR
psql (8.4.0)
Type "help" for help.
test=> insert into testtabelle (id,eins) values(1,1);
INSERT 0 1
test=*> select eins from testtabelle ;
ERROR: permission denied for relation testtabelle
test=!> rollback;
ROLLBACK
test=>
Ich habe jetzt exakt dein Listing bei mir eingefügt.
select * from testtabelle
ERROR: permission denied for relation testtabelle
select eins from testtabelle
ERROR: permission denied for relation testtabelle
Ich meine das ist doch nicht normal oder? Ich erwarte das entweder nur id,zwei,drei angezeigt werden oder id,eins,zwei,drei und im Feld eins ist nichts drin. Ich meine was soll das denn sonst für einen Sinn ergeben? Was passiert bei dir wenn du
In produktivem Einsatz hat ein ‘select *’ nun einmal exakt nix zu suchen.
Ein ‘select *’ wird vom planner automatisch gewandelt in ein select über alle Spalten, das ‘permission denied’ ist also logisch.
Select zwei from Testtabelle geht, Select eins, zwei from testtabelle geht nicht. Ich meine Wenn ich eine Anwendung entwickle kann ich doch nicht hingehen und schreiben:
select eins, zwei, drei from testtabelle
if permission denied
select zwei, drei from testtabelle
Wie soll man denn sowas in der Realität gut gebrauchen können?
Du hast doch exakt dieses Verhalten gewollt, oder?
In der Realität prüft man halt, ob der User passende Rechte hat:
test=*> select case when (select has_column_privilege(current_user, 'testtabelle', 'zwei', 'select') = true) then eins else 'permission denied' end from testtabelle;
case
-------------------
permission denied
(1 row)
und:
test=# select case when (select has_column_privilege(current_user, 'testtabelle', 'zwei', 'select') = true) then eins else 'permission denied' end from testtabelle;
case
------
1
(1 row)
Selbes select, unterschiedliche Nutzer. Du kannst das auch als VIEW definieren.