From c9de6b922e4f8c2647c64a67e86d4a95e3fca2cc Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Thu, 20 Oct 2005 19:18:01 +0000 Subject: [PATCH] Document the behavior of GRANT/REVOKE in cases where the privilege is held by means of role membership, rather than directly. Per discussion and bug fix of a couple weeks ago. --- doc/src/sgml/ref/grant.sgml | 25 +++++- doc/src/sgml/ref/revoke.sgml | 27 +++++- doc/src/sgml/user-manag.sgml | 170 +++++++++++++++++++---------------- 3 files changed, 143 insertions(+), 79 deletions(-) diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 8e8196f480d..bb9571abd83 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.49 2005/10/13 23:26:00 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.50 2005/10/20 19:18:01 tgl Exp $ PostgreSQL documentation --> @@ -343,6 +343,29 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] by the containing role itself.) </para> + <para> + <command>GRANT</> and <command>REVOKE</> can also be done by a role + that is not the owner of the affected object, but is a member of the role + that owns the object, or is a member of a role that holds privileges + <literal>WITH GRANT OPTION</literal> on the object. In this case the + privileges will be recorded as having been granted by the role that + actually owns the object or holds the privileges + <literal>WITH GRANT OPTION</literal>. For example, if table + <literal>t1</> is owned by role <literal>g1</>, of which role + <literal>u1</> is a member, then <literal>u1</> can grant privileges + on <literal>t1</> to <literal>u2</>, but those privileges will appear + to have been granted directly by <literal>g1</>. Any other member + of role <literal>g1</> could revoke them later. + </para> + + <para> + If the role executing <command>GRANT</> holds the required privileges + indirectly via more than one role membership path, it is unspecified + which containing role will be recorded as having done the grant. In such + cases it is best practice to use <command>SET ROLE</> to become the + specific role you want to do the <command>GRANT</> as. + </para> + <para> Currently, <productname>PostgreSQL</productname> does not support granting or revoking privileges for individual columns of a table. diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index 58219c55cef..68c69f8814f 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.34 2005/07/26 23:24:02 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.35 2005/10/20 19:18:01 tgl Exp $ PostgreSQL documentation --> @@ -158,6 +158,31 @@ REVOKE [ ADMIN OPTION FOR ] it is possible for a superuser to revoke all privileges, but this may require use of <literal>CASCADE</literal> as stated above. </para> + + <para> + <command>REVOKE</> can also be done by a role + that is not the owner of the affected object, but is a member of the role + that owns the object, or is a member of a role that holds privileges + <literal>WITH GRANT OPTION</literal> on the object. In this case the + command is performed as though it were issued by the containing role that + actually owns the object or holds the privileges + <literal>WITH GRANT OPTION</literal>. For example, if table + <literal>t1</> is owned by role <literal>g1</>, of which role + <literal>u1</> is a member, then <literal>u1</> can revoke privileges + on <literal>t1</> that are recorded as being granted by <literal>g1</>. + This would include grants made by <literal>u1</> as well as by other + members of role <literal>g1</>. + </para> + + <para> + If the role executing <command>REVOKE</> holds privileges + indirectly via more than one role membership path, it is unspecified + which containing role will be used to perform the command. In such cases + it is best practice to use <command>SET ROLE</> to become the specific + role you want to do the <command>REVOKE</> as. Failure to do so may + lead to revoking privileges other than the ones you intended, or not + revoking anything at all. + </para> </refsect1> <refsect1 id="SQL-REVOKE-examples"> diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index cadca53ace6..fb8f84a4916 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.32 2005/10/15 20:12:33 neilc Exp $ +$PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.33 2005/10/20 19:18:00 tgl Exp $ --> <chapter id="user-manag"> @@ -267,6 +267,81 @@ ALTER ROLE myname SET enable_indexscan TO off; </para> </sect1> + <sect1 id="privileges"> + <title>Privileges</title> + + <indexterm zone="privileges"> + <primary>privilege</primary> + </indexterm> + + <indexterm zone="privileges"> + <primary>owner</primary> + </indexterm> + + <indexterm zone="privileges"> + <primary>GRANT</primary> + </indexterm> + + <indexterm zone="privileges"> + <primary>REVOKE</primary> + </indexterm> + + <para> + When an object is created, it is assigned an owner. The + owner is normally the role that executed the creation statement. + For most kinds of objects, the initial state is that only the owner + (or a superuser) can do anything with the object. To allow + other roles to use it, <firstterm>privileges</firstterm> must be + granted. + There are several different kinds of privilege: <literal>SELECT</>, + <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, + <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, + <literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>, + and <literal>USAGE</>. For more + information on the different types of privileges supported by + <productname>PostgreSQL</productname>, see the + <xref linkend="sql-grant" endterm="sql-grant-title"> reference page. + </para> + + <para> + To assign privileges, the <command>GRANT</command> command is + used. So, if <literal>joe</literal> is an existing role, and + <literal>accounts</literal> is an existing table, the privilege to + update the table can be granted with +<programlisting> +GRANT UPDATE ON accounts TO joe; +</programlisting> + The special name <literal>PUBLIC</literal> can + be used to grant a privilege to every role on the system. Writing + <literal>ALL</literal> in place of a specific privilege specifies that all + privileges that apply to the object will be granted. + </para> + + <para> + To revoke a privilege, use the fittingly named + <xref linkend="sql-revoke" endterm="sql-revoke-title"> command: +<programlisting> +REVOKE ALL ON accounts FROM PUBLIC; +</programlisting> + </para> + + <para> + The special privileges of an object's owner (i.e., the right to modify + or destroy the object) are always implicit in being the owner, + and cannot be granted or revoked. But the owner can choose + to revoke his own ordinary privileges, for example to make a + table read-only for himself as well as others. + </para> + + <para> + An object can be assigned to a new owner with an <command>ALTER</command> + command of the appropriate kind for the object. Superusers can always do + this; ordinary roles can only do it if they are both the current owner + of the object (or a member of the owning role) and a member of the new + owning role. + </para> + </sect1> + <sect1 id="role-membership"> <title>Role Membership</title> @@ -373,6 +448,22 @@ RESET ROLE; </para> </note> + <para> + The role attributes <literal>LOGIN</>, <literal>SUPERUSER</>, + <literal>CREATEDB</>, and <literal>CREATEROLE</> can be thought of as + special privileges, but they are never inherited as ordinary privileges + on database objects are. You must actually <command>SET ROLE</> to a + specific role having one of these attributes in order to make use of + the attribute. Continuing the above example, we might well choose to + grant <literal>CREATEDB</> and <literal>CREATEROLE</> to the + <literal>admin</> role. Then a session connecting as role <literal>joe</> + would not have these privileges immediately, only after doing + <command>SET ROLE admin</>. + </para> + + <para> + </para> + <para> To destroy a group role, use <xref linkend="sql-droprole" endterm="sql-droprole-title">: @@ -386,87 +477,12 @@ DROP ROLE <replaceable>name</replaceable>; </para> </sect1> - <sect1 id="privileges"> - <title>Privileges</title> - - <indexterm zone="privileges"> - <primary>privilege</primary> - </indexterm> - - <indexterm zone="privileges"> - <primary>owner</primary> - </indexterm> - - <indexterm zone="privileges"> - <primary>GRANT</primary> - </indexterm> - - <indexterm zone="privileges"> - <primary>REVOKE</primary> - </indexterm> - - <para> - When an object is created, it is assigned an owner. The - owner is normally the role that executed the creation statement. - For most kinds of objects, the initial state is that only the owner - (or a superuser) can do anything with the object. To allow - other roles to use it, <firstterm>privileges</firstterm> must be - granted. - There are several different kinds of privilege: <literal>SELECT</>, - <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, - <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, - <literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>, - and <literal>USAGE</>. For more - information on the different types of privileges supported by - <productname>PostgreSQL</productname>, see the - <xref linkend="sql-grant" endterm="sql-grant-title"> reference page. - </para> - - <para> - To assign privileges, the <command>GRANT</command> command is - used. So, if <literal>joe</literal> is an existing role, and - <literal>accounts</literal> is an existing table, the privilege to - update the table can be granted with -<programlisting> -GRANT UPDATE ON accounts TO joe; -</programlisting> - The special name <literal>PUBLIC</literal> can - be used to grant a privilege to every role on the system. Writing - <literal>ALL</literal> in place of a specific privilege specifies that all - privileges that apply to the object will be granted. - </para> - - <para> - To revoke a privilege, use the fittingly named - <xref linkend="sql-revoke" endterm="sql-revoke-title"> command: -<programlisting> -REVOKE ALL ON accounts FROM PUBLIC; -</programlisting> - </para> - - <para> - The special privileges of an object's owner (i.e., the right to modify - or destroy the object) are always implicit in being the owner, - and cannot be granted or revoked. But the owner can choose - to revoke his own ordinary privileges, for example to make a - table read-only for himself as well as others. - </para> - - <para> - An object can be assigned to a new owner with an <command>ALTER</command> - command of the appropriate kind for the object. Superusers can always do - this; ordinary roles can only do it if they are both the current owner - of the object (or a member of the owning role) and a member of the new - owning role. - </para> - </sect1> - <sect1 id="perm-functions"> <title>Functions and Triggers</title> <para> Functions and triggers allow users to insert code into the backend - server that other users may execute without knowing it. Hence, both + server that other users may execute unintentionally. Hence, both mechanisms permit users to <quote>Trojan horse</quote> others with relative ease. The only real protection is tight control over who can define functions. -- GitLab