GRANT

GRANT-定义访问权限

Synopsis

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
    [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
    ON [ TABLE ] table_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { { USAGE | SELECT | UPDATE }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { SEQUENCE sequence_name [, ...]
         | ALL SEQUENCES IN SCHEMA schema_name [, ...] }
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
    ON DATABASE database_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON DOMAIN domain_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON FOREIGN DATA WRAPPER fdw_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON FOREIGN SERVER server_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
    ON { { FUNCTION | PROCEDURE | ROUTINE } routine_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...]
         | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] }
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON LANGUAGE lang_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
    ON LARGE OBJECT loid [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { CREATE | ALL [ PRIVILEGES ] }
    ON TABLESPACE tablespace_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
    ON TYPE type_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]

GRANT role_name [, ...] TO role_specification [, ...]
    [ WITH ADMIN OPTION ]
    [ GRANTED BY role_specification ]

where role_specification can be:

    [ GROUP ] role_name
  | PUBLIC
  | CURRENT_USER
  | SESSION_USER

Description

GRANT命令具有两个基本变体:一个对数据库对象(表,列,视图,外部表,序列,数据库,外部数据包装器,外部服务器,函数,过程,过程语言,架构或表空间)授予特权。 ,并授予该角色的成员资格。这些变体在很多方面都是相似的,但是它们的差异足以分别描述。

GRANT 数据库对象

GRANT命令的此变体将一个数据库对象的特定特权授予一个或多个角色。这些特权将添加到已授予的特权(如果有)中。

还有一个选项可以授予一个或多个模式中相同类型的所有对象的特权。当前仅表,序列,函数和过程支持此功能。 ALL TABLES也影响视图和外部表,就像特定对象GRANT命令一样。 ALL FUNCTIONS同样会影响聚合函数,但不会影响过程,就像特定对象GRANT命令一样。

关键字PUBLIC表示将授予所有角色特权,包括以后可能创建的角色。 PUBLIC可以视为始终包含所有角色的隐式定义的组。任何特定角色将具有直接授予它的特权,授予当前它所属的任何角色的特权以及授予PUBLIC的特权的总和。

如果指定了WITH GRANT OPTION,则特权的接收者可以依次将其授予其他人。没有授予选项,接收者将无法做到这一点。授予选项不能授予PUBLIC

无需授予对象所有者(通常是创建对象的用户)特权,因为默认情况下所有者具有所有特权。 (不过,所有者可以出于安全考虑选择撤销自己的某些特权.)

删除对象或以任何方式更改其定义的权利不视为可授予的特权;它是所有者固有的,不能被授予或撤销。 (但是,通过授予或撤消拥有该对象的角色的成员资格,可以获得类似的效果;请参阅下文.)所有者也隐式拥有该对象的所有授予选项。

PostgreSQL 将某些类型的对象的默认特权授予PUBLIC。默认情况下,对表,表列,序列,外部数据包装器,外部服务器,大型对象,模式或表空间,不授予PUBLIC特权。对于其他类型的对象,授予PUBLIC的默认特权如下:数据库的CONNECTTEMPORARY(创建临时表)特权; EXECUTE功能和程序的特权;以及对语言和数据类型(包括域)的USAGE特权。当然,对象所有者可以REVOKE拥有默认特权和明确授予的特权。 (为了获得最大的安全性,请在创建对象的同一事务中发出REVOKE;然后,没有任何窗口可供其他用户使用该对象.)此外,可以使用更改默认特权命令更改这些初始的默认特权设置。

可能的特权是:

  • SELECT

    • 允许来自指定表,视图或序列的任何列或列出的特定列中的SELECT。还允许使用COPY TO。还需要此特权来引用UPDATEDELETE中的现有列值。对于序列,此特权还允许使用currval函数。对于大型对象,此特权允许读取对象。
  • INSERT

    • 允许INSERT的新行进入指定的表。如果列出了特定的列,则只能在INSERT命令中将那些列分配给它们(因此其他列将接收默认值)。还允许COPY FROM。
  • UPDATE

    • 允许指定表的任何列或列出的特定列中的UPDATE。 (实际上,任何不平凡的UPDATE命令也都需要SELECT特权,因为它必须引用表列以确定要更新的行和/或计算列的新值.)SELECT ... FOR UPDATESELECT ... FOR SHARE也至少需要一个特权。列,以及SELECT特权。对于序列,此特权允许使用nextvalsetval函数。对于大型对象,此特权允许写入或截断对象。
  • DELETE

    • 允许指定表中的DELETE行。 (实际上,任何不平凡的DELETE命令也需要SELECT特权,因为它必须引用表列以确定要删除的行.)
  • TRUNCATE

    • 在指定的表格上允许TRUNCATE
  • REFERENCES

    • 允许创建引用指定表或表的指定列的外键约束。 (请参见CREATE TABLE语句。)
  • TRIGGER

    • 允许在指定的表上创建触发器。 (请参见CREATE TRIGGER语句。)
  • CREATE

    • 对于数据库,允许在数据库中创建新的架构和发布。

