你应该知道的数仓安全:都是同名Schema惹的祸

应该,知道,安全,同名,schema · 浏览次数 : 424

小编点评

## 摘要 本文探讨了同名Schema如何导致管理员权限不足的问题以及如何解决权限报错的方法。 **主要内容:** * 同名Schema是私有Schema,所有对象所有者都是用户自己。 * 当管理员在私有Schema下创建对象时,对象所有者会切换到用户本身。 * 视图规则会按照视图Owner对基表做权限检查,当私有Schema的Owner切换到用户本身时,视图规则会无法对其进行权限检查。 * 权限报错的原因是由于视图规则要求对基表按照视图Owner做权限检查,而私有Schema的Owner切换到用户本身,导致无法执行视图操作。 * 解决权限报错的方法是授予用户相应的权限,使其成为视图的owner或基表的owner。 **总结:** 同名Schema是私有Schema,需要在创建对象时指定Owner才能拥有对象的所有权。当管理员在私有Schema下创建对象时,对象所有者会自动切换到用户本身,导致视图规则无法对其进行权限检查,从而导致权限报错。解决权限报错方法是授予用户相应的权限使其成为视图的owner或基表的owner。

正文

摘要:我是管理员账号,怎么还没有权限?当小伙伴询问的时候,我第一时间就会想到都是用户同名Schema惹的祸

本文分享自华为云社区《你应该知道的数仓安全——都是同名Schema惹的祸》,作者: zhangkunhn 。

典型场景

经常遇到小伙伴问到:

  • 我是管理员账号,怎么还没有权限?
  • 管理员给我赋权了啊,怎么还没有权限?

当小伙伴询问的时候,我第一时间就会想到都是用户同名Schema惹的祸。

同名Schema是私有Schema

我们知道,CREATE USER语法在创建用户的同时会在当前数据库中创建一个与用户同名的SCHEMA。这个Schema很特殊,只有两种用户能在这个Schema下面创建表、视图、函数等对象:

  1. 用户自己
  2. 管理员

然而,不管谁创建的,对象的所有者(Owner)都是用户自己。基于这个事实,我们可以称用户同名Schema为私有Schema。私有表明了当前Schema的特殊性,在这个Schema下面的所有对象都是这个用户自己的,不管是谁创建的。

我们来看一个例子。数据库中有三个用户,如表所示。

使用管理员dbadmin执行以下SQL:

 gaussdb=# create table ua.ta (c1 int);
 CREATE TABLE
 gaussdb =# select relname, relowner, rolname from pg_class c, pg_authid a where relname = 'ta' and c.relowner= a.oid;
 relname | relowner | rolname 
 ---------+----------+---------
  t1      | 16546 | ua(不是dbadmin)
 (1 row)

可以看到:系统管理员在普通用户同名schema下创建的对象,所有者为schema的同名用户

让我们来总结第一点:同名Schema是私有Schema,这个Schema下面的所有对象的所有者都是用户自己,不管是谁创建的。管理员在私有Schema下创建的表等对象会发生Owner切换。

视图规则:按照view的owner做权限检查

再来谈视图和视图封装的基表的权限。视图对基表的权限检查是按照视图的Owner做权限检查。例如

create view v1 as select * from t1;

用户执行select * from v1时做权限检查分为两步:

  1. 首先检查当前用户对视图v1的SELECT权限;
  2. 然后检查视图v1的owner对基表t1的SELECT权限。

而不是直接检查当前用户对基表t1的SELECT权限。

总结第二点:视图会按照视图的Owner对基表做权限检查。

私有Schema与视图规则导致莫名其妙的权限报错

由于私有Schema会造成Owner切换,而视图规则要求对基表按照视图Owner做权限检查。那么在私有Schema下面创建视图就会导致莫名其妙的现象:

私有Schema + view规则 --> 管理员无权限访问自己创建的视图。

 gaussdb =# set role dbadmin password ‘*******’; -- 切换到管理员用户
 SET
 gaussdb => create table ua.ta (c1 int); -- 表ta的owner是???
 CREATE TABLE
 gaussdb => create view ub.vb as select * from ua.ta; -- 视图vb的owner是???
 CREATE VIEW
 gaussdb => select * from ub.vb; -- 管理员创建的view,他竟然无权限!!!
 ERROR: SELECT permission denied to user “ub” for relation “ua.ta“ 

