Kurze Demo:
Zuerst einmal als Superuser:
test=# create database rhaupt;CREATE DATABASE
Time: 304,252 ms
test=# \c rhaupt;You are now connected to database "rhaupt" as user "kretschmer".
rhaupt=# create user rhaupt1;CREATE ROLE
Time: 0,380 ms
rhaupt=*# create user rhaupt2;
CREATE ROLE
Time: 0,125 ms
rhaupt=*# revoke all on schema public from rhaupt1;
REVOKE
Time: 0,437 ms
rhaupt=*# revoke all on schema public from rhaupt2;
REVOKE
Time: 0,155 ms
rhaupt=*# create table foo (user_id text default session_user, value int);CREATE TABLE
Time: 5,338 ms
rhaupt=*# create function insert_foo(int) returns bool as $$begin insert into foo(user_id,value) values (default, $1); return true;end;$$language plpgsql security definer;
CREATE FUNCTION
Time: 1,284 ms
rhaupt=*# create function get_foo() returns setof int as $$begin return query select value from foo where user_id=session_user; end;$$language plpgsql security definer;
CREATE FUNCTION
Time: 0,536 ms
rhaupt=*# commit;
COMMIT
Time: 0,460 ms
Wichtig ist, daß man mit session_user da hantiert, da augfrund security definer der current_user ja der Superuser (Ersteller) ist. bedingt natürlich, daß jeder Mandant in der DB als eigener User angelegt ist, aber das ist ja kein Problem.
Nun in einer anderen Session:
kretschmer@tux:~$ psql -U rhaupt1 rhaupt;
Timing is on.
psql (9.2.0)
Type "help" for help.
rhaupt=> select * from foo;
ERROR: permission denied for relation foo
Time: 0,832 ms
rhaupt=*> select insert_foo(1);
insert_foo
------------
t
(1 row)
Time: 1,326 ms
rhaupt=*> select get_foo();
get_foo
---------
1
(1 row)
Time: 1,481 ms
rhaupt=*> \q
kretschmer@tux:~$ psql -U rhaupt2 rhaupt;
Timing is on.
psql (9.2.0)
Type "help" for help.
rhaupt=> select get_foo();
get_foo
---------
(0 rows)
Time: 2,262 ms
rhaupt=*> select insert_foo(2);
insert_foo
------------
t
(1 row)
Time: 0,495 ms
rhaupt=*> select get_foo();
get_foo
---------
2
(1 row)
Time: 0,201 ms
rhaupt=*>
So hat man eine extra Schicht eingezogen und trennt schön die einzelnen Mandanten. Als Superuser hast natürlich alle rechte, wieder die erste Session:
rhaupt=# select * from foo;
user_id | value
---------+-------
rhaupt2 | 2
rhaupt1 | 1
(2 rows)
(ich hatte erst das commit vergessen, daher nun andere reihenfolge…)
.oO( ich muß mal wieder compilieren, 9.2.0, aber das ist hier lokal nur meine Spielwiese)