暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

静态数据字典视图的内部实现

原创 Eygle 2019-07-24
477

既然以上提到的这三类字典都是视图(VIEW),那这些视图是怎样建立起来的?又是如何实现的权限控制呢?我们一起来探索一下Oracle的实现。

通常USER_类视图不包含Owner字段,查询潜在的返回当前用户的对象信息,我们以USER_TABLES视图为例(篇幅原因,省略了部分内容)看一下其创建及结构:

create or replace view USER_TABLES
    (TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME,
     PCT_FREE, PCT_USED,
    …….
     DEGREE, INSTANCES, CACHE, TABLE_LOCK,
     SAMPLE_SIZE, LAST_ANALYZED, PARTITIONED,
     IOT_TYPE, TEMPORARY, SECONDARY, NESTED,
     BUFFER_POOL, ROW_MOVEMENT,
     GLOBAL_STATS, USER_STATS, DURATION, SKIP_CORRUPT, MONITORING,
     CLUSTER_OWNER, DEPENDENCIES, COMPRESSION)
as
select o.name, decode(bitand(t.property, 4194400), 0, ts.name, null),
       decode(bitand(t.property, 1024), 0, null, co.name),
       ……
from sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o,
     sys.obj$ cx, sys.user$ cu
where o.owner# = userenv('SCHEMAID')
  and o.obj# = t.obj#
  …..
  and t.dataobj# = cx.obj# (+)
  and cx.owner# = cu.user# (+)
/

我们注意到Where条件中有这样一个限制:

where o.owner# = userenv('SCHEMAID')

这就限制了当前查询只返回当前用户的SCHEMA对象信息。

而对于ALL_TABLES视图,在Where子句中,关于用户部分,增加了这样一个条件:

  and (o.owner# = userenv('SCHEMAID')
       or o.obj# in
            (select oa.obj#
             from sys.objauth$ oa
             where grantee# in ( select kzsrorol
                                 from x$kzsro
                               )
            )
       or /* user has system privileges */
         exists (select null from v$enabledprivs
                 where priv_number in (-45 /* LOCK ANY TABLE */,
                                       -47 /* SELECT ANY TABLE */,
                                       -48 /* INSERT ANY TABLE */,
                                       -49 /* UPDATE ANY TABLE */,
                                       -50 /* DELETE ANY TABLE */)
                 )
      )

这个条件扩展了关于用户有权限访问的对象信息,所以实际上USER_TABLES的结果是ALL_TABLES结果的一个子集。

DBA_TABLES视图的Where条件中,则没有关于Owner的限制,所以查询返回了数据库中所有表的信息:

where o.owner# = u.user#
  and o.obj# = t.obj#
  and bitand(t.property, 1) = 0
  and t.bobj# = co.obj# (+)
  and t.ts# = ts.ts#
  and t.file# = s.file# (+)
  and t.block# = s.block# (+)
  and t.ts# = s.ts# (+)
  and t.dataobj# = cx.obj# (+)
  and cx.owner# = cu.user# (+)
/

这就是这几类数据字典视图的区别所在,也就是Oracle实现权限隔离的方式。


最后修改时间:2019-07-24 10:42:23
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论