对于模式,允许在模式内创建新对象。要重命名现有对象,您必须拥有对象*,并且*对于包含架构具有此特权。

对于表空间,允许在表空间内创建表,索引和临时文件,并允许创建将表空间作为其默认表空间的数据库。 (请注意,撤销此特权不会更改现有对象的位置.)

  • CONNECT

    • 允许用户连接到指定的数据库。连接启动时会检查此特权(除了检查pg_hba.conf施加的任何限制)。
  • TEMPORARY
    TEMP

    • 允许在使用指定数据库时创建临时表。
  • EXECUTE

    • 允许使用指定的功能或过程,以及使用在该功能之上实现的任何运算符。这是适用于功能和过程的唯一特权类型。 FUNCTION语法也适用于聚合函数。或者,使用ROUTINE来引用函数,聚合函数或过程,无论它是什么。
  • USAGE

    • 对于过程语言,允许使用指定的语言来创建该语言的功能。这是适用于过程语言的唯一特权类型。

对于模式,允许访问指定模式中包含的对象(假设还满足对象自身的特权要求)。本质上,这允许被授予者在架构内“查找”对象。没有此许可,仍然可以查看对象名称,例如通过查询系统表。同样,在撤消该权限之后,现有后端可能具有以前执行过此查找的语句,因此这不是防止对象访问的完全安全的方法。

对于序列,此特权允许使用currvalnextval函数。

对于类型和域,此特权允许在创建表,函数和其他架构对象时使用类型或域。 (请注意,它不控制类型的一般“用法”,例如查询中出现的类型的值.它仅防止创建依赖于类型的对象.特权的主要目的是控制哪些用户创建依赖关系类型,这可能会阻止所有者稍后更改类型.)

对于外来数据包装器,此特权允许使用外来数据包装器创建新服务器。

对于服务器,此特权允许使用服务器创建外部表。受赠方还可以创建,更改或删除其自己与该服务器关联的用户 Map。

  • ALL PRIVILEGES

    • 一次授予所有可用特权。 PRIVILEGES关键字在 PostgreSQL 中是可选的,尽管严格的 SQL 要求使用。

其他命令所需的特权在相应命令的参考页上列出。

授予角色

GRANT命令的此变体将一个角色的成员资格授予一个或多个其他角色。角色的成员资格意义重大,因为它可以将授予角色的特权传达给每个成员。

如果指定了WITH ADMIN OPTION,则成员可以依次将角色的成员身份授予其他人,也可以撤消该角色的成员身份。没有 admin 选项,普通用户将无法做到这一点。角色不认为自己拥有WITH ADMIN OPTION,但是它可以从会话用户与角色匹配的数据库会话中授予或撤销成员资格。数据库超级用户可以以任何角色向任何人授予或撤销成员资格。具有CREATEROLE特权的角色可以授予或撤消不是超级用户的任何角色的成员资格。

如果指定了GRANTED BY,则将授予记录为已由指定角色完成。只有数据库超级用户可以使用此选项,除非它具有与执行命令相同的角色。

与具有特权的情况不同,不能将角色的成员资格授予PUBLIC。还要注意,这种形式的命令不允许* role_specification *中的噪声字GROUP

Notes

REVOKE命令用于撤消访问权限。

自 PostgreSQL 8.1 起,用户和组的概念已统一为一种称为角色的单一实体。因此,不再需要使用关键字GROUP来标识被授予者是用户还是组。该命令中仍允许使用GROUP,但这是一个干扰词。

如果用户对特定列或其整个表拥有该特权,则他们可以对列执行SELECTINSERT等。在表级别上授予特权,然后将其撤销一列将不会满足您的期望:表级别授予不受列级别操作的影响。

当对象的非所有者尝试对该对象具有GRANT特权时,如果用户对该对象没有任何特权,该命令将完全失败。只要有某些特权,该命令就会 continue 执行,但是它将只授予用户具有授予选项的那些特权。如果未保留任何授予选项,则GRANT ALL PRIVILEGES表单将发出警告消息,而如果未保留针对命令中特别指定的任何特权的授予选项,则其他表单将发出警告。 (原则上,这些声明也适用于对象所有者,但是由于所有者总是被视为拥有所有授予选项,因此永远不会发生这种情况.)

应该注意的是,数据库超级用户可以访问所有对象,而不管对象特权设置如何。这与 Unix 系统中root的权限相当。与root一样,除非绝对必要,否则以超级用户身份操作是不明智的。

如果超级用户选择发出GRANTREVOKE命令,则该命令的执行就像由受影响对象的所有者发出一样。特别是,通过此类命令授予的特权似乎已由对象所有者授予。 (对于角色成员身份,成员资格似乎已由包含角色本身授予.)

