PROC_ROLE
Dana Day, March 28, 2003 - 9:08 am UTC
Very interesting application of data dictionary.
logon trigger condition
Sravan, February 01, 2005 - 4:49 pm UTC
Hello Tom,
my requirement is that if a speific user logs in, am inserting a row into a table. So, am setting a logon trigger to do this work.
=======================
create or replace trigger logontrig
after logon on database
DECLARE
asid NUMBER;
aprogram VARCHAR2(48);
ausername VARCHAR2(30);
aserial NUMBER;
BEGIN
execute immediate 'select v.sid, v.program, v.username, v.serial#
from v$session v
where sid = ( select sid from v$mystat where rownum = 1 )' INTO asid, aprogram, ausername, aserial;
if ausername='SHRAV' THEN
execute immediate 'insert into shrav.shrav_log values (100)';
end if;
COMMIT;
END;
/
=====================
The trigger is created fine(logged in as user sys). Now, when I log into sqlplus as user 'SHRAV', the row is not getting inserted.
I do not believe the trigger is getting fired. I am stuck here, can you please guide me in the right direction in troubleshooting this issue.
February 02, 2005 - 4:45 am UTC
why in the world would you use dynamic SQL?????
first, is shrav a DBA... I'm going to guess yes.
what is happening is your trigger is failing, shrav as a dba is allowed to log in anyway. the error will be in your alert log and the error would be one of:
table or view doesn't exist for the query (the definer of this routine needs direct access to v_$session and v_$mystat
table or view doesn't exist for shrav.shrav_log
LOSE the dynamic sql
COMPILE the trigger with STATIC sql
and if you don't have the necessary privs, you'll KNOW right away.
but peek at your alert log right now
Thanks ..... it works now
Sravan, February 02, 2005 - 1:12 pm UTC
Hello Tom,
I removed dynamic sql and implemented static SQL. Peeped into the alert.log and corrected the error. It works fine now. Thanks for the pointer. Yes, Shrav is a DBA. Why do you recommened against the use of dynamic sql in this situation? Extra overhead, resources ???
My real requirement on using these triggers is that when a session gets connected from a specific program, I need to modify the user sessions' Resource Consumer Group. The Resource Consumer Group, Plan and Plan directives are created on the db already.
My logic is when a user logs into the db, a logon trigger checks if its coming from a spf. program and then execute grant_switch_consumer_group, set_initial_consumer_group and set the RESOURCE_MANAGER_PLAN to the new_plan.
Similarly, on logoff, a trigger revokes the privileges, set_initial_consumer_group to default and resets the RESOURCE_MANAGER_PLAN to null.
====== logon trigger =====
create or replace trigger logontrig
after logon on database
DECLARE
asid NUMBER;
aprocess VARCHAR2(12);
aprogram VARCHAR2(48);
ausername VARCHAR2(30);
aosuser VARCHAR2(30);
aserial NUMBER;
BEGIN
select v.sid, v.process, v.program, v.username, v.osuser, v.serial# INTO asid, a
process, aprogram, ausername, aosuser, aserial
from v$session v
where sid = ( select sid from v$mystat where rownum = 1);
insert into shrav.shrav_log values(100); -- debug stt.
IF aprogram='jrew.exe' THEN
dbms_resource_manager_privs.grant_switch_consumer_group
(ausername, 'UI_RESOURCE_GROUP', TRUE );
dbms_resource_manager.set_initial_consumer_group
(ausername, 'UI_RESOURCE_GROUP' );
DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA;
DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA;
insert into shrav.shrav_log values(101); -- debug stt.
execute immediate 'alter system set resource_manager_plan = '||'UI_PLAN';
END IF;
END;
/
============
===== logoff trigger =====
create or replace trigger logouttrig
before logoff on database
DECLARE
asid NUMBER;
aprocess VARCHAR2(12);
aprogram VARCHAR2(48);
ausername VARCHAR2(30);
aosuser VARCHAR2(30);
aserial NUMBER;
BEGIN
select v.sid, v.process, v.program, v.username, v.osuser, v.serial# INTO asid, a
process, aprogram, ausername, aosuser, aserial
from v$session v
where sid = ( select sid from v$mystat where rownum = 1);
insert into shrav.shrav_log values(200); -- debug stt.
IF aprogram='jrew.exe' THEN
dbms_resource_manager_privs.revoke_switch_consumer_group
(ausername, 'UI_RESOURCE_GROUP');
dbms_resource_manager.set_initial_consumer_group
(ausername, 'DEFAULT_CONSUMER_GROUP' );
DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA;
DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA;
insert into shrav.shrav_log values(201); -- debug stt.
execute immediate 'alter system set resource_manager_plan = ''';
END IF;
END;
/
===============
This is my first stab at resource consumer groups. If there is any flaw in my logic and understanding, please let me know. I would greatly appreciate it.
Thanks much
-Sravan
February 03, 2005 - 1:05 am UTC
if you have my book "Effective Oracle by Design", I cover in depth why dynamic sql is a tool that should be used only when you really need it.
You were a case study in "why", had you used static sql, you would have found your trigger never compiled!!!!!!!
you lose the dependency mechanism
you lose the plsql cursor cache
you lose lots of stuff by using dynamic sql -- so make sure the price you pay is worth it.
besides, coding in dynamic sql is just HARD as compared to static.
that grant/revoke logic - think about it. Think about it in the context of a multi-user environment. Think about what happens when an "spf" program logs in and then a non spf program.
will the non spf program have that grant?
yes
anyway, why grant on and grant off? just grant them the ability once and do the switch (which won't be needed in 10g by the way, you can set it up -- no trigger) in the trigger.
How about for a session
Sravan, February 03, 2005 - 11:40 am UTC
Tom,
thanks for the info. on dynamic sql. I will try to read the book.
You are absolutely right, I would have that problem of the user loging in from non-spf program with the grant. Alternateively, I was going to try to set the RCG to a session instead of the user. That way, am controlling the grant at the session level and not the user level -
dbms_session.switch_current_consumer_group(newg,oldg,flag);
I will try this option.
Also, I have been getting the pending area not active error, ORA-27391. And when I run clear the pending area and create the pending area stts., then am getting the ORA-29370: pending area is already active. I went through all the articles on metalink on this error but to noavail. Am little lost, if you have seen this error before, pelase let me know.
-Sravan
check on active role
Peter Mommen, April 03, 2007 - 5:56 am UTC
Would it be possible to make a likewise function that checks if the user does not only have the role, but also checks if the role is currently active?
April 04, 2007 - 9:41 am UTC
well, if you write a definers rights routine - no, roles are "not active" at all in them (the security domain changes - you become the definer with only their base set of privileges)
if you write an invokers rights routine - sort of - maybe. If you call the function DIRECTLY - as the invoker, yes. But, if you call it from a definers rights procedure, roles are gone again.
And the answer is NOT to use invokers rights all over the place, they should hardly ever be used.
ops$tkyte%ORA10GR2> create or replace function is_role_active( p_name in varchar2 ) return varchar2
2 authid current_user
3 as
4 l_str varchar2(50);
5 begin
6 select 'Role ' || role || ' is active'
7 into l_str
8 from session_roles
9 where role = upper(p_name);
10
11 return l_str;
12 exception
13 when no_data_found
14 then
15 return 'Role ' || p_name || ' is not active';
16 end;
17 /
Function created.
ops$tkyte%ORA10GR2> create or replace procedure p
2 as
3 begin
4 dbms_output.put_line( is_role_active( 'DBA' ) );
5 end;
6 /
Procedure created.
ops$tkyte%ORA10GR2> exec p
Role DBA is not active
PL/SQL procedure successfully completed.
ops$tkyte%ORA10GR2> exec dbms_output.put_line( is_role_active( 'DBA' ) );
Role DBA is active
PL/SQL procedure successfully completed.
log off a user from pl/sql
v k ravi, April 07, 2007 - 7:32 am UTC
Hi tom
can we logoff a user forcely from a pl/sql block ?
April 09, 2007 - 10:16 am UTC
you can use dynamic sql to issue an alter system kill session, yes.