Skip to Main Content
  • Questions
  • Who is an Invoker , and Who is a Definer

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, omer.

Asked: October 01, 2001 - 3:27 pm UTC

Last updated: June 09, 2005 - 6:07 pm UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked

Tom

This is a cabal question, but very important

Who is an invoker? Example for invoker
Who is a Definer ? Example for definer

My comphrehension of the concept:

If I use an object belonging to another schema over which I just select grant, then Iam the Invoker of that object, where as , as Iam creating the procedure, Iam also the definer.

Confusing, kindly clarify.



and Tom said...

well, invoker/definer rights only come into play with procedures/functions and packages.


The invoker is the caller of the routine. If I (tkyte) run a stored procedure owned by you that supports invoker rights - I (tkyte) am the invoker and the procedure will run its SQL as if I typed it in -- not you.

If I (tkyte) run a stored procedure owned by you that supports definer rights -- I am still the invoker HOWEVER the procedure will run with YOUR privs -- the DEFINERS privs, not mine.

To add to this -- suppose the definer rights routine YOU wrote calls that invoker rights routine. Now, if I (tkyte) call your definer rights procedure -- it'll execute as you and when it calls the invoker rights routine the invoker this time is YOU -- not me. When we entered that definer rights routine -- that definer becomes the invoker for all other calls (unless it calls another definer rights routine in another schema -- then that schema becomes the invoker)

I've got a pretty good chapter on this topic that goes into this in great depth in my book if you are interested.

Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

misunderstanding

A reader, October 01, 2001 - 9:49 pm UTC

Tom

We were under the impression that invokers rights allow you to compile and execute a procedure even though the schema creating the procedure or function has privileges over the underlying objects through roles, but not directly.

But your explanation tells us that this is not so.

So this means, if the schema doesnt have direct privileges over say table T, there is no way you can use that object in creating your sub program subprogram.

That is final.

Is it so?

Tom Kyte
October 02, 2001 - 7:17 am UTC

Invokers rights are compiled no differently then a definers rights routine, the owner needs to have access to the underlying objects via a direct grant. In this respect, at compile time, invokers and definers rights routines are no different.

(i go into this in great detail, with tons of examples and recommandations on how to and how not to use this feature in my book if you are interested. Some 40 pages on this topic alone)


It is only at RUNTIME that the behavior is different. At runtime, an invokers rights routine runs under the invokers rights -- much like an anonymous plsql block (with differences, its not exactly the same).

There is no way using STATIC SQL to create that object, this is true. But if you look at:
</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:1035431863958 <code>

You'll see that you can create a procedure that can access any object the invoker can access. This is what invokers rights routines excell at. Writing generic, reusable utilities that work on unknown sets of data using dynamic sql (either via dbms_sql or using native dynamic sql).


A query on Invoker rights

Anil Pant, January 09, 2005 - 3:27 am UTC

Hello,
In your book Effective Oracle by Desgin on page 586, you say "You flood the Oracle shared pool".
What I understand from this is, similar procedure when invoked by N different users then each will parsed differently (even though the sql statements are same) and each will have their own sql area rather than sharing.
Am I correct ?


Tom Kyte
January 09, 2005 - 11:46 am UTC

in invokers rights -- the SAME procedure (not similar) is used by many people, but it is AS IF each person had their own copy of the procedure as the SQL is not parsed as the "owner" (as is normal) but rather as "user" or "invoker".

Meaning, a procedure with:


for x in ( select * from emp )
loop


can in fact be accessing totally different EMP tables when you run it versus me running it, or with different security privs or whatever. so you end up with a parsed sql plan PER INVOKER instead of one nice plan to be used by all.

SESSION_USER and CURRENT_USER query

Adrian, January 24, 2005 - 7:21 am UTC

Tom,

I was seeing some strange behaviour with SESSION_USER and CURRENT_USER earlier, so returned to your chapter on Invokers Rights in your first book. I'm seeing no difference between invokers or definers with respect to CURRENT_USER, SESSION_USER or CURRENT_SCHEMA. Could you please comment - it's the bit where I change users that is confusing me.

SQL*Plus: Release 10.1.0.2.0 - Production on Mon Jan 24 12:15:24 2005

Copyright (c) 1982, 2004, Oracle. All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options


ABB>
ABB> CREATE OR REPLACE PROCEDURE definer_proc IS
2 BEGIN
3 DBMS_OUTPUT.PUT_LINE( 'Current user=' || sys_context('userenv','current_user') );
4 DBMS_OUTPUT.PUT_LINE( 'Session user=' || sys_context('userenv','session_user') );
5 DBMS_OUTPUT.PUT_LINE( 'Current schema=' || sys_context('userenv','current_schema') );
6 END definer_proc;
7 /

Procedure created.

ABB>
ABB> CREATE OR REPLACE PROCEDURE invoker_proc AUTHID CURRENT_USER IS
2 BEGIN
3 DBMS_OUTPUT.PUT_LINE( 'Current user=' || sys_context('userenv','current_user') );
4 DBMS_OUTPUT.PUT_LINE( 'Session user=' || sys_context('userenv','session_user') );
5 DBMS_OUTPUT.PUT_LINE( 'Current schema=' || sys_context('userenv','current_schema') );
6 END invoker_proc;
7 /

