系统中可能会碰到查询数据没有权限,但是从数据字典中查看却显示包含查询权限的情况。
先看一下问题:
SQL> CONN U3/U3@YTK已连接。
SQL> SELECT SYNONYM_NAME, TABLE_OWNER, TABLE_NAME FROM USER_SYNONYMS
2 WHERE SYNONYM_NAME = 'V_T2';
SYNONYM_NAME TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------ ----------------
V_T2 U2 V_T2
SQL> SELECT COUNT(*) FROM V_T2;
SELECT COUNT(*) FROM V_T2
*第 1 行出现错误:
ORA-01031: 权限不足
SQL> SELECT GRANTEE, OWNER, TABLE_NAME, GRANTOR, PRIVILEGE
2 FROM USER_TAB_PRIVS
3 WHERE TABLE_NAME = 'V_T2';
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE
-------- ------ ------------------------------ -------- ----------------------
U3 U2 V_T2 U2 SELECT
SQL> CONN U2/U2@YTK已连接。
SQL> SELECT COUNT(*) FROM V_T2;
COUNT(*)
----------
40834
现在问题已经出来了,U2可以正常访问,而且U2也对U3进行了授权,但是U3无法进行访问。
其实问题的产生很简单,V_T2本身并不是一个表,而是一个视图,这个视图访问其他用户的对象。这个时候U2不仅需要SELECT权限,为了让U3可以访问自己创建的视图,U2需要SELECT WITH GRANT OPTION。
如果U2用户丢失了这个权限,且在重现获取权限时只获取到SELECT权限,而没有WITH GRANT OPTION,就会造成上面的问题。
通过一个例子来描述这个问题:
SQL> CONN YANGTK/YANGTK@YTK已连接。
SQL> DROP USER U1 CASCADE;
用户已删除。
SQL> DROP USER U2 CASCADE;
用户已删除。
SQL> DROP USER U3 CASCADE;
用户已删除。
SQL> CREATE USER U1 IDENTIFIED BY U1 DEFAULT TABLESPACE YANGTK;
用户已创建。
SQL> CREATE USER U2 IDENTIFIED BY U2 DEFAULT TABLESPACE YANGTK;
用户已创建。
SQL> CREATE USER U3 IDENTIFIED BY U3 DEFAULT TABLESPACE YANGTK;
用户已创建。
SQL> GRANT CONNECT, RESOURCE TO U1;
授权成功。
SQL> GRANT CONNECT, RESOURCE TO U2;
授权成功。
SQL> GRANT CONNECT, RESOURCE TO U3;
授权成功。
SQL> GRANT CREATE VIEW TO U1;
授权成功。
SQL> GRANT CREATE VIEW, CREATE SYNONYM TO U2;
授权成功。
SQL> GRANT CREATE VIEW, CREATE SYNONYM TO U3;
授权成功。
SQL> CONN U1/U1@YTK已连接。
SQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;
表已创建。
SQL> GRANT SELECT ON T TO U2 WITH GRANT OPTION;
授权成功。
SQL> CONN U2/U2@YTK已连接。
SQL> CREATE SYNONYM T FOR U1.T;
同义词已创建。
SQL> SELECT COUNT(*) FROM T;
COUNT(*)
----------
40834
SQL> CREATE VIEW V_T2 AS SELECT * FROM U1.T;
视图已创建。
SQL> GRANT SELECT ON T TO U3;
授权成功。
SQL> GRANT SELECT ON V_T2 TO U3;
授权成功。
SQL> CONN U3/U3@YTK已连接。
SQL> CREATE SYNONYM T FOR U2.T;
同义词已创建。
SQL> CREATE SYNONYM V_T2 FOR U2.V_T2;
同义词已创建。
SQL> SELECT COUNT(*) FROM T;
COUNT(*)
----------
40834
SQL> SELECT COUNT(*) FROM V_T2;
COUNT(*)
----------
40834
现在就将测试的环境建立好了,用户U1建立T表并对U2授权查询同时运行T2将T表的访问权限授权给其他用户。
U2建立一个同义词指向T表,同时建立了一个视图查询T表。
U2将T表的查询权限和视图V_T2的查询权限授权给U3。
U3可以访问T表和V_T2视图。
下面看看数据字典中的权限:
SQL> CONN YANGTK/YANGTK@YTK已连接。
SQL> SELECT GRANTEE, OWNER, TABLE_NAME, GRANTOR, PRIVILEGE, GRANTABLE
2 FROM DBA_TAB_PRIVS
3 WHERE OWNER IN ('U1', 'U2');
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRA
-------- ------ ---------- -------- ---------- ---
U2 U1 T U1 SELECT YES
U3 U1 T U2 SELECT NO
U3 U2 V_T2 U2 SELECT NO
删除T表,重建后只赋予U2用户SELECT权限:
SQL> CONN U1/U1@YTK已连接。
SQL> DROP TABLE T PURGE;
表已删除。
SQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;
表已创建。
SQL> GRANT SELECT ON T TO U2;
授权成功。
SQL> CONN YANGTK/YANGTK@YTK已连接。
SQL> SELECT GRANTEE, OWNER, TABLE_NAME, GRANTOR, PRIVILEGE, GRANTABLE
2 FROM DBA_TAB_PRIVS
3 WHERE OWNER IN ('U1', 'U2');
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRA
-------- ------ ---------- -------- ---------- ---
U3 U2 V_T2 U2 SELECT NO
U2 U1 T U1 SELECT NO
可以看到U3从U2出获取的T表的查询权限被连带删除,但是U3仍然有U2授权的V_T2的查询权限,不过这个时候U3已经无法查询U2的V_T2视图了:
SQL> CONN U3/U3@YTK已连接。
SQL> SELECT COUNT(*) FROM V_T2;
SELECT COUNT(*) FROM V_T2
*第 1 行出现错误:
ORA-01031: 权限不足
SQL> CONN U2/U2@YTK已连接。
SQL> SELECT COUNT(*) FROM T;
COUNT(*)
----------
40834
SQL> SELECT COUNT(*) FROM V_T2;
COUNT(*)
----------
40834
这就是开始看到的现象,虽然数据字典中显示U3有访问U2对象的权限,且U2的对象可以正常访问,但是U3实际上已经没有访问对象的权限了。
而且,这个时候U2也无法再次授权给U3了:
SQL> GRANT SELECT ON V_T2 TO U3;
GRANT SELECT ON V_T2 TO U3
*第 1 行出现错误:
ORA-01720: 不存在 'U1.T' 的授权选项
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-69461/,如需转载,请注明出处,否则将追究法律责任。