我们以管理员用户在用户ua的私有schema下创建表ta, 之后在用户ub的schema下创建了视图vb, 视图vb的基表是ua.ta。管理员执行对视图vb的查询,报错无权限。

对于这个莫名其妙的现象,我们仔细捋一捋其中的来龙去脉。

  1. 根据私有Schema切换Owner的法则,尽管是管理员创建的,ta的owner切换到ua, 同样vb的owner应该是u2.
  2. 结合view规则,对基表按照视图Owner做权限检查,视图vb的owner对基表ua.ta是否具有select权限。视图vb的owner是ub,而ub对ua.ta无select权限,因此查询报错。

权限报错消除

如何解决这种权限报错呢?从上述梳理中,其实已经明白了如何赋权来消除这种报错。那就是给视图的owner用户ub赋予基表ua.ta的SELCT权限:管理员或者用户ua执行下面的赋权语句即可。

 GRANT SELECT on ua.ta to ub; 

有小伙伴 问了,我每次都这么仔细捋一捋,感觉很浪费时间,有没有简单的方法。答案是有的,只需从查询的权限报错着手,不需要每次都捋一捋。

我们当前的权限报错有着非常完备的提醒,会给用户显示如下提示:

SELECT permission denied to user “user_name” for relation “ schema_name.table_name

可以看到,权限报错包括哪个权限、哪个用户、哪个schema的哪个对象。那么看到这个之后,可以直接找管理员或者Owner来执行授予操作就可以了。

对于上述报错,直接就对应到赋权语句:

grant SELECT on schema_name.table_name to user_name;

当然这个赋权跟我们前面的分析是殊途同归的。

现在来回想下,是不是一切都清晰了。那么我们再来看一遍示例。以管理员dbadmin执行以下SQL语句。

 gaussdb => create table ua.ta (c1 int); -- ta的owner是ua
 CREATE TABLE
 gaussdb => create view ub.vb as select * from ua.ta; -- vb的owner是ub
 CREATE VIEW
 postgres=# select * from ub.vb; -- 按照报错的指引来
 ERROR: SELECT permission denied to user “ub” for relation “ua.ta“ 
 gaussdb =# grant usage on schema ua to ub; -- 将schema ua和基表ta的权限给ub
 GRANT
 gaussdb =# grant select on ua.ta to ub;
 GRANT
 postgres=# select * from ub.vb; -- 权限检查通过,可以正常查询
  c1 
 ----
 (0 rows)

补充知识:

  1. CREATE USER语法在创建用户的同时会在当前数据库中,为该用户创建一个同名的SCHEMA;其他数据库中,则不会创建同名的SCHEMA;如果需要,可使用create schema authorization user_name语法,该语法会根据用户名来创建同名schema。
  2. 为什么用户同名Schema这么特殊,别的Schema没有这些特点?因为:a) 在创建用户时同时创建了与用户同名的Schema,并将Schema的owner设置为同名用户;b) 在创建对象时,如果创建对象的schema是用户同名Schema,就会将对象的Owner切换为同名用户,而不是执行SQL语句的当前用户。

总结

遇到权限报错第一时间想到是否涉及同名schema。同名Schema是用户的私有Schema。私有Schema中所有的对象Owner都是用户自己,不管是谁创建的。在私有Schema中创建对象,对象Owner会切换到同名用户。视图规则是按照视图Owner来检查对基表的权限。由于私有Schema的Owner切换机制和视图规则导致了同名Schema的权限报错。根据报错的提示,授予用户相应的权限就可以解决权限报错问题。

 

点击关注,第一时间了解华为云新鲜技术~

与你应该知道的数仓安全:都是同名Schema惹的祸相似的内容:

你应该知道的数仓安全:都是同名Schema惹的祸

