【发布时间】:2020-01-08 12:14:30
【问题描述】:
在 PostgreSQL 10 上,我有一个名为 tn_schema 的架构和一个名为 tn_beta_db 的数据库。我想是的,虽然我必须连接到相关数据库才能看到架构:
[T] jeff@nantes-4:~ $ sudo su postgres -c psql
psql (10.10 (Ubuntu 10.10-0ubuntu0.18.04.1))
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 |
template0 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
tn_beta_db | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 |
(4 rows)
postgres=# \dn
List of schemas
Name | Owner
--------+----------
public | postgres
(1 row)
postgres=# \c tn_beta_db
You are now connected to database "tn_beta_db" as user "postgres".
tn_beta_db=# \dn
List of schemas
Name | Owner
-----------+----------
public | postgres
tn_schema | postgres
(2 rows)
tn_beta_db=#
现在奇怪的是,我想授予一个用户在此架构上创建表的权利,并对这些表执行任何必要的操作。所以我输入这个:
tn_beta_db=# ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema GRANT ALL ON TABLES TO tn_beta_migrator;
ALTER DEFAULT PRIVILEGES
tn_beta_db=#
而且反应让我觉得一切都很好。虽然当我查询时,
tn_beta_db=# \du
List of roles
Role name | Attributes | Member of
------------------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
tn_beta_migrator | | {}
tn_beta_reader | | {}
tn_beta_writer | | {}
tn_beta_db=#
看起来我什么都没做。而且,确实,当我以用户 tn_beta_migrator 连接时,我发现我无法在 tn_schema 中创建表:
[T] jeff@nantes-4:~ $ psql --username tn_beta_migrator --host localhost tn_beta_db
Password for user tn_beta_migrator:
psql (10.10 (Ubuntu 10.10-0ubuntu0.18.04.1))
Type "help" for help.
tn_beta_db=> create table foo();
CREATE TABLE
tn_beta_db=> drop table foo;
DROP TABLE
tn_beta_db=> create table tn_schema.foo();
ERROR: permission denied for schema tn_schema
LINE 1: create table tn_schema.foo();
^
tn_beta_db=>
我会注意到我也尝试过这个,这不会改变结果:
GRANT ALL ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_migrator;
关于我误解了什么的任何指针?
更新
需要说明的是,我有三个用户:一个是只读的,一个是只读的,另一个是具有完整表修改权限的。目标是允许用户创建的表可以被读取器读取,并且可以被读写器读写。
根据反馈,我发出了以下命令:
-- Connect to the correct db, as schemas are part of databases.
\c tn_beta_db
-- For future tables, these are the privileges I want to see. Note
-- that I need to alter the privileges for the role in question,
-- even though I grant to the role as well.
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_reader \
GRANT SELECT ON TABLES TO tn_beta_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_writer \
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO tn_beta_writer;
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_migrator \
GRANT ALL ON TABLES TO tn_beta_migrator;
-- This wasn't a problem, but to be explicit, I do want
-- all three roles to be able to connect.
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_reader;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_writer;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_migrator;
-- While I'm doing this at a time when there are not yet any tables
-- in the database, it would be good to for this script to work
-- even at some later time. So here I grant the appropriate rights
-- to those tables that might already exist, as ALTER DEFAULT
-- does not change privileges for existing tables.
GRANT SELECT ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_reader;
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_writer;
GRANT ALL ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_migrator;
-- And finally, I note that this role is allowed to create tables.
GRANT CREATE ON SCHEMA tn_schema TO tn_beta_migrator;
通过这些修改,tn_beta_migrator 能够创建表,但不能从中选择、插入或更新,也不能再次删除它们。
更新:解决方案
根据@laurenz-albe 的建议,我做了一个新的最小示例here。这导致了一个答案。对于那些关注的人,问题是我忘记授予使用权限:
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_migrator;
【问题讨论】:
-
更改默认权限不会改变现有表的任何实际权限,它只会在某个用户创建新表时默认分配权限。
-
对,但我在任何人创建表之前执行了权限更改。那我还是不能建表。
-
GRANT ALL ON TABLES不包含创建表的权限,表对象的授权用于使用该表。请参阅postgresql.org/docs/current/ddl-priv.html - 表创建权限是模式对象的一部分。 -
谢谢!这确实让我可以将表创建为 tn_beta_migrator。但仍然禁止选择、插入、更新和删除。
标签: postgresql