声明:
仅用于测试环境方便调试,不可能应用于生产环境;故请勿加入到程序源代码来实现自动杀进程。
只需一个参数,就能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和要kill的session的sid查找到这个session的(sid,serial#);再把这两个变量传到另一个存储过程P_KILL_SESSION,该存储过程中sys用户会亲自执行alter system kill session (sid,serial#);从而杀掉session。
背景知识:
sid是唯一的,不会重复;假设登录了A用户,意图要kill user A的会话,结果输入了user B的sid,则在查找(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.sys再grant执行存储过程的权限给用户
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 'system3>';
04:15:23 system3>col sys_context('userenv','session_user') for a50;
04:15:30 system3>col sys_context('userenv','sid') for a50;
04:15:30 system3>select sys_context('userenv','session_user') ,sys_context('userenv','sid') from dual;
SYS_CONTEXT('USERENV','SESSION_USER') SYS_CONTEXT('USERENV','SID')
-------------------------------------------------- --------------------------------------------------
SYSTEM 2525
04:15:30 system3>
04:15:32 system3>select sid,serial#,username,type,program,machine from v$session where machine like '%srcbdc%';
SID SERIAL# USERNAME TYPE PROGRAM MACHINE
---------- ---------- ------------------------------ ---------- ------------------------------------------------ --------
1070 469 JF_ISU USER sqlplus@srcbdc (TNS V1-V3) srcbdc
2525 511 SYSTEM USER sqlplus@srcbdc (TNS V1-V3) srcbdc
3012 751 JF_ISU USER sqlplus@srcbdc (TNS V1-V3) srcbdc
安全限制测试:
u JF_ISU不能kill其它用户的会话;(JF_ISU无法kill system用户的)
04:14:46 sql1>exec sys.p_kill_user_session(2525);
BEGIN sys.p_kill_user_session(2525); END;
*
ERROR at line 1:
ORA-20001: SID? 2525 DOES NOT EXISTS, OR THE SESSION USER IS NOT JF_ISU
ORA-06512: at "SYS.P_KILL_SESSION", line 12
ORA-06512: at "SYS.P_KILL_USER_SESSION", line 10
ORA-06512: at line 1
u JF_ISU不能kill当前session;
04:16:29 sql1>exec sys.p_kill_user_session(3012);
BEGIN sys.p_kill_user_session(3012); END;
*
ERROR at line 1:
ORA-20000: CAN NOT KILL CURRENT SESSION!
ORA-06512: at "SYS.P_KILL_USER_SESSION", line 12
ORA-06512: at line 1
u 未获得存储过程执行权限的用户不能调用该存储过程。
04:15:41 system3>exec sys.p_kill_user_session(3012);
BEGIN sys.p_kill_user_session(3012); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.P_KILL_USER_SESSION' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
基本测试:
JF_ISU能kill除当前session之外的自己的所有会话(且该用户不具备alter system权限);
04:16:38 sql1>exec sys.p_kill_user_session(1070);
PL/SQL procedure successfully completed.
04:17:16 sql1>
04:17:18 sql1>select * from session_privs; (实际上只需要有create session并获得exec on procedure p_kill_user_session即可完成)
PRIVILEGE
----------------------------------------
CREATE SESSION
UNLIMITED TABLESPACE
CREATE TABLE
SELECT ANY TABLE
CREATE CLUSTER
CREATE SYNONYM
CREATE VIEW
CREATE SEQUENCE
SELECT ANY SEQUENCE
CREATE DATABASE LINK
CREATE PROCEDURE
CREATE TRIGGER
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE
SELECT ANY DICTIONARY
DEBUG CONNECT SESSION
DEBUG ANY PROCEDURE
18 rows selected.
04:17:44 sql1>
04:15:01 sql2>select sys_context('userenv','session_user') ,sys_context('userenv','sid') from dual;
select sys_context('userenv','session_user') ,sys_context('userenv','sid') from dual
*
ERROR at line 1:
ORA-00028: your session has been killed
附录:
查看当前session信息,要对视图v$session有select权限才能获得serial#,
col username for A10;
sql1>select sid,serial#,username from v$session where sid=(select sys_context('userenv','sid') from dual);
SID SERIAL# USERNAME
---------- ---------- ----------
1457 3 JF_ISU
04:43:18 sql1>select * from user_role_privs;
USERNAME GRANTED_ROLE ADM DEF OS_
------------------------------ ------------------------------ --- --- ---
JF_ISU CONNECT NO YES NO
JF_ISU RESOURCE NO YES NO
04:43:24 sql1>
04:43:25 sql1>select * from role_sys_privs;
ROLE PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
CONNECT CREATE SESSION NO
RESOURCE CREATE CLUSTER NO
RESOURCE CREATE SEQUENCE NO
RESOURCE CREATE TRIGGER NO
RESOURCE CREATE TABLE NO
RESOURCE CREATE PROCEDURE NO
RESOURCE CREATE TYPE NO
RESOURCE CREATE OPERATOR NO
RESOURCE CREATE INDEXTYPE NO
9 rows selected.
04:43:34 sql1>
04:43:35 sql1>select * from user_sys_privs;
USERNAME PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
JF_ISU SELECT ANY DICTIONARY NO
JF_ISU CREATE SEQUENCE NO
JF_ISU DEBUG CONNECT SESSION NO
JF_ISU CREATE TYPE NO
JF_ISU CREATE VIEW NO
JF_ISU SELECT ANY TABLE NO
JF_ISU CREATE DATABASE LINK NO
JF_ISU CREATE TABLE NO
JF_ISU UNLIMITED TABLESPACE NO
JF_ISU CREATE TRIGGER NO
JF_ISU CREATE SYNONYM NO
JF_ISU DEBUG ANY PROCEDURE NO
JF_ISU SELECT ANY SEQUENCE NO
13 rows selected.
04:43:43 sql1>