摘要:我是管理员账号,怎么还没有权限?当小伙伴询问的时候,我第一时间就会想到都是用户同名Schema惹的祸 本文分享自华为云社区《你应该知道的数仓安全——都是同名Schema惹的祸》,作者: zhangkunhn 。 典型场景 经常遇到小伙伴问到: 我是管理员账号,怎么还没有权限? 管理员给我赋权了

[转帖]你应该知道的Shell 脚本的经典十三问

https://blog.csdn.net/wangzhicheng987/article/details/131031344 1. 为何叫做shell? 我们知道计算机的运作不能离开硬件,但使用者却无法直接操作硬件,硬件的驱动只能通过一种称为操作系统(OS,Opertating System)的软

FAQ 关于pip你应该知道的一些技巧

pip简介 pip是安装了python之后的一个应用程序,包管理程序,有点类似于yum、npm、apt等工具 物理位置一般是python.exe所在目录下的scripts下 以我为例,我Python安装在D:\Python39\下,那么pip就在D:\Python39\Scripts 而这个工具所在

2024好用的项目管理软件有哪些?这10款最火国内项目管理工具你应该知道

不管是大公司还是小公司,如果想提高企业运作效率、规范管理并且高效且实用的项目管理工具,对项目流程进行把控、及时共享工作进度,从而让工作变得更有效率。那么一款好用的项目管理工具必不可少。然而面对市场上这么多的项目管理工具,你是否感到疑惑,不知道选择哪款项目管理软件好?那么在本文中我们挑选了10款最优秀

漫谈Python魔术方法,见过的没见过的都在这里了

漫谈Python魔术方法,见过的没见过的都在这里了 就说一下,不深入 假的一览 提到魔术方法,学过python都应该知道一些。至少你得会__init__吧。 在我之前写的博文中有很多都涉及魔术方法。比如 浅谈Python中的if,可能有你不知道的,涉及__bool__和__len__ 浅谈Pytho

[转帖]《Linux性能优化实战》笔记(23)—— 内核线程 CPU 利用率过高,perf 与 火焰图

在排查网络问题时,我们还经常碰到的一个问题,就是内核线程的 CPU 使用率很高。比如,在高并发的场景中,内核线程 ksoftirqd 的 CPU 使用率通常就会比较高。回顾一下前面学过的 CPU 和网络模块,你应该知道,这是网络收发的软中断导致的。 要分析 ksoftirqd 这类 CPU 使用率比

一个库帮你轻松的创建漂亮的.NET控制台应用程序

前言 做过.NET控制台应用程序的同学应该都知道原生的.NET控制台应用程序输出的内容都比较的单调,假如要编写漂亮且美观的控制台输出内容或者样式可能需要花费不少的时间去编写代码和调试。今天大姚给大家分享一个.NET开源且免费的类库帮你轻松的创建漂亮、美观的.NET控制台应用程序:Spectre.Co

[转帖]Kafka需要知道的一些基础知识点

`https://blog.csdn.net/daima_caigou/article/details/109101405` 前言 kafka是常用MQ的一种,站在使用者的角度来看待,kafka以及所有的MQ应该是这样的: (注意箭头的方向) 这个一点问题都没有,即使你站在MQ的开发者的角度,这个图

[转帖]为什么网络 I/O 会被阻塞?

https://my.oschina.net/lenve/blog/5952439 我们应该都知道 socket(套接字),你可以认为我们的通信都要基于这个玩意,而常说的网络通信又分为 TCP 与 UDP 两种,下面我会以 TCP 通信为例来阐述下 socket 的通信流程。 不过在此之前,我先来说

不抖机灵!让工程师来告诉你做芯片是如何烧钱的!

这是IC男奋斗史的第33篇原创 本文3742字,预计阅读8分钟。 大家应该都知道做芯片是一件非常烧钱的事情。经常看到新闻通稿,某某公司融资了xx亿,外行乍看之下觉得好多钱啊,但实际上可能只够该公司烧一年。那么做芯片到底有多烧钱?钱都花在哪哪些地方了?这篇文章杰哥将从芯片设计公司的角度切入,详细讲解芯