向数据库上的用户授予所有权限


206

我想给用户一个数据库的所有权限,而无需使其成为管理员。之所以要这样做,是因为目前DEV和PROD是同一集群上的不同DB,所以我不希望用户能够更改生产对象,但用户必须能够更改DEV上的对象。

我试过了:

grant ALL on database MY_DB to group MY_GROUP;

但似乎没有任何许可。

然后我尝试了:

grant all privileges on schema MY_SCHEMA to group MY_GROUP;

而且似乎授予了我创建对象的权限,但不允许我在该模式上查询\删除属于其他用户的对象

我可以继续向MY_SCHEMA上的用户授予USAGE权限,但随后它会抱怨没有对该表的权限...

所以我想我的问题是:是否有任何简单的方法可以将所有权限授予数据库上的用户?

我正在使用PostgreSQL 8.1.23。

Answers:


271

用户显然需要访问数据库

GRANT CONNECT ON DATABASE my_db TO my_user;

以及(至少)模式USAGE特权:

GRANT USAGE ON SCHEMA public TO my_user;

或授予USAGE所有自定义架构:

DO
$$
BEGIN
   -- RAISE NOTICE '%', (  -- use instead of EXECUTE to see generated commands
   EXECUTE (
   SELECT string_agg(format('GRANT USAGE ON SCHEMA %I TO my_user', nspname), '; ')
   FROM   pg_namespace
   WHERE  nspname <> 'information_schema' -- exclude information schema and ...
   AND    nspname NOT LIKE 'pg\_%'        -- ... system schemas
   );
END
$$;

然后,所有表的所有权限(需要Postgres 9.0或更高版本)。
并且不要忘记序列(如果有的话):

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO my_user;

对于较旧的版本,您可以使用pgAdmin III的“授予向导”(默认GUI)。

还有其他一些对象,其手册GRANT自Postgres 12起具有完整列表:

数据库对象(表,列,视图,外部表,序列,数据库,外部数据包装器,外部服务器,函数,过程,过程语言,模式或表空间)的特权

但是其余的几乎不需要。更多细节:

考虑升级到当前版本


133
GRANT ALL PRIVILEGES ON DATABASE "my_db" to my_user;

24
授予所有特权ON DATABASE听起来很强大,但并没有做很多事情。这只是一个开始。它不对包含的对象授予任何特权。
Erwin Brandstetter

49

在PostgreSQL 9.0+中,您可以执行以下操作:

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA MY_SCHEMA TO MY_GROUP;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA MY_SCHEMA TO MY_GROUP;

如果您也想为新创建的关系启用此功能,请设置默认权限:

ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
  GRANT ALL PRIVILEGES ON TABLES TO MY_GROUP;
ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
  GRANT ALL PRIVILEGES ON SEQUENCES TO MY_GROUP;

但是,看到使用8.1,您必须自己编写代码:

CREATE FUNCTION grant_all_in_schema (schname name, grant_to name) RETURNS integer AS $$
DECLARE
  rel RECORD;
BEGIN
  FOR rel IN
    SELECT c.relname
    FROM pg_class c
    JOIN pg_namespace s ON c.namespace = s.oid
    WHERE s.nspname = schname
  LOOP
    EXECUTE 'GRANT ALL PRIVILEGES ON ' || quote_ident(schname) || '.' || rel.relname || ' TO ' || quote_ident(grant_to);
  END LOOP;
  RETURN 1;
END; $$ LANGUAGE plpgsql STRICT;
REVOKE ALL ON FUNCTION grant_all_in_schema(name, name) FROM PUBLIC;

这将对所有关系设置特权:表,视图,索引,序列等。如果要限制特权,请在上过滤pg_class.relkind。有关详细信息,请参见pg_class文档

您应该以超级用户身份并根据应用程序的需要定期运行此功能。一种选择是将其打包在每天或每小时执行的cron作业中。


嗨,帕特里克,您好!8.1上不提供“所有表”(postgresql.org/docs/8.1/static/sql-grant.html)我知道我可以遍历表并单独赋予权限,但这就是我的意思。试图避免。但感谢您的帮助
迭戈

@Diego:为8.1添加了解决方案
Patrick

谢谢patrick,我最终使用了和您一样的方法,但没有使用“ GRANT ALL”。由于某种原因,它似乎什么也没做。例如,我跑了:将模式测试中的ALL授予userA;但在那之后,userA仍然无权访问架构测试中的表
Diego

2
您应该在模式上授予使用权。然后,在该架构内的所有关系(表,视图,序列,索引等)上,您必须分别授予SELECT,INSERT,UPDATE,DELETE和TRUNCATE。模式是名称空间,关系是数据所在的位置。
2014年

28

我执行以下操作在PostgreSQL 9.4.15数据库上添加了一个角色'eSumit'并提供了对该角色的所有权限:

CREATE ROLE eSumit;

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO eSumit;

GRANT ALL PRIVILEGES ON DATABASE "postgres" to eSumit;

ALTER USER eSumit WITH SUPERUSER;

还通过以下方式检查了pg_table条目:

从pg_roles中选择*; 在此处输入图片说明

数据库查询快照: 在此处输入图片说明


我有Postgres版本10.3,在数据库名称周围使用引号时会引发语法错误。
萨吉德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.