GRANTREVOKE也可以由不是受影响对象的所有者,但是拥有该对象的角色的成员,或者是拥有对该对象的特权WITH GRANT OPTION的角色的成员来完成的。在这种情况下,特权将被记录为已由实际拥有对象或拥有特权WITH GRANT OPTION的角色授予。例如,如果表t1由角色g1拥有,而角色u1是角色u1的成员,则u1可以将t1的特权授予u2,但是这些特权似乎是由g1直接授予的。角色g1的任何其他成员以后都可以撤消它们。

如果执行GRANT的角色通过一个以上的角色成员资格路径间接拥有所需的特权,则未指定哪个包含角色将记录为已完成授予。在这种情况下,最佳做法是使用SET ROLE成为您要执行GRANT的特定角色。

授予表权限不会自动将权限扩展到该表使用的任何序列,包括与SERIAL列绑定的序列。序列权限必须单独设置。

使用psql\dp命令获取有关表和列的现有特权的信息。例如:

=> \dp mytable
                              Access privileges
 Schema |  Name   | Type  |   Access privileges   | Column access privileges 
--------+---------+-------+-----------------------+--------------------------
 public | mytable | table | miriam=arwdDxt/miriam | col1:
                          : =r/miriam             :   miriam_rw=rw/miriam
                          : admin=arw/miriam        
(1 row)

\dp所示的条目将这样解释:

rolename=xxxx -- privileges granted to a role
        =xxxx -- privileges granted to PUBLIC

            r -- SELECT ("read")
            w -- UPDATE ("write")
            a -- INSERT ("append")
            d -- DELETE
            D -- TRUNCATE
            x -- REFERENCES
            t -- TRIGGER
            X -- EXECUTE
            U -- USAGE
            C -- CREATE
            c -- CONNECT
            T -- TEMPORARY
      arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)
            * -- grant option for preceding privilege

        /yyyy -- role that granted this privilege

创建表mytable并执行以下操作后,用户miriam将看到以上示例显示:

GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;

对于非表对象,还有其他\d个命令可以显示其特权。

如果给定对象的“访问特权”列为空,则表示该对象具有默认特权(即,其特权列为 null)。如上所述,默认特权始终包含所有者的所有特权,并且可以包含PUBLIC的某些特权,具体取决于对象类型,如上所述。对象上的前GRANTREVOKE将实例化默认特权(例如,产生{miriam=arwdDxt/miriam}),然后根据指定的请求对其进行修改。同样,条目仅在具有非默认特权的列中显示在“列访问特权”中。 (注意:为此,“默认特权”始终表示对象类型的内置默认特权.特权受ALTER DEFAULT PRIVILEGES命令影响的对象将始终显示为显式特权条目,其中包括ALTER.)

请注意,所有者的隐式授予选项未在访问权限显示中标记。仅当授予选项已明确授予某人时,*才会出现。

Examples

向表films上的所有用户授予插入权限:

GRANT INSERT ON films TO PUBLIC;

在视图kinds上向用户manuel授予所有可用特权:

GRANT ALL PRIVILEGES ON kinds TO manuel;

请注意,尽管上述内容的确会由超级用户或kinds的所有者执行时授予所有特权,但在由其他人执行时,它只会授予其他人具有授予选项的权限。

将角色admins的成员资格授予用户joe

GRANT admins TO joe;

Compatibility

根据 SQL 标准,ALL PRIVILEGES中的PRIVILEGES关键字是必需的。 SQL 标准不支持为每个命令在多个对象上设置特权。

PostgreSQL 允许对象所有者撤销自己的普通特权:例如,表所有者可以通过撤销自己的INSERTUPDATEDELETETRUNCATE特权使表对自己只读。根据 SQL 标准,这是不可能的。原因是 PostgreSQL 将所有者的特权视为所有者授予自己的特权。因此他们也可以撤销它们。在 SQL 标准中,所有者的特权由假定的实体“ _SYSTEM”授予。所有者不是“ _SYSTEM”,不能撤消这些权利。

根据 SQL 标准,可以将授予选项授予PUBLIC; PostgreSQL 仅支持将授予选项授予角色。

SQL 标准允许GRANTED BY选项以GRANT的所有形式使用。 PostgreSQL 仅在授予角色成员身份时才支持它,即使那样,只有超级用户才能以非平凡的方式使用它。

SQL 标准为其他类型的对象提供USAGE特权:字符集,排序规则,翻译。

在 SQL 标准中,序列仅具有USAGE特权,该特权控制NEXT VALUE FOR表达式的使用,这等效于 PostgreSQL 中的nextval函数。序列特权SELECTUPDATE是 PostgreSQL 扩展。 USAGE特权序列对currval函数的应用也是 PostgreSQL 扩展(函数本身也是如此)。

数据库,表空间,模式和语言的特权是 PostgreSQL 扩展。

See Also

REVOKE, 更改默认特权