PostgreSQL以什么顺序检查对象权限?


16

给定数据库角色,定义为存储过程user1的函数something()和创建的视图如下:

CREATE VIEW view1 AS select * from something()

并且,鉴于此权限:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

当我跑步时SELECT * FROM view1,出现错误permission denied for function something()

我的问题是,如果我撤消了对视图的选择权限,为什么要调用该函数?我期待收到类似的东西:

permission denied for relation view1

谢谢!


2
AFAIK没有检查权限的定义顺序。
克雷格·林格

@CraigRinger谢谢!我想那是预期的行为。当我在api中公开视图时,我试图避免透露视图的实现细节(给错误消息抱怨函数权限而不是视图)。
santios

1
我怀疑权限的评估方式与查询计划的方式几乎相同(例如,从下至上),因此,首先评估最低的对象,在您的情况下是something()函数。一种快速的测试是修改查询,以便您获得不同的解释计划,相应地调整权限,然后查看该something()函数是否引发了权限错误,或者是否遵循重新评估新执行计划的方式。
约翰·埃斯布雷纳

如果您授予该功能权限并在视图上吊销它们,则它应忽略对基础功能的任何提及
amenadiel

Answers:


3

在这种情况下,问题不完全与许可顺序有关,而与执行顺序有关。

在简历中,对于PostgreSQL:

1-访问表的视图将覆盖表权限

2-视图访问功能,在检查之前需要评估所有功能-因此即使视图没有选择权限,也必须在访问视图之前执行功能...

我们如何证明这一点?

在postgresql中,即使用户没有此权限,视图也可以为您提供在表中进行选择的权限。

例如:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

以用户1身份登录:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

在这种情况下,即使没有权限选择表,用户也可以选择view2。

但是如果我们对一个函数做同样的事情怎么办?行为一样。让我们创建一个在返回1之前等待5秒钟的函数(以便我们可以在每次调用视图时调试postgresql是否正在运行该函数)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

以用户1身份登录:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

在视图上执行选择的权限不会覆盖函数权限,甚至更糟的是,如果我们从view1撤消该权限,无论该视图的权限如何,该消息仍然显示postgresql由于该函数而停止了我们的查询。 (这正是问题所在)

但是是否真的要首先检查该功能?如果我们授予该功能“全部”权限,但撤消了查看权限...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

如您所见,在说我们没有输出视图的权限之前, postgresql 等待了5秒 ,表明执行了“ something()”函数。因此,在检查视图之前,必须存在函数数据返回。

因此,现在通过此测试,我们现在知道PostgreSQL需要在继续我们的查询之前首先评估所有功能,就像在所有涉及的功能完全完成之前查询仍然不存在一样,因此无法解决视图的问题,以解决PostgreSQL的问题。知道我们是否有权选择它。

我认为这以“许可顺序”的方式回答了您的问题,但是为什么postgresql在继续之前需要评估所有功能,这是另一个问题...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.