在 Postgres 中,如何创建一个具有 CREATEROLE
权限的用户,但仅限于特定的数据库/数据库集?
我试过:
CREATE ROLE user WITH LOGIN PASSWORD 'password' NOCREATEDB CREATEROLE;
这是正确的吗? + 如何将 CREATEROLE
授予多个数据库?
最佳答案
看来这不是一个简单的方法。但是您可以使用 security definer
选项创建函数来实现所需的行为:
create or replace function fn_create_role(p_name text, p_password text, p_databases text[]) returns void
language plpgsql
security definer
as $$
begin
execute format('create role %I with login password %L;', p_name, p_password);
execute format('grant connect on database %s to %I', array_to_string(p_databases, ','), p_name);
return;
end $$;
以 super 用户身份创建此函数。
然后您可以使用 NOCREATEROLE
选项创建角色,但授予它对该函数的 EXECUTE
权限并使用它来创建另一个角色。
注意:您需要从 public
角色中撤销特定数据库的 connect
选项,以禁止角色默认连接到它们,例如:
revoke connect on database db1, db2 from public;
测试它:
作为 super 用户(nd
在我的例子中他也拥有同名的模式)
postgres=# create database db1; create database db2;
CREATE DATABASE
CREATE DATABASE
postgres=# revoke connect on database db1, db2 from public;
REVOKE
postgres=# create role foo with login password 'bar' nocreatedb nocreaterole;
CREATE ROLE
postgres=# set role foo;
SET
postgres=> create role win with login password 'amp' nocreatedb nocreaterole;
ERROR: permission denied to create role
postgres=> set role nd;
SET
postgres=# grant usage on schema nd to foo;
GRANT
postgres=# grant execute on function nd.fn_create_role(text, text, text[]) to foo;
GRANT
postgres=# set role foo;
SET
postgres=> select nd.fn_create_role('win', 'amp', '{db1}');
┌────────────────┐
│ fn_create_role │
╞════════════════╡
│ │
└────────────────┘
(1 row)
在终端中:
$ psql -h localhost -d db1 -U win Password for user win: psql (9.6.3) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. win@db1=> \q $ psql -h localhost -d db2 -U win Password for user win: psql: FATAL: permission denied for database "db2" DETAIL: User does not have CONNECT privilege.
关于postgresql - 对特定数据库的 Postgres CREATEROLE 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45402909/