Procedure created.

ABB>
ABB> SELECT object_name, authid
2 FROM user_procedures
3 WHERE object_name LIKE '%PROC';

OBJECT_NAME AUTHID
------------------------------ ------------
INVOKER_PROC CURRENT_USER
DEFINER_PROC DEFINER

ABB>
ABB> exec definer_proc;
Current user=ABB
Session user=ABB
Current schema=ABB

PL/SQL procedure successfully completed.

ABB> exec invoker_proc;
Current user=ABB
Session user=ABB
Current schema=ABB

PL/SQL procedure successfully completed.

ABB>
ABB> GRANT EXECUTE ON definer_proc TO ac;

Grant succeeded.

ABB> GRANT EXECUTE ON invoker_proc TO ac;

Grant succeeded.

ABB>
ABB> conn ac/ac
Connected.
AC>
AC> exec abb.definer_proc;
Current user=AC
Session user=AC
Current schema=AC

PL/SQL procedure successfully completed.

AC> exec abb.invoker_proc;
Current user=AC
Session user=AC
Current schema=AC

PL/SQL procedure successfully completed.

Regards
Adrian


Tom Kyte
January 24, 2005 - 8:43 am UTC

you should select them from dual

But...

Adrian, January 24, 2005 - 10:01 am UTC

>> you should select them from dual

But surely the advantage of application contexts is that SQL and PL/SQL can use them. Selecting from dual to get the "correct" answer hides an implementation that just wouldn't be obvious to people. For example, I just came along and used the SYS_CONTEXT function in PL/SQL and assumed it should give me the correct answer. Surely many more developers will have made the same "mistake".

Is there a good reason why we would need to select this from dual to have it respond correctly ?

Regards
Adrian

Tom Kyte
January 24, 2005 - 11:18 am UTC

please take this one up with support - the only way to get behaviour changed is via the mechanism. (eg: i agree with you)

...case sensitive

Adrian, February 21, 2005 - 9:27 am UTC

Tom,

In case you were interested, there is already a bug with this and to get the correct behaviour in PL/SQL, you must use SYS_CONTEXT( 'USERENV', 'CURRENT_USER' ) i.e. capitals. Strange but true.

Regards
Adrian

Ravi, June 08, 2005 - 6:29 pm UTC

Tom I'm schema A and I need to run a procedure in schema B with all roles enabled. How do I do that?

That means I can call an invoker rights procedure in Schema B because I'll have roles disabled.

Should I call a definer rights procedure in Schema B, which in turn calls an invoker rights procedure in Schema B to do this?


Tom Kyte
June 08, 2005 - 10:18 pm UTC

You cannot.

If you are schema A, you can either:

a) run an invoker rights procedure as you "A" with all of "A"'s roles or
b) run a definer rights preocedure as "B" with "B"'s base privileges

that is all. as soon as you hit that definer rights procedure, the roles are "gone" and you cannot set them on once you hit the Definer Rights procedure.

Ravi, June 08, 2005 - 6:30 pm UTC

To add one bit, my code in procedure that I want to execute is a NDS using execute immediate.

Ravi, June 09, 2005 - 9:46 am UTC

Tom, I should rephrase the Question,
When I have logged on as Schema A and then call a Definer procedure in Schema B. But in Schema B, I want SCHEMA B's roles enabled, because one of its roles gives me a special DCL privliege.

So if this procedure now calls ANOTHER procedure in Schema B which is running as invoker (Authid current_user), while this second procedures run, would I have Schema B's roles enabled.

Important that I dont want Schema A's roles enabled, but Schema B's.

So instead of directly calling a Invoker rights procedure in Schema B (which means I'd have A's roles enabled), I am calling a definer rights first so that my current_user becomes SCHEMAB. Then I call another invoker procedure in Schema B to have Schema B's roles enabled?

Tom Kyte
June 09, 2005 - 11:21 am UTC

No, i understood what you *want*

I can only say "you cannot get that to happen"


It will not work - once you call the D.R. routine, roles are gone and you are not getting them back.

B needs to have this privilege granted directly to them, not via a role.

Getting the right USER

A reader, June 09, 2005 - 11:36 am UTC

I have a standard definer right stored procedure owned by FOO that references the builtin USER keyword.

If I grant execute to A and A runs it, the USER in the code will return A. If I grant execute to B and B runs it, USER will return B.

How can I refer to the value of the "owner" (definer) of the procedure in the stored procedure code?

Thanks

Tom Kyte
June 09, 2005 - 6:07 pm UTC

a@ORA9IR2W> create procedure p
2 as
3 begin
4 for x in ( select user u, sys_context('userenv', 'current_schema' ) cs from dual )
5 loop
6 dbms_output.put_line( x.u || ', ' || x.cs );
7 end loop;
8 end;
9 /

Procedure created.

a@ORA9IR2W>
a@ORA9IR2W> grant execute on p to b;

Grant succeeded.

a@ORA9IR2W>
a@ORA9IR2W> @connect b/b
a@ORA9IR2W> set termout off
b@ORA9IR2W> set termout on
b@ORA9IR2W>
b@ORA9IR2W> exec a.p
B, A

PL/SQL procedure successfully completed.


sadf

dfd, September 19, 2010 - 3:47 am UTC

sdaf

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library