限制Oracle普通用户能且只能kill自己的会话(一)

2014-11-24 18:41:02 · 作者: · 浏览: 0

声明


仅用于测试环境方便调试,不可能应用于生产环境;故请勿加入到程序源代码来实现自动杀进程。


只需一个参数,就能kill用户自己的会话,请小心操作,以免误kill进程。



使用方法


新开一个session后,执行


EXEC SYS.P_KILL_USER_SESSION(要杀的会话的sid);


就能实现sys用户才能操作的 alter system kill session(sid,serial#);


例子:04:14:46 sql1>exec sys.p_kill_user_session(2525);




目的


一般用户在不具备执行alter system权限的前提下,对于自己的所有session,能达到alter system kill session 功能。



原理


普通用户先根据(自己的)username和要killsessionsid查找到这个session(sid,serial#);再把这两个变量传到另一个存储过程P_KILL_SESSION,该存储过程中sys用户会亲自执行alter system kill session (sid,serial#);从而杀掉session



背景知识:


sid是唯一的,不会重复;假设登录了A用户,意图要kill user A的会话,结果输入了user Bsid,则在查找(sid,serial#)时,因为限制了username=A and sid=输入的sid,则会返回0条记录。从而限制了只能kill当前操作用户的session




实施步骤


1.sys用户先建立procedure



存储过程P_KILL_SESSION


CREATE OR REPLACE PROCEDURE P_KILL_SESSION(P_USER IN VARCHAR2,


P_SID IN VARCHAR2) AS


V_SQL VARCHAR2(32767);


BEGIN


SELECT 'ALTER SYSTEM KILL SESSION ''' || SID || ',' || SERIAL# || ''''


INTO V_SQL


FROM V$SESSION


WHERE USERNAME = P_USER


AND SID = P_SID;


EXECUTE IMMEDIATE V_SQL;


EXCEPTION


WHEN NO_DATA_FOUND THEN


RAISE_APPLICATION_ERROR(-20001,


'SID' || P_SID ||


' DOES NOT EXISTS, OR THE SESSION USER IS NOT ' ||


P_USER);


END;



存储过程P_KILL_USER_SESSION


CREATE OR REPLACE PROCEDURE P_KILL_USER_SESSION(P_SID IN NUMBER) AUTHID CURRENT_USER AS


V_USERNAME VARCHAR2(30);


V_SID NUMBER;


BEGIN


SELECT SYS_CONTEXT('USERENV', 'SESSION_USER'),


SYS_CONTEXT('USERENV', 'SID')


INTO V_USERNAME, V_SID


FROM DUAL;


IF P_SID != V_SID THEN


P_KILL_SESSION(V_USERNAME, P_SID);


ELSE


RAISE_APPLICATION_ERROR(-20000, 'CAN NOT KILL CURRENT SESSION!');


END IF;


END;



2.sysgrant执行存储过程的权限给用户


GRANT EXECUTE ON P_KILL_USER_SESSION TO JF_ISU;


3.获得授权的用户根据会话的sid就可以杀自己的任何session了;


exec sys.p_kill_user_session(sid);



验证


在服务器srcbdc建立3个会话;2个JF_ISU用户sql1=(3012,751)sql2=(1070,469)1个system用户(其它用户)


会话1


04:14:22 192.168.210.65:1521/SRCBFIN@JF_ISU> set sqlp 'sql1>'


04:14:30 sql1>col sys_context('userenv','session_user') for a50;


04:14:46 sql1>col sys_context('userenv','sid') for a50;


04:14:46 sql1>select sys_context('userenv','session_user') ,sys_context('userenv','sid') from dual;



SYS_CONTEXT('USERENV','SESSION_USER') SYS_CONTEXT('USERENV','SID')


-------------------------------------------------- --------------------------------------------------


JF_ISU 3012


会话2


04:14:52 192.168.210.65:1521/SRCBFIN@JF_ISU> set sqlp 'sql2>'


04:14:59 sql2>col sys_context('userenv','session_user') for a50;


04:15:01 sql2>col sys_context('userenv','sid') for a50;


04:15:01 sql2>select sys_context('userenv','session_user') ,sys_context('userenv','sid') from dual;



SYS_CONTEXT('USERENV','SESSION_USER') SYS_CONTEXT('USERENV','SID')


-------------------------------------------------- --------------------------------------------------


JF_ISU 1070



会话3


04:15:05 192.168.210.65:1521/SRCBFIN@SYSTEM> set sqlp 'syste