Zugriff auf Spalten

Hallo PG Gemeinde,

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…

Für eine Weise eingebung bin ich dankbar :wink:

Entziehe dem testUser erst mal alles und erlaube ihm dann das, was erlaubt sein soll.


Andreas

Also mein create sieht wie folgt aus:

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.

Nicht nur dem User. Vor allem auch PUBLIC die Rechte entziehen.

Steht unter anderem in meinem Buch ab Seite 80, spaltenbasierte Rechte ab Seite 86 :wink:

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 :wink: 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=>

Wo exakt ist Dein Problem?

Andreas

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

select * from testtabelle

machst?

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.

Andreas

Interessant.

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.


Andreas

In der Realität schreibt man keine Anfragen mit SELECT * sondern fragt die Spalten ab, die man braucht. Das spart Performance.

Außerdem macht man sich in der Realität zuerst Gedanken, wer worauf zugreifen darf und legt das abhängig von der Applikation fest.


Wo ist das Problem? :wink:

ahh. Ok dann sag ich mal vielen Dank.