PostgreSQL:列表数据库用户具有连接权限

时间:2017-06-08 00:46:55

标签: sql database postgresql

如何仅列出用户对PostgreSQL具有CONNECT权限的数据库?

例如,user1可以访问数据库db1,而user2可以访问db2

当这些用户中的每一个登录/连接到他们的数据库并且他们需要检索他们可以连接的数据库列表时。

以下是我迄今所做的事情:

在我的新prostgreSQL服务器上创建了两个数据库db1db2

CREATE DATABASE db1
    WITH 
    OWNER = admin
    ENCODING = 'WIN1252'
    CONNECTION LIMIT = -1;

CREATE DATABASE db2
    WITH 
    OWNER = admin
    ENCODING = 'WIN1252'
    CONNECTION LIMIT = -1;

我还创建了两个新用户(管理员除外)user1user2

CREATE USER user1 WITH LOGIN ENCRYPTED PASSWORD 'user1';
CREATE USER user2 WITH LOGIN ENCRYPTED PASSWORD 'user2';

然后,我运行了以下查询,将user1作为db1user2的所有者作为db2

的开头
BEGIN;
ALTER DATABASE db1 owner to user1;
REVOKE CONNECT ON DATABASE db1 FROM public; 
GRANT CONNECT ON DATABASE db1 TO user1;
COMMIT

BEGIN;
ALTER DATABASE db2 owner to user2;
REVOKE CONNECT ON DATABASE db2 FROM public; 
GRANT CONNECT ON DATABASE db2 TO user2;
COMMIT

这种方式user1无法连接到db2user2无法连接到db1

运行此查询

SELECT datname , (aclexplode(datacl)).grantor,
       (aclexplode(datacl)).grantee,
       (aclexplode(datacl)).privilege_type,
       (aclexplode(datacl)).is_grantable FROM pg_database

给出了这个:

 datname | grantor | grantee | privilege_type | is_grantable
---------+---------+---------+----------------+--------------
 db1     |   16386 |       0 | TEMPORARY      | f
 db1     |   16386 |   16386 | CREATE         | f
 db1     |   16386 |   16386 | TEMPORARY      | f
 db1     |   16386 |   16386 | CONNECT        | f
 db2     |   16387 |       0 | TEMPORARY      | f
 db2     |   16387 |   16387 | CREATE         | f
 db2     |   16387 |   16387 | TEMPORARY      | f
 db2     |   16387 |   16387 | CONNECT        | f
(8 rows)

从结果中省略了template1和template0

如何判断user1是否有权访问CONNECT db2

还有其他方法可以达到这个目的吗?

1 个答案:

答案 0 :(得分:1)

aclexplode().grantee可以加入pg_user.usesysid以获取用户名。

但是,更简单的解决方案是使用access privilege inquiry functions

检查user1是否可以连接到db2

SELECT has_database_privilege('user1', 'db2', 'CONNECT')

列出user1可访问的所有数据库:

SELECT datname
FROM pg_database
WHERE has_database_privilege('user1', datname, 'CONNECT')