27. Juni 2007

PL/SQL und Rollen, Invoker's Rights vs. Definer's Rights ...

Missverständnisse und Probleme tauchen recht häufig im Bereich PL/SQL und Rollen auf. In diesem Zusammenhang wichtig sind folgende Grundsätze:
  • PL/SQL-Prozeduren, -Funktionen und -Packages können mit Definer's Rights oder Invoker's Rights ausgeführt werden.
  • Während der Ausführung von Definer's Rights Procedures sind alle Rollen abgeschaltet.
Ein Beispiel: Es wird (als SYS) eine Rolle table_creator mit dem Systemprivileg create table erzeugt. Anschließend wird ein User proc_owner erzeugt und diesem werden die Privilegien create session, create procedure und die soeben erzeugte Rolle table_creator zugewiesen. Die Quota auf dem Tablespace (hier: Users) nicht vergessen!
create role table_creator not identified 
/
grant create table to table_creator
/
 
create user proc_owner identified by proc_owner
/

grant create session, create procedure to proc_owner
/

grant table_creator to proc_owner
/

alter user proc_owner quota 10M on users
/
Nun wird als PROC_OWNER die folgende Prozedur angelegt und gestartet:
create or replace procedure CREATE_TABLE_PROC
is
begin
  execute immediate 'create table test_roles (column1 number(10))';
end;
/

Prozedur wurde erstellt.

create table test_table (column1 number(10))
/

Tabelle wurde erstellt.


begin
  create_table_proc;
end;
/

begin
*
FEHLER in Zeile 1:
ORA-01031: insufficient privileges
ORA-06512: at "PROC_OWNER.CREATE_TABLE_PROC", line 4
ORA-06512: at line 2
Man sieht: Der User table_owner kann Tabellen mit create table direkt erstellen, sobald er dasselbe jedoch über seine Prozedur versucht, schlägt das ganze fehl ... Grund dafür ist, wie oben bereits geschrieben: Während der Ausführung einer Definer's Rights-Prozedur (und das ist der Default bei PL/SQL) sind alle Rollen abgeschaltet. Und wie löst man nun das Problem?
  1. Man gibt dem User proc_owner das Systemprivileg create table direkt.
  2. Man erzeugt die Prozedur als Invoker's Rights-Prozedur. Dann werden die Rollen nicht abgeschaltet. Aber: Für die Ausführung gelten dann die Rechte des Aufrufers, nicht des Eigentümers!
Hier ist ein Beispiel für eine Invoker's Rights-Prozedur:
create or replace procedure CREATE_TABLE_PROC 
authid current_user is
begin
  execute immediate 'create table test_roles (column1 number(10))';
end;
/

Prozedur wurde erstellt.

begin
  create_table_proc;
end;
/

PL/SQL-Prozedur erfolgreich abgeschlossen.
Das praktische an invoker's rights-Prozeduren ist übrigens, dass man, setzt man das Rechtekonzept richtig auf, das execute-Privileg daran an PUBLIC vergeben kann - was der jeweilige User dann tatsächlich tun kann, hängt von seinen Rechten ab. Sehr viele der PL/SQL-Pakete von Oracle sind mit Invoker's Rights erzeugt. Mehr Information zum Thema findet sich übrigens in der PL/SQL-Dokumentation:
http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14261/subprograms.htm#sthref1758

Keine Kommentare:

Beliebte Postings