非典型ORA-01720: grant option does not exist2020-08-20

现象

这个问题来自于朋友工作中遇到的一个真实场景:
Oracle 11.2.0.4数据库
数据库用户A:create any view,select any table
数据库用户B:select any table
数据库用户C: 只读用户,有且仅有create session权限

执行步骤:

  1. 数据库用户A在数据库用户B中创建了一张VIEW,VIEW的基表来自于多个数据库用户。
  2. 使用SYS用户将VIEW的select权限授权给数据库用户C。
  3. 数据库用户B和数据库用户C均可正常查询该VIEW。
  4. 数据库用户A再次执行:create or replace view语句,结果报出:
    ORA-01720: grant option does not exist for 'TEST.T_OBJ'。
  5. 数据库用户A新建一个VIEW(和老VIEW定义完全一致),可以成功执行。

重演过程

创建测试用户

SQL> create user test0 identified by test;
grant create session to test0;
grant select any table to test0;
grant create any view to test0;

User created.

SQL> 
Grant succeeded.

SQL> 
Grant succeeded.

SQL> 
Grant succeeded.

SQL>create user test2 identified by test;
grant create session to test2;
grant select any table to test2;

SQL> 
User created.

SQL> 
Grant succeeded.

SQL> 
Grant succeeded.

SQL> create user test3 identified by test;
grant create session to test3;

SQL> 
Grant succeeded.

SQL> 
User created.

系统权限查询:

SQL> select * from dba_sys_privs where grantee like 'TEST%' order by grantee,privilege;

GRANTEE                        PRIVILEGE                                ADMIN_OPTION
------------------------------ ---------------------------------------- ------------
TEST0                          CREATE ANY VIEW                          NO
TEST0                          CREATE SESSION                           NO
TEST0                          SELECT ANY TABLE                         NO
TEST2                          CREATE SESSION                           NO
TEST2                          SELECT ANY TABLE                         NO
TEST3                          CREATE SESSION                           NO

为简化测试,测试视图仅仅引用了test.t_obj表,记录有800多万条。

SQL> connect test0/test;
Connected.
SQL> create or replace view test2.v_t_obj as select * from test.t_obj;

View created.

SQL> connect test2/test;
Connected.
SQL> select count(*) from v_t_obj;

  COUNT(*)
----------
   8053248


SQL> connect /as sysdba;
Connected.
SQL> grant select on test2.v_t_obj to test3;

Grant succeeded.

SQL> connect test3/test
Connected.
SQL> select count(*) from test2.v_t_obj;

  COUNT(*)
----------
   8053248

至此,一切看起来均很正常。

表的权限如下:

SQL> select * from dba_tab_privs where grantee like 'TEST%';

GRANT OWNER TABLE_NAME                     GRANT PRIVILEGE  GRANTABLE HIERARCHY
----- ----- ------------------------------ ----- ---------- --------- ---------
TEST3 TEST2 V_T_OBJ                        TEST2 SELECT     NO        NO

SQL> select * from dba_sys_privs where grantee like 'TEST%' order by grantee,privilege;

GRANT PRIVILEGE                      ADMIN_OPTION
----- ------------------------------ ------------
TEST0 CREATE ANY VIEW                NO
TEST0 CREATE SESSION                 NO
TEST0 SELECT ANY TABLE               NO
TEST2 CREATE SESSION                 NO
TEST2 SELECT ANY TABLE               NO
TEST3 CREATE SESSION                 NO

重建视图,问题发生了:

SQL> connect test0/test;
Connected.
SQL> create or replace view test2.v_t_obj as select * from test.t_obj;
create or replace view test2.v_t_obj as select * from test.t_obj
                                                           *
ERROR at line 1:
ORA-01720: grant option does not exist for 'TEST.T_OBJ'

SQL> create view test2.v_t_obj_new as select * from test.t_obj;

View created.

测试到这里,结合常规场景中的视图授权问题,初步可以断定和表的select grant option策略有关。
进一步继续测试:

SQL> connect /as sysdba              
Connected.
SQL> revoke select on test2.v_t_obj from test3;

Revoke succeeded.

SQL> connect test0/test
Connected.
SQL> create or replace view test2.v_t_obj as select * from test.t_obj;

View created.

到这里时,可以思考一下,以上的操作里,有一步操作值得关注:

SQL> connect /as sysdba;
Connected.
SQL> grant select on test2.v_t_obj to test3;

Grant succeeded.

按照正常操作,一般view的授权会以VIEW的owner登录数据库,然后直接grant。

SQL> connect test2/test
Connected.
SQL> grant select on test2.v_t_obj to test3;
grant select on test2.v_t_obj to test3
                      *
ERROR at line 1:
ORA-01720: grant option does not exist for 'TEST.T_OBJ'

问题还是出在多用户的级联授权上,继续往下探:

SQL> connect system
Enter password: 
Connected.
SQL> grant select on test2.v_t_obj to test3;
grant select on test2.v_t_obj to test3
                      *
ERROR at line 1:
ORA-01720: grant option does not exist for 'TEST.T_OBJ'

SQL> select * from dba_sys_privs where grantee like 'SYS%' and privilege = 'SELECT ANY TABLE' order by grantee,privilege;

GRANTEE    PRIVILEGE                      ADMIN_OPTION
---------- ------------------------------ ------------
SYS        SELECT ANY TABLE               YES
SYSTEM     SELECT ANY TABLE               NO

到了这里,问题原因浮出水面:

with admin option

根据查询官方文档,发现有这么一段话:

You will get this ORA-1720 error when REPLACING a view that selects from some other user's tables and both of the following conditions are true:
 
- you have already granted select or other privileges on the VIEW to some other user
- the view owner does not have the GRANT option on the tables being selected from (or view owner may have some privilege with grant option but not others)
- 

The code was changed in 11.2.0.4 so that create view behavior is similar to grant. If you try to make a GRANT on an existing view and the view owner does not have the grant option, then ORA-1720 is the expected result (even in 11.2.0.3). In 11.2.0.4, we have simply made CREATE VIEW consistent with the GRANT behavior, i.e. if an incompatible grant exists, then the new view definition must not be allowed (even with FORCE). In other words, we do not allow incompatible grants to coexist with the view definition and so an error must be thrown. The behavior in release 11.2.0.3 (and earlier) was incorrect; the new behavior in 11.2.0.4 is intentional and correct. 

为了解决这一问题,建议对多用户表或者视图进行级联授权时:

1. 不要使用SYS用户执行类似操作
2. 使用常规方式进行相关授权
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342