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?
- Man gibt dem User proc_owner das Systemprivileg create table direkt.
- 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
http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14261/subprograms.htm#sthref1758