权限 ========= 一旦一个对象被创建,它会被分配一个所有者。所有者通常是执行创建语句的角色。对于大部分类型的对象,初始状态下只有所有者(或者超级用户)能够对该对象做任何事情。为了允许其他角色使用它,必须分配\ *权限*\ 。 有多种不同的权限:\ ``SELECT``\ 、\ ``INSERT``\ 、\ ``UPDATE``\ 、\ ``DELETE``\ 、\ ``TRUNCATE``\ 、\ ``REFERENCES``\ 、\ ``TRIGGER``\ 、\ ``CREATE``\ 、\ ``CONNECT``\ 、\ ``TEMPORARY``\ 、\ ``EXECUTE``\ 以及\ ``USAGE``\ 。可以应用于一个特定对象的权限随着对象的类型(表、函数等)而不同。 有关这些权限含义的更多详细信息请参阅下文。后续的章节将介绍如何使用这些权限。 修改或销毁一个对象的权力通常是只有所有者才有的权限。 一个对象可以通过该对象类型相应的\ ``ALTER``\ 命令来重新分配所有者,例如 .. code:: programlisting ALTER TABLE table_name OWNER TO new_owner; 超级用户总是可以做到这点,普通角色只有同时是对象的当前所有者(或者是拥有角色的一个成员)以及新拥有角色的一个成员时才能做同样的事。 要分配权限,可以使用\ `GRANT `__\ 命令。例如,如果\ ``joe``\ 是一个已有角色,而\ ``accounts``\ 是一个已有表,更新该表的权限可以按如下方式授权: .. code:: programlisting GRANT UPDATE ON accounts TO joe; 用\ ``ALL``\ 取代特定权限会把与对象类型相关的所有权限全部授权。 一个特殊的名为\ ``PUBLIC``\ 的“角色”可以用来向系统中的每一个角色授予一个权限。同时,在数据库中有很多用户时可以设置“组”角色来帮助管理权限。 为了撤销一个权限,使用\ `REVOKE `__ 命令: .. code:: programlisting REVOKE ALL ON accounts FROM PUBLIC; 对象拥有者的特殊权限(即执行\ ``DROP``\ 、\ ``GRANT``\ 、\ ``REVOKE``\ 等的权力)总是隐式地属于拥有者,并且不能被授予或撤销。但是对象拥有者可以选择撤销他们自己的普通权限,例如把一个表变得对他们自己和其他人只读。 一般情况下,只有对象拥有者(或者超级用户)可以授予或撤销一个对象上的权限。但是可以在授予权限时使用“with grant option”来允许接收人将权限转授给其他人。如果后来授予选项被撤销,则所有从接收人那里获得的权限(直接或者通过授权链获得)都将被撤销。更多详情请见\ `GRANT `__\ 和\ `REVOKE `__\ 参考页。 The available privileges are: .. container:: variablelist ``SELECT`` 允许 `SELECT `__ 从任何列、或特定的列、表、视图、物化视图、或其他类似表格的对象。 也允许使用 `COPY `__ TO. 还需要这个权限来引用\ `UPDATE `__ 或 `DELETE `__\ 中现有的列值。 对于序列,这个权限还允许使用\ ``currval`` 函数。对于大对象,此权限允许读取对象。 ``INSERT`` 允许将新行的 `INSERT `__ 加入表、视图等等。 可以在特定列上授予,在这种情况下\ ``INSERT``\ 命令中只有那些列可以被分配(其他列将因此而收到默认值)。 还允许使用\ `COPY `__ FROM。 ``UPDATE`` 允许 `UPDATE `__ 更新任何列、或指定列、表、视图等等。 (实际上,任何有效的\ ``UPDATE``\ 命令也需要\ ``SELECT``\ 权限,因为它必须引用表列来确定要更新的行,和/或计算列的新值。) ``SELECT ... FOR UPDATE``\ 和\ ``SELECT ... FOR SHARE``\ 除了\ ``SELECT``\ 权限外,还需要至少一列上的这个权限。 对于序列,这个权限允许使用 ``nextval`` 和 ``setval`` 函数。对于大对象,此权限允许写入或截断对象。 ``DELETE`` 允许 `DELETE `__ 从表、视图等等中删除行. (实际上,任何有效的\ ``DELETE``\ 命令也需要\ ``SELECT``\ 权限,因为它必须引用表列来确定要删除的行。) ``TRUNCATE`` 允许在表、视图等等上 `TRUNCATE `__ 。 ``REFERENCES`` 允许创建引用表或表的特定列的外键约束。 ``TRIGGER`` 允许在表、视图等等上创建触发器。 ``CREATE`` 对于数据库,允许在数据库中创建新的模式和发布。 对于模式,允许在模式中创建新对象。要重命名现有对象,你必须拥有对象 *and*\ 所包含模式的此权限。 对于表空间,允许在表空间中创建表、索引和临时文件,并允许创建将表空间作为默认表空间的数据库。(注意,撤销此特权不会更改已有对象的位置。) ``CONNECT`` 允许受让者连接到数据库。此权限在连接启动时进行检查(加之\ ``pg_hba.conf``\ 施加的任何约束). ``TEMPORARY`` 允许在使用数据库时创建临时表。 ``EXECUTE`` 允许调用函数或过程,包括使用在函数之上实现的任何运算符。这是适用于函数和过程的唯一权限类型。 ``USAGE`` 对于程序语言,允许使用语言来创建该语言的函数。 这是适用于过程语言的唯一权限类型。 对于模式,允许访问模式中包含的对象(假设对象自己的权限要求也已得到满足)。 从本质上讲,这允许受让者“look up”模式中的对象。如果没有此权限,仍可以看到对象名称,例如通过查询系统目录。 此外,在撤消此权限后,现有会话可能还具有以前执行过此查找的语句,因此这不是阻止对象访问的彻底安全的方法。 对于序列, 允许使用\ ``currval`` 和 ``nextval`` 函数. 对于类型和域,允许在创建表、函数和其他模式对象时使用类型或域。 (注意,此权限不控制类型的全部 “usage” ,例如查询中出现的类型的值。 它仅防止创建依赖于类型的对象。 此权限的主要目的是控制哪些用户可以对类型创建依赖项,这可能会防止所有者以后更改类型。 ) 对于外部数据包装器,允许使用外部数据包装器创建新服务器。 对于外部服务器,允许使用服务器创建外部表。受让者还可以创建、更改或删除与该服务器关联的自己的用户映射。 其他命令所需的权限罗列在相应命令的参考页上。 在创建对象时,PostgreSQL默认将某些类型对象的权限授予\ ``PUBLIC``\ 。 默认情况下,在表、表列、序列、外部数据包装器、外部服务器、大型对象、模式或表空间上,不向\ ``PUBLIC``\ 授予权限。 对于其他类型的对象,授予 ``PUBLIC``\ 的默认权限如下所示: 针对数据库的\ ``CONNECT``\ 和\ ``TEMPORARY``\ (创建临时表)权限; 针对函数和程序的\ ``EXECUTE``\ 权限;以及针对语言和数据类型(包括域)的\ ``USAGE``\ 权限。 当然,对象所有者可以\ ``REVOKE``\ 默认权限和特别授予的权限。 (为了最大程度的安全性,在创建对象的同一事务中发出\ ``REVOKE``;那么就没有其他用户能够使用该对象的窗口。) 此外,可以使用\ `ALTER DEFAULT PRIVILEGES `__\ 命令取代这些默认权限设置。 `表 5.1 `__\ 显示了\ *ACL*\ (访问控制列表)值中用于这些权限类型的单字母缩写。 你将在下面列出的 `psql `__ 命令的输出中,或者在查看系统目录的 ACL 列时看到这些字母。 .. container:: table :name: PRIVILEGE-ABBREVS-TABLE **表 5.1. ACL 权限缩写** .. container:: table-contents +----------------+----------------+----------------------------------+ | 权限 | 缩写 | 适用对象类型 | +================+================+==================================+ | ``SELECT`` | ``r`` (“读”) | ``LARGE OBJECT``, ``SEQUENCE``, | | | | ``TABLE`` (and table-like | | | | objects), table column | +----------------+----------------+----------------------------------+ | ``INSERT`` | ``a`` (“增补”) | ``TABLE``, table column | +----------------+----------------+----------------------------------+ | ``UPDATE`` | ``w`` (“写”) | ``LARGE OBJECT``, ``SEQUENCE``, | | | | ``TABLE``, table column | +----------------+----------------+----------------------------------+ | ``DELETE`` | ``d`` | ``TABLE`` | +----------------+----------------+----------------------------------+ | ``TRUNCATE`` | ``D`` | ``TABLE`` | +----------------+----------------+----------------------------------+ | ``REFERENCES`` | ``x`` | ``TABLE``, table column | +----------------+----------------+----------------------------------+ | ``TRIGGER`` | ``t`` | ``TABLE`` | +----------------+----------------+----------------------------------+ | ``CREATE`` | ``C`` | ``DATABASE``, ``SCHEMA``, | | | | ``TABLESPACE`` | +----------------+----------------+----------------------------------+ | ``CONNECT`` | ``c`` | ``DATABASE`` | +----------------+----------------+----------------------------------+ | ``TEMPORARY`` | ``T`` | ``DATABASE`` | +----------------+----------------+----------------------------------+ | ``EXECUTE`` | ``X`` | ``FUNCTION``, ``PROCEDURE`` | +----------------+----------------+----------------------------------+ | ``USAGE`` | ``U`` | ``DOMAIN``, | | | | ``FOREIGN DATA WRAPPER``, | | | | ``FOREIGN SERVER``, | | | | ``LANGUAGE``, ``SCHEMA``, | | | | ``SEQUENCE``, ``TYPE`` | +----------------+----------------+----------------------------------+ `表 5.2 `__ 使用上面所示的缩写总结了每种类型 SQL 对象可用的权限. 它还显示可用于检查每种对象类型的特权设置的 psql 命令。 .. container:: table :name: PRIVILEGES-SUMMARY-TABLE **表 5.2. 访问权限摘要** .. container:: table-contents +--------------------+-------------+--------------------+-----------+ | 对象类型 | 所有权限 | 默认 ``PUBLIC`` | psql 命令 | | | | 权限 | | +====================+=============+====================+===========+ | ``DATABASE`` | ``CTc`` | ``Tc`` | ``\l`` | +--------------------+-------------+--------------------+-----------+ | ``DOMAIN`` | ``U`` | ``U`` | ``\dD+`` | +--------------------+-------------+--------------------+-----------+ | ``FUNCTION`` or | ``X`` | ``X`` | ``\df+`` | | ``PROCEDURE`` | | | | +--------------------+-------------+--------------------+-----------+ | ``FORE | ``U`` | none | ``\dew+`` | | IGN DATA WRAPPER`` | | | | +--------------------+-------------+--------------------+-----------+ | ``FOREIGN SERVER`` | ``U`` | none | ``\des+`` | +--------------------+-------------+--------------------+-----------+ | ``LANGUAGE`` | ``U`` | ``U`` | ``\dL+`` | +--------------------+-------------+--------------------+-----------+ | ``LARGE OBJECT`` | ``rw`` | none | | +--------------------+-------------+--------------------+-----------+ | ``SCHEMA`` | ``UC`` | none | ``\dn+`` | +--------------------+-------------+--------------------+-----------+ | ``SEQUENCE`` | ``rwU`` | none | ``\dp`` | +--------------------+-------------+--------------------+-----------+ | ``TABLE`` (and | ``arwdDxt`` | none | ``\dp`` | | table-like | | | | | objects) | | | | +--------------------+-------------+--------------------+-----------+ | Table column | ``arwx`` | none | ``\dp`` | +--------------------+-------------+--------------------+-----------+ | ``TABLESPACE`` | ``C`` | none | ``\db+`` | +--------------------+-------------+--------------------+-----------+ | ``TYPE`` | ``U`` | ``U`` | ``\dT+`` | +--------------------+-------------+--------------------+-----------+ 已授予特定对象的权限显示为\ ``aclitem``\ 项的列表,其中每个\ ``aclitem``\ 项描述了特定授予者授予给一个被授与者的权限。 例如,\ ``calvin=r*w/hobbes`` 指明角色\ ``calvin``\ 具有\ ``SELECT``\ (\ ``r``\ )权限和授予选项(\ ``*``\ )以及不可授予权限\ ``UPDATE``\ (\ ``w``\ ),均由角色\ ``hobbes``\ 授予。 如果\ ``calvin``\ 对由其他授予人授予的同一对象也具有一些权限,那将显示为单独的\ ``aclitem``\ 条目。 ``aclitem`` 中的空受赠方字段代表\ ``PUBLIC``\ 。 例如,假设用户\ ``miriam``\ 创建了表\ ``mytable``\ 并且: .. code:: programlisting GRANT SELECT ON mytable TO PUBLIC; GRANT SELECT, UPDATE, INSERT ON mytable TO admin; GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw; 则 psql的 ``\dp`` 命令将显示: .. code:: programlisting => \dp mytable Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies -−-−-−-−+-−-−-−-−-+-−-−-−-+-−-−-−-−-−-−-−-−-−-−-−-+-−-−-−-−-−-−-−-−-−-−-−-+-−-−-−-−-− public | mytable | table | miriam=arwdDxt/miriam+| col1: +| | | | =r/miriam +| miriam_rw=rw/miriam | | | | admin=arw/miriam | | (1 row) 如果“Access privileges”列对于给定对象为空,则表示该对象具有默认权限(也就是说,它在相关系统目录中的权限条目为空)。 默认权限始终包含所有者的所有权限,并且可以包括 ``PUBLIC`` 的一些权限,具体取决于对象类型,如上所述。 对象上的第一个\ ``GRANT``\ 或\ ``REVOKE``\ 将实例化默认权限(例如,生成\ ``miriam_arwdDxt/miriam``\ ),然后根据指定的请求修改它们。 类似的,只有具有非默认特权的列的条目才显示在“Column privileges”中。(注意:为此目的,“default privileges”始终表示对象类型的内置缺省权限。其权限受\ ``ALTER DEFAULT PRIVILEGES`` 命令影响的对象将始终显示一个显式权限条目,其中包含 ``ALTER``\ 。) 注意所有者的隐式授予选项没有在访问权限显示中标记。仅当授予选项被显式授予给某人时才会出现\ ``*``\ 。