Postgresql:noInherit不工作?

时间:2018-01-14 04:01:07

标签: database postgresql database-administration

所以,我试图弄清楚如何正确管理postgresql数据库。 我是postgres和DBA的新成员。

我目前正在尝试为特定数据库设置专用角色。 我还想让其他用户拥有该角色的授权,这样我就可以SET ROLE my_db_role并且能够从那里操作这个特定的数据库。 但是,我已经获得了权限泄漏,这意味着我可以操作我的数据库而无需执行此SET ROLE my_db_role命令。

以下是我为获取不成功结果而执行的命令:

=# CREATE ROLE test NOINHERIT;
=# CREATE USER myuser;
=# CREATE DATABASE test OWNER test;
=# \c test
=# DROP SCHEMA public;
=# CREATE SCHEMA AUTHORIZATION test;
=# GRANT test TO myuser;
=# \c test myuser
=> CREATE TABLE test.mytable(id integer);
CREATE TABLE
Temps : 46,469 ms

为什么最后的命令成功了?

在我看来,myuser应该对测试数据库/模式没有权利,因为测试角色具有NOINHERIT标志,因此不应该使用此CREATE命令。 它应该需要SET ROLE test才能成功,而这并非如此。

我错过了什么?

在旁注中,除了官方文档之外,我很难找到关于如何正确管理postgresql的良好信息来源。如果你能分享一些关于它的好材料,那么你非常欢迎。

2 个答案:

答案 0 :(得分:1)

我担心我不知道任何特别好的资源涵盖角色管理和管理。这里的标准显示了必须取悦几个利益相关者的所有迹象,并且灵活但令人困惑。

关于你当前的问题,问题在于“NOINHERIT”是错误的角色。但是,此功能实际上并不是安全约束。

test=# ALTER USER myuser NOINHERIT;
test=# \c - myuser
You are now connected to database "test" as user "myuser".
test=> CREATE TABLE test.mytable(id int);
ERROR:  permission denied for schema test
LINE 1: CREATE TABLE test.mytable(id int);
                     ^
test=> SET ROLE test;
SET
test=> CREATE TABLE test.mytable(id int);
CREATE TABLE

正如您所看到的,myuser不会继承test的权限,但没有什么可以阻止您直接切换到该角色。

如果你发现这个令人费解并且令人困惑,那么你就远远不是孤军奋战。我发现添加一些tests来检查我设置的任何配置都很有用。

答案 1 :(得分:0)

因为test是数据库的所有者,所以它在后续对象上基本上拥有它的所有权限。

正如@Richard Huxton所指出的,在NOINHERIT角色上设置test会阻止它继承其他角色,但不会阻止其特权被继承到其他角色。

发出时:

GRANT test TO myuser;

您只需向myuser授予与所有者相同的权限,因此myuser可以创建对象,实际上它可以执行所有者可以做的任何事情。

这不是PostgreSQL的问题,它是所有权的运作方式。无论如何,你可以明确地撤销所有者的特权(例如,不要误删除重要的对象)。

但是您应该考虑角色myuser的其他权限策略,使其不是从所有者继承而是仅仅授予其所需的权限。如果用户可以创建一个表,那么应该祝福:

GRANT CREATE ON SCHEMA test TO myuser;

我知道你对PostgreSQL权限管理有点失望,在恳求中,通过文档似乎很难理解。为了更好地了解它的实际工作原理,您应该发出:

REVOKE ALL ON DATABASE test FROM public; 

然后,所有角色都需要CONNECTSCHEMA USAGE的显式权限。然后,您将发现对象和特权之间的依赖关系。正在阅读越来越多的GRANT页面就足够了,即使它很简洁。

关于SET ROLE安全“问题”,它仅限于当前角色所属的所有角色:

  

指定的role_name必须是当前会话用户的角色   是...的成员。 (如果会话用户是超级用户,则可以是任何角色   地选择。)

因此,用户无法覆盖其权限,它只能支持已授予的其他身份。