实际现象如下:
15:24:36 C@zkm(51)> select * FROM USER_TAB_PRIVS WHERE table_name='V_T';
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY
------------------------- ------------------------------ ------------------------------ ------------------------- ------------------------------ --------- ---------
C B V_T B SELECT NO NO
Elapsed: 00:00:00.05
15:24:39 C@zkm(51)> select count(*) from b.v_t;
select count(*) from b.v_t
ERROR at line 1:
ORA-01031: insufficient privileges
Elapsed: 00:00:00.00
从视图user_tab_privs可以看出,C用户对表B.V_T(实际是视图)是有select权限的,但是查询确会报权限不足。
还真是奇葩。
实际上V_T是用户B的一个视图,V_T视图内容是查询用户A的表T。
看下实际环境构造时候的语句会更加直观明了。
1.sys管理员用户创建a,b,c三个用户并授权:
create user a identified by a;
create user b identified by b;
create user c identified by c;
grant resource,connect,unlimited tablespace,create synonym,create view to a,b,c;
2.登录用户a:
create table a.t (id int);
grant select on a.t to b;
3.登录用户b:
create view v_t as select * from a.t;
4.使用sys将b.v_t授权查询权限给用户c:
grant select on b.v_t to c;
按照上边的顺序执行后就将该现象重现出来了。
根本原因在于使用sys用户授权b.v_t给c用户的时候,虽然直接授权成功了,查询user_tab_privs也显示权限没有问题,但是实际上如果第4步使用b用户授权自己的视图v_t给c的时候会报错:
15:24:26 B@zkm(486)> grant select on b.v_t to c;
grant select on b.v_t to c
ERROR at line 1:
ORA-01720: grant option does not exist for 'A.T'
这样就明白了,b用户对a.t这个表只有查询权限,没法私自将a.t查询权限授权给c去查询。
解决方法就是让b用户也有讲a.t这个表给c用户的权限。
登录a用户:
grant select on t to b with grant option;
不需要在做其他操作,with grant option后c用户再次执行就不会报错了。
因为sys用户拥有最高权限,所以上边第4步骤直接执行成功了,但是我觉得Oracle应该有个校验然后报错提示才合理。