oracle授权其他用户会话,能否给一般db用户授权,让他只可以kill掉自己的session呢?...

这个问题通过权限是没有办法控制的,因为允许KILL会话的权限就是ALTER SYSTEM。ALTER SYSTEM本身就是一个很强大的权限,可以对数据库实例进行设置。Oracle不但没有控制KILL哪些会话的权限,连单独KILL SESSION的权限都不存在。

而对于这种权限没有办法解决的问题,最好的处理方法就是通过存储过程将功能封装起来,然后将过程授权给用户:

[PHP]

SQL> CONN SYS@TESTRAC AS SYSDBA

输入口令: ****

已连接。

SQL> CREATE OR REPLACE PROCEDURE P_KILL_SESSION(P_USER IN VARCHAR2, P_SID IN VARCHAR2) AS

2   V_SQL VARCHAR2(32767);

3  BEGIN

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

5   INTO V_SQL

6   FROM V$SESSION

7   WHERE USERNAME = P_USER

8   AND SID = P_SID;

9   EXECUTE IMMEDIATE V_SQL;

10  EXCEPTION

11   WHEN NO_DATA_FOUND THEN

12    RAISE_APPLICATION_ERROR(-20001,

13     'SID: ' || P_SID || ' DOES NOT EXISTS, OR THE SESSION USER IS NOT ' || P_USER);

14  END;

15  /

过程已创建。

SQL> CREATE OR REPLACE PROCEDURE P_KILL_USER_SESSION(P_SID IN NUMBER)

2   AUTHID CURRENT_USER AS

3   V_USERNAME VARCHAR2(30);

4   V_SID NUMBER;

5  BEGIN

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

7   INTO V_USERNAME, V_SID FROM DUAL;

8   IF P_SID != V_SID THEN

9    P_KILL_SESSION(V_USERNAME, P_SID);

10   ELSE

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

12   END IF;

13  END;

14  /

过程已创建。

SQL> CREATE USER U1 IDENTIFIED BY U1;

用户已创建。

SQL> GRANT CONNECT TO U1;

授权成功。

SQL> GRANT EXECUTE ON P_KILL_USER_SESSION TO U1;

授权成功。

.

[/PHP]

过程P_KILL_SESSION用来KILL指定的会话,由于这个过程在SYS用户下创建,因此可以KILL任何会话,不过在KILL SESSION之前,过程检查输入的SID和USERNAME是否相符,如果不相符则报错。

过程P_KILL_USER_SESSION是一个调用者权限过程,通过在这个过程中获取当前会话的SID和USERNAME信息,并检查用户KILL的SESSION是否与当前会话SID相同,如果相同则报错。

下面创建一个用户,并授予CONNECT角色,使得这个用户可以登陆数据库。这个用户除了CREATE SESSION权限外,没有其他的系统权限。下面将P_KILL_USER_SESSION过程授权给U1。

并启动两个会话以U1连接到数据库:

[php]

SQL> CONN U1/U1@TESTRAC

已连接。

SQL> SET SQLP 'SQL2> '

SQL2>

.

[/php]

另一个连接:

[php]

SQL> CONN U1/U1@TESTRAC

已连接。

SQL> SET SQLP 'SQL3> '

.

[/php]

查询一下连接信息:

[php]

SQL> SELECT SID, USERNAME

2  FROM V$SESSION

3  WHERE MACHINE LIKE '%YTK%';

SID USERNAME

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

286 U1

291 U1

307 SYS

.

[/php]

U1连查询V$SESSION的权限都没有,但是可以KILL另外一个以U1用户登陆的会话:

[php]

SQL2> SELECT * FROM V$SESSION;

SELECT * FROM V$SESSION

*

第 1 行出现错误:

ORA-00942: 表或视图不存在

SQL2> SELECT SYS_CONTEXT('USERENV', 'SID')

2  FROM DUAL;

SYS_CONTEXT('USERENV','SID')

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

286

SQL2> EXEC SYS.P_KILL_USER_SESSION(286)

BEGIN SYS.P_KILL_USER_SESSION(286); END;

*

第 1 行出现错误:

ORA-20000: CAN NOT KILL CURRENT SESSION!

ORA-06512: 在 "SYS.P_KILL_USER_SESSION", line 11

ORA-06512: 在 line 1

SQL2> EXEC SYS.P_KILL_USER_SESSION(307)

BEGIN SYS.P_KILL_USER_SESSION(307); END;

*

第 1 行出现错误:

ORA-20001: SID: 307 DOES NOT EXISTS, OR THE SESSION USER IS NOT U1

ORA-06512: 在 "SYS.P_KILL_SESSION", line 12

ORA-06512: 在 "SYS.P_KILL_USER_SESSION", line 9

ORA-06512: 在 line 1

SQL2> EXEC SYS.P_KILL_USER_SESSION(291)

PL/SQL 过程已成功完成。

.

[/php]

验证一下会话已经被KILL:

[php]

SQL3> SELECT * FROM DUAL;

SELECT * FROM DUAL

*

第 1 行出现错误:

ORA-00028: 您的会话己被终止

SQL3>

.

[/php]

这个问题并不复杂,不过刚好可以体现定义者存储过程和调用者存储过程的区别。

原文出自:http://yangtingkun.itpub.net/post/468/481170

[本帖最后由 yangtingkun 于 2009-3-27 23:48 编辑]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值