即使在运行 GRANT ALL to role 之后,使用 SECURITY DEFINER 调用函数时权限被拒绝
Posted
技术标签:
【中文标题】即使在运行 GRANT ALL to role 之后,使用 SECURITY DEFINER 调用函数时权限被拒绝【英文标题】:Permission denied when calling a function when using SECURITY DEFINER even after GRANT ALL to role has been run 【发布时间】:2019-09-07 22:12:07 【问题描述】:运行下面的 SQL 我遇到了权限问题。
[42501] 错误:模式 myschema 的权限被拒绝其中:PL/pgSQL 函数 >myschema.test_func() SQL 语句的第 8 行
我需要授予什么权限才能允许 SECURITY DEFINER 选择/执行功能。所有权限似乎都不起作用。
看着https://www.postgresql.org/docs/current/sql-grant.html,我看不出还有什么可以让我完成这项工作的。
我正在使用 Postgresql 11。显然,如果我让 myrole 成为超级用户,它就可以正常工作。即使将赠款放在最后也会产生相同的错误。
编辑:
我没有很好地解释。问题不是创建函数我在调用以下行时遇到问题:
SELECT myschema.test_func_2('foo', 'bar') INTO l_table_result;
函数的创建工作正常,只有当我运行select myschema.test_func();
时才会得到SQL 错误。
我看不到 myrole 需要什么其他权限才能调用另一个函数。
CREATE ROLE myrole WITH NOLOGIN;
CREATE SCHEMA IF NOT EXISTS myschema;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschema TO myrole ;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA myschema TO myrole ;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA myschema TO myrole ;
CREATE OR REPLACE
FUNCTION myschema.test_func()
RETURNS BOOLEAN
SECURITY DEFINER
LANGUAGE plpgsql
AS $$
DECLARE
l_table_result BOOLEAN;
BEGIN
RAISE LOG 'Will Get This Far ... ';
SELECT myschema.test_func_2('foo', 'bar') INTO l_table_result;
RAISE LOG 'But Not This Far';
RETURN TRUE;
END;
$$;
/* OWNERSHIP AND PERMISSIONS*/
ALTER FUNCTION myschema.test_func OWNER to myrole;
CREATE OR REPLACE
FUNCTION myschema.test_func_2(
p_foo VARCHAR(10),
p_bar VARCHAR(10)
)
RETURNS BOOLEAN
SECURITY DEFINER
LANGUAGE plpgsql
AS $$
BEGIN
RETURN TRUE;
END;
$$;
/* OWNERSHIP AND PERMISSIONS*/
ALTER FUNCTION myschema.test_func_2(VARCHAR, VARCHAR) OWNER to myrole;
select myschema.test_func();
【问题讨论】:
【参考方案1】:您需要架构上的CREATE
权限,才能在该架构中创建新对象。
因此GRANT ALL ON SCHEMA myschema to myrole;
授予myrole
创建此功能的权利。此GRANT
的文档也在您链接的页面上。
不管怎样,你刚刚在你的脚本中创建了这个用户,我猜你当时没有和这个用户连接到数据库,所以你可以在创建函数之前添加SET ROLE myrole;
。你可以在之后杀死ALTER FUNCTION
,尽管有时你可能想保留它,这是你的决定。
最后一句话:如果您尝试使用 SECURITY DEFINER
和 ALTER FUNCTION
的组合来获得一个以真正发出 CREATE FUNCTION
的用户身份执行的函数(如果您故意不这样做,可能会发生什么) SET ROLE
),这是行不通的。如here 所述,权限检查是针对拥有该功能的用户,而不是创建它的用户。
编辑:从评论中回答,确实解决了(编辑的)问题
尽管创建是可能的(也许只是您通过ALTER FUNCTION
选择的方式,而不是通过CREATE FUNCTION
和用户myrole
)并且您可以调用该函数,在您作为用户myrole
和函数myschema.test_func_2
的查找由他执行,因此myrole
至少需要架构上的USAGE
权限。
【讨论】:
感谢问题不是创建函数问题是当函数运行时(即使通过超级用户帐户),SQL 错误显示与此行SELECT myschema.test_func_2('foo', 'bar') INTO l_table_result;
运行。函数创建得很好,这是我遇到问题的执行。
由于指定了SECURITY DEFINER
,因此通过超级用户调用该函数应该没有什么不同,因此预计您在两种设置中都会出现错误(或没有错误)。尽管创建是可能的(也许只是您通过ALTER FUNCTION
而不是通过CREATE FUNCTION
和用户myrole
选择的方式)并且您可以调用该函数,在函数内部您作为用户myrole
和查找函数myschema.test_func_2
由他执行,因此myrole
至少需要架构上的USAGE
权限。您是否尝试过授予它?
GRANT USAGE 已对其进行排序。我在想这是一个功能级别的问题,但它是一个模式级别。非常感谢。以上是关于即使在运行 GRANT ALL to role 之后,使用 SECURITY DEFINER 调用函数时权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章
Security10:Grant object Permission to DB Role or User
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant
Mysql grant all privileges on ...不生效解决方案
grant all privileges on *.* to root@"%" identified by ".";报错问题