PostgreSQL 权限不继承:数据库 owner ≠ schema owner ≠ table owner
这一点跟SQL Server非常不一样。
SUPERUSER跟SQL Server的sysadmin一样,最高权限。
instance level:
--https://www.postgresql.org/docs/18/role-attributes.html
CREATE ROLE name SUPERUSER;
CREATE ROLE name CREATEDB;
CREATE ROLE name CREATEROLE;
CREATE ROLE name REPLICATION LOGIN;
CREATE ROLE name LOGIN;
CREATE ROLE name PASSWORD 'string';
CREATE ROLE name NOINHERIT; ---默认是INHERIT
CREATE ROLE name BYPASSRLS;
CREATE ROLE name CONNECTION LIMIT 'integer'; -- "-1"(the default) means no limit.
sql
-- View all roles and their instance-level privileges
SELECT
rolname,
rolsuper,
rolinherit,
rolcreaterole,
rolcreatedb,
rolcanlogin,
rolreplication,
rolconnlimit,
rolbypassrls
FROM pg_roles;
--Predefined Roles
--https://www.postgresql.org/docs/18/predefined-roles.html
pg_monitor
pg_read_all_settings
pg_read_all_stats
pg_stat_scan_tables
pg_signal_backend
pg_checkpoint
pg_use_reserved_connections
pg_read_server_files
pg_write_server_files
pg_execute_server_program
pg_database_owner
pg_read_all_data
pg_write_all_data
pg_create_subscription
pg_maintain
pg_signal_autovacuum_worker
--database level
CONNECT
CREATE
TEMPORARY
ALL
--ALL指的是拥有上面3个权限
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }ON DATABASE database_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
GRANTED BY role_specification
--https://www.postgresql.org/docs/18/functions-info.html
has_database_privilege ( [ user name or oid, ] database text or oid, privilege text ) → boolean
Does user have privilege for database?
Allowable privilege types are CREATE, CONNECT, TEMPORARY, and TEMP (which is equivalent to TEMPORARY).
sql
--默认设置下,任何一个用户都可以连接到新建的数据库,因为默认connect权限是给到public的。
--可以用以下命令收回权限:
revoke connect on database mydb from public;
sql
SELECT
datname,
r.rolname as grantee,
has_database_privilege(r.rolname, datname, 'CONNECT') as connect_priv,
has_database_privilege(r.rolname, datname, 'CREATE') as create_priv,
has_database_privilege(r.rolname, datname, 'TEMPORARY') as temp_priv
FROM pg_database d
CROSS JOIN pg_roles r
WHERE --d.datname = 'mydb' AND
r.rolname NOT LIKE 'pg_%'
ORDER BY r.rolname;
PostgreSQL 权限不继承:数据库 owner ≠ schema owner ≠ table owner
这一点跟SQL Server非常不一样。
举个简单的例子:
例1:
用户ccc创建了数据库db3,
用户ddd在上面建了个schema db3,然后创建了表t1.
结果用户ccc没权限查询db3.t1这张表。
You are now connected to database "db3" as user "ccc". ^
db3=> select * from db3.t1;
ERROR: permission denied for schema db3
LINE 1: select * from db3.t1;
^
db3=>
例2:
---用ddd用户连接,ddd是schema的owner,没权限读db3.t2,但可以删掉表db3.t2,真的太不一样了!!
db3=> select * from db3.t2;
ERROR: permission denied for table t2
db3=> \dt db3.*
List of tables
Schema | Name | Type | Owner
--------+------+-------+-------
db3 | t1 | table | ddd
db3 | t2 | table | eee
(2 rows)
db3=> drop table db3.t2;
DROP TABLE
db3=>