调用没有其他功能许可的功能

时间:2016-05-27 15:15:08

标签: postgresql function permissions

假设我们有两个功能。首先应检查权限,如果一切顺利更新表。这是:

CREATE OR REPLACE FUNCTION public.clients_test(
_clientid int
,_comments varchar
)
  RETURNS void AS
$BODY$
declare _result varchar;
BEGIN

if now()::time>'17:00'::time then
    select public.clients_check_17_00() into _result;
end if;

update clients set comments=_comments where clientid=_clientid;

END
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER
  COST 1;
ALTER FUNCTION public.clients_test(int, varchar) OWNER TO postgres;
GRANT EXECUTE ON FUNCTION public.clients_test(int, varchar) TO postgres;
GRANT EXECUTE ON FUNCTION public.clients_test(int, varchar) TO "RestrictedAccess";
REVOKE ALL ON FUNCTION public.clients_test(int, varchar) FROM public;

第二个函数对数据库不执行任何操作,仅出于安全原因而存在。我打算从第一个打电话给它。这是:

CREATE OR REPLACE FUNCTION public.clients_check_17_00()
  RETURNS void AS
$BODY$
BEGIN

END
$BODY$
  LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
  COST 1;
ALTER FUNCTION public.clients_check_17_00()OWNER TO postgres;
GRANT EXECUTE ON FUNCTION public.clients_check_17_00() TO postgres;
GRANT EXECUTE ON FUNCTION public.clients_check_17_00() TO "FullAccess";
REVOKE ALL ON FUNCTION public.clients_check_17_00() FROM public;

有些用户只需要在17:00之前更新评论。所以他们有权限

public.clients_test

并且没有

的权限
public.clients_check_17_00

我想输入错误'你没有权限执行public.clients_check_17_00',但这不起作用。

1 个答案:

答案 0 :(得分:0)

这是一个有趣的问题,但你的方法都是错的。

您应该操作该函数的外部权限,而不是检查内部的时间。在你的方法中,每次通话都会检查时间,也就是在08:02,14:23,16:34等,由于显而易见的原因这是非常低效的。相反,制作两个简单的SQL脚本文件,一个用于禁用该功能的执行权限,另一个用于再次启用这些权限,并让计划的作业在17:00运行这些脚本,然后大概在08:00左右重新启用执行允许。它可以很简单:

psql -h localhost -d your_db -U postgres \
     -c 'REVOKE EXECUTE ON FUNCTION clients_test(int, varchar) FROM "RestrictedAccess"'

反之亦然,再次启用权限。但请参阅documentation了解访问服务器的特定参数。

究竟如何运作取决于您的操作系统;在Linux中,您将使用cron作业,在Windows上使用任务计划程序。

顺便说一句,将函数中的消息返回到会话是使用RAISE NOTICE完成的。

您的代码中的另一个要点:永远不要使用postgres作为对象或运行代码的角色。为 EMPHASIS 道歉,但这一点不够强调。您应该将非特权角色(最好没有login权限)作为所有对象(表和函数等)的所有者,然后为特定用户角色显式设置权限。