我正在努力理解Postgres中默认模式特权的工作方式。对我来说,它们应该通过自动发布权限来减轻管理负担,但是我发现它们有些用处。我从documentation中发现了一些根本不明显的东西。
我希望多个用户能够在架构中创建和修改对象。我创建了一个将成为所有者的角色,并将该角色授予多个(通常)用户:
create schema my_schema;
create role my_schema_owner;
alter schema my_schema owner to my_schema_owner;
create user my_user password 'xxx';
grant my_schema_owner to my_user;
create role my_role;
alter default privileges in schema my_schema grant execute on functions to my_role;
create function my_schema.my_func1() returns int as
$$ begin return 3; end; $$ language plpgsql;
请注意,我是使用我自己的(管理)帐户进行的。
接下来,我检查我得到了什么。我使用此视图:
create or replace view pg_functions_grants as
select proname, n.nspname, coalesce(nullif(s[1], ''), 'public') as grantee,
s[2] as privileges, s[3] as grantor
from pg_proc p
join pg_namespace n on n.oid = p.pronamespace
join pg_roles r on r.oid = p.proowner
join pg_type rt on p.prorettype = rt.oid,
unnest(coalesce(p.proacl::text[], format('{%s=arwdDxt/%s}', r.rolname, r.rolname)::text[])) acl,
regexp_split_to_array(acl, '=|/') s
并请求创建对象的权限:
select * from pg_functions_grants where proname = 'my_func1' order by 1;
my_func1 my_schema public X <me>
my_func1 my_schema <me> X <me>
my_func1 my_schema my_role X <me>
a)我们看到它已在func1上授予PUBLIC执行。可以,文档说它是默认设置。 b)它向我授予了执行许可。可以,但是由于我已经是所有者了,因此似乎很多余。 c)按照我的要求,将执行授予my_role。完美。
现在,我假装我是被授予所有权的用户:
set role my_user;
create function my_schema.my_func2() returns int as
$$ begin return 3; end; $$ language plpgsql;
select * from pg_functions_grants where proname = 'my_func2' order by 1;
my_func2 my_schema my_user arwdDxt my_user
d)为什么不授予PUBLIC执行权限?
e)为什么没有应用默认特权?
我试图弄清楚发生了什么事
create or replace view pg_namespaces_default_grants as
select n.nspname, r.rolname, d.defaclobjtype, coalesce(nullif(s[1], ''), 'public') as grantee,
s[2] as privileges, s[3] as grantor
from pg_default_acl d
join pg_namespace n on d.defaclnamespace = n.oid
join pg_roles r on r.oid = n.nspowner,
unnest(coalesce(d.defaclacl::text[], format('{%s=arwdDxt/%s}', r.rolname, r.rolname)::text[])) acl,
regexp_split_to_array(acl, '=|/') s;
select * from pg_namespaces_default_grants where nspname = 'my_schema';
my_schema my_schema_owner f my_role X <me>
嗯...我看到这里提到的授予者...这可能很重要吗?让我们在用户下设置默认值:
set role my_user;
alter default privileges in schema my_schema grant execute on functions to my_role;
create function my_schema.my_func3() returns int as
$$ begin return 3; end; $$ language plpgsql;
select * from pg_functions_grants where proname = 'my_func3' order by 1;
my_func3 my_schema public X my_user
my_func3 my_schema my_user X my_user
my_func3 my_schema my_role X my_user
现在它按预期工作了。
好吧,可能是它通过授予的角色继承了默认特权吗?
set role my_schema_owner;
alter default privileges in schema my_schema grant execute on functions to my_role;
set role my_user;
alter default privileges in schema my_schema revoke execute on functions from my_role;
让我们验证一下:
select * from pg_namespaces_default_grants where nspname = 'my_schema';
my_schema my_schema_owner f my_role X my_schema_owner
my_schema my_schema_owner f my_role X <me>
正确。现在:
set role my_user;
create function my_schema.my_func7() returns int as
$$ begin return 3; end; $$ language plpgsql;
select * from pg_functions_grants where proname = 'my_func7' order by 1;
my_func7 my_schema my_user arwdDxt my_user
该死,不是!
总结:默认特权仅在创建用户时(显式)设置了默认特权的用户有效,不在授予了以下角色的用户下有效:设置默认权限。
现在的问题:
在我找不到的文档中某个地方提到了以上事实吗?
为什么这么不方便?我可能会滥用它吗?有没有办法在架构中设置默认特权,该特权将对具有某些授予角色的每个用户都起作用?对于所有(现有的和将来的)用户?
PUBLIC的情况完全不清楚。为什么没有在d)中将EXECUTE授予PUBLIC?我进行了几次实验,发现如果用户为架构设置了任何个默认授予,则EXECUTE for PUBLIC会为他们增强。但是,如果没有默认特权,则不会在函数上授予PUBLIC EXECUTE。在我看来,这完全不合逻辑。对此有解释吗?
答案 0 :(得分:2)
我将尽力回答最后提出的问题:
ALTER DEFAULT PRIVILEGES [ FOR { ROLE | USER } target_role [, ...] ] [ IN SCHEMA schema_name [, ...] ] abbreviated_grant_or_revoke
target_role
当前角色是成员的现有角色的名称。如果省略
FOR ROLE
,则假定当前角色。
您总是为某个角色定义默认权限 ,即,特权仅在该角色创建对象时适用。
就是这样。最好的办法是只允许一个角色在架构中创建对象。
任何授予的特权都会添加到现有特权中。
所有功能都是使用EXECUTE
的{{1}}特权创建的,我不相信d)中的结果。为此,您必须提出一个简单的可复制测试用例。
更改的唯一方法是拥有撤销 PUBLIC
特权的默认特权(不限于架构!)。