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


声明:

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

只需一个参数,就能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 '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>

相关内容