From 96147a6d1c15b7604838dcd5de5ebd771f551d96 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Sun, 27 May 2001 09:59:30 +0000 Subject: [PATCH] Make UPDATE and DELETE privileges distinct. Add REFERENCES and TRIGGER privileges. INSERT and COPY FROM now require INSERT (only). Add privileges regression test. --- doc/src/sgml/ref/copy.sgml | 6 +- doc/src/sgml/ref/create_rule.sgml | 6 +- doc/src/sgml/ref/create_trigger.sgml | 6 +- doc/src/sgml/ref/delete.sgml | 6 +- doc/src/sgml/ref/grant.sgml | 555 ++++++++--------------- doc/src/sgml/ref/insert.sgml | 6 +- doc/src/sgml/ref/psql-ref.sgml | 6 +- doc/src/sgml/ref/revoke.sgml | 394 +++------------- doc/src/sgml/ref/select.sgml | 6 +- doc/src/sgml/ref/update.sgml | 6 +- src/backend/catalog/aclchk.c | 28 +- src/backend/commands/command.c | 7 +- src/backend/commands/comment.c | 4 +- src/backend/commands/copy.c | 4 +- src/backend/commands/sequence.c | 8 +- src/backend/commands/trigger.c | 8 +- src/backend/executor/execMain.c | 15 +- src/backend/parser/gram.y | 32 +- src/backend/tcop/utility.c | 6 +- src/backend/utils/adt/acl.c | 46 +- src/include/utils/acl.h | 33 +- src/test/regress/expected/privileges.out | 198 ++++++++ src/test/regress/parallel_schedule | 1 + src/test/regress/pg_regress.sh | 14 +- src/test/regress/serial_schedule | 3 +- src/test/regress/sql/privileges.sql | 146 ++++++ 26 files changed, 724 insertions(+), 826 deletions(-) create mode 100644 src/test/regress/expected/privileges.out create mode 100644 src/test/regress/sql/privileges.sql diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 6019eb7a089..3c4dd31a5a2 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.20 2001/01/13 23:58:55 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.21 2001/05/27 09:59:27 petere Exp $ Postgres documentation --> <refentry id="SQL-COPY"> <refmeta> - <refentrytitle id="sql-copy-title"> - COPY - </refentrytitle> + <refentrytitle id="sql-copy-title">COPY</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml index e6a1a7b1468..430026a7863 100644 --- a/doc/src/sgml/ref/create_rule.sgml +++ b/doc/src/sgml/ref/create_rule.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.22 2001/01/13 23:58:55 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.23 2001/05/27 09:59:27 petere Exp $ Postgres documentation --> <refentry id="SQL-CREATERULE"> <refmeta> - <refentrytitle id="sql-createrule-title"> - CREATE RULE - </refentrytitle> + <refentrytitle id="sql-createrule-title">CREATE RULE</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml index c4fbe0203bf..1dc633ce9d1 100644 --- a/doc/src/sgml/ref/create_trigger.sgml +++ b/doc/src/sgml/ref/create_trigger.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.12 2000/10/05 19:48:18 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.13 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-CREATETRIGGER"> <refmeta> - <refentrytitle id="SQL-CREATETRIGGER-TITLE"> - CREATE TRIGGER - </refentrytitle> + <refentrytitle id="SQL-CREATETRIGGER-TITLE">CREATE TRIGGER</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml index 1f684b946f8..261ac327080 100644 --- a/doc/src/sgml/ref/delete.sgml +++ b/doc/src/sgml/ref/delete.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/delete.sgml,v 1.12 2001/01/13 23:58:55 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/delete.sgml,v 1.13 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-DELETE"> <refmeta> - <refentrytitle id="SQL-DELETE-TITLE"> - DELETE - </refentrytitle> + <refentrytitle id="SQL-DELETE-TITLE">DELETE</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 9770c3dd542..1399d049d77 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -1,444 +1,253 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.9 2000/10/05 19:48:18 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.10 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-GRANT"> <refmeta> - <refentrytitle id="SQL-GRANT-TITLE"> - GRANT - </refentrytitle> + <refentrytitle>GRANT</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> + <refnamediv> - <refname> - GRANT - </refname> - <refpurpose> - Grants access privilege to a user, a group or all users - </refpurpose> + <refname>GRANT</refname> + <refpurpose>Grants access privileges to a user, a group, or all users</refpurpose> </refnamediv> - <refsynopsisdiv> - <refsynopsisdivinfo> - <date>1999-07-20</date> - </refsynopsisdivinfo> - <synopsis> -GRANT <replaceable class="PARAMETER">privilege</replaceable> [, ...] ON <replaceable class="PARAMETER">object</replaceable> [, ...] - TO { PUBLIC | GROUP <replaceable class="PARAMETER">group</replaceable> | <replaceable class="PARAMETER">username</replaceable> } - </synopsis> - - <refsect2 id="R2-SQL-GRANT-1"> - <refsect2info> - <date>1998-09-23</date> - </refsect2info> - <title> - Inputs - </title> - <para> - - <variablelist> - <varlistentry> - <term><replaceable class="PARAMETER">privilege</replaceable></term> - <listitem> - <para> - The possible privileges are: - - <variablelist> - <varlistentry> - <term>SELECT</term> - <listitem> - <para> - Access all of the columns of a specific - table/view. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>INSERT</term> - <listitem> - <para> - Insert data into all columns of a - specific table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>UPDATE</term> - <listitem> - <para> - Update all columns of a specific - table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>DELETE</term> - <listitem> - <para> - Delete rows from a specific table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>RULE</term> - <listitem> - <para> - Define rules on the table/view - (See CREATE RULE statement). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>ALL</term> - <listitem> - <para> - Grant all privileges. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="PARAMETER">object</replaceable></term> - <listitem> - <para> - The name of an object to which to grant access. - The possible objects are: - - <itemizedlist spacing="compact" mark="bullet"> - <listitem> - <para> - table - </para> - </listitem> - - <listitem> - <para> - view - </para> - </listitem> - - <listitem> - <para> - sequence - </para> - </listitem> - - </itemizedlist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PUBLIC</term> - <listitem> - <para> - A short form representing all users. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>GROUP <replaceable class="PARAMETER">group</replaceable></term> - <listitem> - <para> - A <replaceable class="PARAMETER">group</replaceable> to whom to grant privileges. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <replaceable class="PARAMETER">username</replaceable> - </term> - <listitem> - <para> - The name of a user to whom to grant privileges. PUBLIC is a short form - representing all users. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </refsect2> - - <refsect2 id="R2-SQL-GRANT-2"> - <refsect2info> - <date>1998-09-23</date> - </refsect2info> - <title> - Outputs - </title> - <para> - <variablelist> - <varlistentry> - <term><computeroutput> -CHANGE - </computeroutput></term> - <listitem> - <para> - Message returned if successful. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><computeroutput> -ERROR: ChangeAcl: class "<replaceable class="PARAMETER">object</replaceable>" not found - </computeroutput></term> - <listitem> - <para> - Message returned if the specified object is not available or - if it is impossible - to give privileges to the specified group or users. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </refsect2> + <refsynopsisdiv> +<synopsis> +GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } + ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...] + TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } +</synopsis> </refsynopsisdiv> - <refsect1 id="R1-SQL-GRANT-1"> - <refsect1info> - <date>1998-09-23</date> - </refsect1info> - <title> - Description - </title> + <refsect1 id="sql-grant-description"> + <title>Description</title> + + <para> + The <command>GRANT</command> command gives specific permissions on + an object (table, view, sequence) to a user or a group of users. + The special key word <literal>PUBLIC</literal> indicates that the + privileges are to be granted to all users, including those that may + be created later. + </para> <para> - <command>GRANT</command> allows the creator of an object to give specific permissions to - all users (PUBLIC) or to a certain user or group. - Users other than the creator don't have any access permission - unless the creator GRANTs permissions, after the object - is created. + Users other than the creator do not have any access privileges + unless the creator grants permissions, after the object is created. + There is no need to grant privileges to the creator of an object, + as the creator automatically holds all privileges, and can also + drop the object. </para> <para> - Once a user has a privilege on an object, he is enabled to exercise - that privilege. - There is no need to GRANT privileges to the creator of - an object, the creator automatically holds ALL privileges, and can - also drop the object. + The possible privileges are: + + <variablelist> + <varlistentry> + <term>SELECT</term> + <listitem> + <para> + Allows <xref linkend="sql-select"> from any column of the + specified table, view, or sequence. Also allows the use of + <xref linkend="sql-copy"> FROM. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>INSERT</term> + <listitem> + <para> + Allows <xref linkend="sql-insert"> of a new row into the + specified table. Also allows <xref linkend="sql-copy"> TO. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>UPDATE</term> + <listitem> + <para> + Allows <xref linkend="sql-update"> of any column of the + specified table. <literal>SELECT ... FOR UPDATE</literal> + also requires this privilege (besides the + <literal>SELECT</literal> privilege). For sequences, this + privilege allows the use of <function>currval</function> and + <function>nextval</function>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>DELETE</term> + <listitem> + <para> + Allows the <xref linkend="sql-delete"> of a row from the + specified table. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>RULE</term> + <listitem> + <para> + Allows the creation of a rule on the table/view. (See <xref + linkend="sql-createrule"> statement). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>REFERENCES</term> + <listitem> + <para> + To create of a table with a foreign key constraint, it is + necessary to have this privilege on the table with the primary + key. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>TRIGGER</term> + <listitem> + <para> + Allows the creation of a trigger on the specified table. (See + <xref linkend="sql-createtrigger"> statement). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ALL PRIVILEGES</term> + <listitem> + <para> + Grant all of the above privileges at once. The + <literal>PRIVILEGES</literal> key word is optional, but it is + required by strict SQL. + </para> + </listitem> + </varlistentry> + </variablelist> + + The privileges required by other commands are listed on the + reference page of the respective command. </para> + </refsect1> + - <refsect2 id="R2-SQL-GRANT-3"> - <refsect2info> - <date>1998-09-23</date> - </refsect2info> - <title> - Notes - </title> + <refsect1 id="SQL-GRANT-notes"> + <title>Notes</title> <para> Currently, to grant privileges in <productname>Postgres</productname> to only a few columns, you must - create a view having desired columns and then grant privileges + create a view having the desired columns and then grant privileges to that view. </para> <para> - Use <command>psql \z</command> - for further information about permissions + Use <xref linkend="app-psql">'s <command>\z</command> command + to obtain information about privileges on existing objects: - <programlisting> - Database = lusitania +<programlisting> + Database = lusitania +------------------+---------------------------------------------+ | Relation | Grant/Revoke Permissions | +------------------+---------------------------------------------+ - | mytable | {"=rw","miriam=arwR","group todos=rw"} | + | mytable | {"=rw","miriam=arwdRxt","group todos=rw"} | +------------------+---------------------------------------------+ Legend: uname=arwR -- privileges granted to a user - group gname=arwR -- privileges granted to a GROUP + group gname=arwR -- privileges granted to a group =arwR -- privileges granted to PUBLIC - r -- SELECT - w -- UPDATE/DELETE - a -- INSERT + r -- SELECT ("read") + w -- UPDATE ("write") + a -- INSERT ("append") + d -- DELETE R -- RULE - arwR -- ALL - </programlisting> - + x -- REFERENCES + t -- TRIGGER + arwdRxt -- ALL PRIVILEGES +</programlisting> </para> <para> - Refer to REVOKE statements to revoke access privileges. + The <xref linkend="sql-revoke"> command is used to revoke access + privileges. </para> - </refsect2> </refsect1> - <refsect1 id="R1-SQL-GRANT-2"> - <title> - Usage - </title> + <refsect1 id="sql-grant-examples"> + <title>Examples</title> + <para> Grant insert privilege to all users on table films: - <programlisting> +<programlisting> GRANT INSERT ON films TO PUBLIC; - </programlisting> +</programlisting> </para> <para> Grant all privileges to user manuel on view kinds: - <programlisting> -GRANT ALL ON kinds TO manuel; - </programlisting> +<programlisting> +GRANT ALL PRIVILEGES ON kinds TO manuel; +</programlisting> </para> </refsect1> - <refsect1 id="R1-SQL-GRANT-3"> - <title> - Compatibility - </title> + <refsect1 id="sql-grant-compatibility"> + <title>Compatibility</title> - <refsect2 id="R2-SQL-GRANT-4"> - <refsect2info> - <date>1998-09-23</date> - </refsect2info> - <title> - SQL92 - </title> + <refsect2> + <title>SQL92</title> + <para> - The <acronym>SQL92</acronym> syntax for GRANT allows setting privileges - for individual columns - within a table, and allows setting a privilege to grant - the same privileges to others: + The <literal>PRIVILEGES</literal> key word in <literal>ALL + PRIVILEGES</literal> is required. <acronym>SQL</acronym> does not + support setting the privileges on more than one table per command. + </para> + + <para> + The <acronym>SQL92</acronym> syntax for GRANT allows setting + privileges for individual columns within a table, and allows + setting a privilege to grant the same privileges to others: - <synopsis> +<synopsis> GRANT <replaceable class="PARAMETER">privilege</replaceable> [, ...] ON <replaceable class="PARAMETER">object</replaceable> [ ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) ] [, ...] TO { PUBLIC | <replaceable class="PARAMETER">username</replaceable> [, ...] } [ WITH GRANT OPTION ] - </synopsis> +</synopsis> + </para> + + <para> + <acronym>SQL</acronym> allows to grant the USAGE privilege on + other kinds of objects: CHARACTER SET, COLLATION, TRANSLATION, DOMAIN. </para> <para> - Fields are compatible with those in the <acronym>Postgres</acronym> - implementation, with the following additions: - - <variablelist> - <varlistentry> - <term><replaceable class="PARAMETER">privilege</replaceable></term> - <listitem> - <para> - <acronym>SQL92</acronym> permits additional privileges to be specified: - - <variablelist> - <varlistentry> - <term>SELECT</term> - <listitem> - <para> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>REFERENCES</term> - <listitem> - <para> - Allowed to reference some or all of the columns of a specific - table/view in integrity constraints. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>USAGE</term> - <listitem> - <para> - Allowed to use a domain, character set, collation - or translation. - If an object specifies anything other than a table/view, - <replaceable class="PARAMETER">privilege</replaceable> - must specify only USAGE. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="PARAMETER">object</replaceable></term> - <listitem> - <para> - - <variablelist> - <varlistentry> - <term>[ TABLE ] <replaceable class="PARAMETER">table</replaceable></term> - <listitem> - <para> - <acronym>SQL92</acronym> allows the additional - non-functional keyword <literal>TABLE</literal>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>CHARACTER SET</term> - <listitem> - <para> - Allowed to use the specified character set. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>COLLATION</term> - <listitem> - <para> - Allowed to use the specified collation sequence. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>TRANSLATION</term> - <listitem> - <para> - Allowed to use the specified character set translation. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>DOMAIN</term> - <listitem> - <para> - Allowed to use the specified domain. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>WITH GRANT OPTION</term> - <listitem> - <para> - Allowed to grant the same privilege to others. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </listitem> - </varlistentry> - </variablelist> + The TRIGGER privilege was introduced in SQL99. The RULE privilege + is a PostgreSQL extension. </para> </refsect2> + + </refsect1> + + + <refsect1> + <title>See Also</title> + + <simpara> + <xref linkend="sql-revoke"> + </simpara> </refsect1> + </refentry> <!-- Keep this comment at the end of the file diff --git a/doc/src/sgml/ref/insert.sgml b/doc/src/sgml/ref/insert.sgml index dc6fb14da83..f6ab93f9f59 100644 --- a/doc/src/sgml/ref/insert.sgml +++ b/doc/src/sgml/ref/insert.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/insert.sgml,v 1.13 2001/01/13 23:58:55 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/insert.sgml,v 1.14 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-INSERT"> <refmeta> - <refentrytitle id="SQL-INSERT-TITLE"> - INSERT - </refentrytitle> + <refentrytitle id="SQL-INSERT-TITLE">INSERT</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 3a1c8ab0e07..ac58fdb3843 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.53 2001/05/17 21:50:18 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.54 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> @@ -1187,8 +1187,8 @@ Access permissions for database "test" </para> <para> - The commands <xref linkend="SQL-GRANT" endterm="SQL-GRANT-title"> and - <xref linkend="SQL-REVOKE" endterm="SQL-REVOKE-title"> + The commands <xref linkend="SQL-GRANT"> and + <xref linkend="SQL-REVOKE"> are used to set access permissions. </para> diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index d7e83c822d9..a9988fbc1ea 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -1,379 +1,96 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.13 2000/12/25 23:15:26 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.14 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-REVOKE"> <refmeta> - <refentrytitle id="SQL-REVOKE-TITLE"> - REVOKE - </refentrytitle> + <refentrytitle>REVOKE</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> + <refnamediv> - <refname> - REVOKE - </refname> - <refpurpose> - Revokes access privilege from a user, a group or all users. - </refpurpose> + <refname>REVOKE</refname> + <refpurpose>Revokes access privilege from a user, a group, or all users.</refpurpose> </refnamediv> - <refsynopsisdiv> - <refsynopsisdivinfo> - <date>1999-07-20</date> - </refsynopsisdivinfo> - <synopsis> -REVOKE <replaceable class="PARAMETER">privilege</replaceable> [, ...] - ON <replaceable class="PARAMETER">object</replaceable> [, ...] - FROM { PUBLIC | GROUP <replaceable class="PARAMETER">groupname</replaceable> | <replaceable class="PARAMETER">username</replaceable> } - </synopsis> - - <refsect2 id="R2-SQL-REVOKE-1"> - <refsect2info> - <date>1998-09-24</date> - </refsect2info> - <title> - Inputs - </title> - <para> - - <variablelist> - <varlistentry> - <term><replaceable class="PARAMETER">privilege</replaceable></term> - <listitem> - <para> - The possible privileges are: - - <variablelist> - <varlistentry> - <term>SELECT</term> - <listitem> - <para> - Privilege to access all of the columns of a specific - table/view. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>INSERT</term> - <listitem> - <para> - Privilege to insert data into all columns of a - specific table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>UPDATE</term> - <listitem> - <para> - Privilege to update all columns of a specific - table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>DELETE</term> - <listitem> - <para> - Privilege to delete rows from a specific table. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>RULE</term> - <listitem> - <para> - Privilege to define rules on table/view. - (See - <xref linkend="sql-createrule" endterm="sql-createrule-title">). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>ALL</term> - <listitem> - <para> - Rescind all privileges. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="PARAMETER">object</replaceable></term> - <listitem> - <para> - The name of an object from which to revoke access. - - The possible objects are: - <itemizedlist spacing="compact" mark="bullet"> - <listitem> - <para> - table - </para> - </listitem> - <listitem> - <para> - view - </para> - </listitem> - - <listitem> - <para> - sequence - </para> - </listitem> - - </itemizedlist> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="PARAMETER">group</replaceable></term> - <listitem> - <para> - The name of a group from whom to revoke privileges. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="PARAMETER">username</replaceable></term> - <listitem> - <para> - The name of a user from whom revoke privileges. Use the PUBLIC keyword - to specify all users. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PUBLIC</term> - <listitem> - <para> - Rescind the specified privilege(s) for all users. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </refsect2> - - <refsect2 id="R2-SQL-REVOKE-2"> - <refsect2info> - <date>1998-09-24</date> - </refsect2info> - <title> - Outputs - </title> - <para> - - <variablelist> - <varlistentry> - <term><computeroutput> -CHANGE - </computeroutput></term> - <listitem> - <para> - Message returned if successfully. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><computeroutput> -ERROR - </computeroutput></term> - <listitem> - <para> - Message returned if object is not available or impossible - to revoke privileges from a group or users. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </refsect2> + <refsynopsisdiv> +<synopsis> +REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] } + ON [ TABLE ] <replaceable class="PARAMETER">object</replaceable> [, ...] + FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } +</synopsis> </refsynopsisdiv> - <refsect1 id="R1-SQL-REVOKE-1"> - <refsect1info> - <date>1998-09-24</date> - </refsect1info> - <title> - Description - </title> + <refsect1 id="SQL-REVOKE-description"> + <title>Description</title> + <para> - <command>REVOKE</command> allows creator of an object to revoke permissions granted - before, from all users (via PUBLIC) or a certain user or group. + <command>REVOKE</command> allows the creator of an object to revoke + permissions granted before, from a users or a group of users. The + key word <literal>PUBLIC</literal> means to revoke this privilege + from all users. </para> - <refsect2 id="R2-SQL-REVOKE-3"> - <refsect2info> - <date>1998-09-24</date> - </refsect2info> - <title> - Notes - </title> - <para> - Refer to psql \z command for further information about permissions - on existing objects: - - <programlisting> -Database = lusitania -+------------------+---------------------------------------------+ -| Relation | Grant/Revoke Permissions | -+------------------+---------------------------------------------+ -| mytable | {"=rw","miriam=arwR","group todos=rw"} | -+------------------+---------------------------------------------+ -Legend: - uname=arwR -- privileges granted to a user - group gname=arwR -- privileges granted to a GROUP - =arwR -- privileges granted to PUBLIC - - r -- SELECT - w -- UPDATE/DELETE - a -- INSERT - R -- RULE - arwR -- ALL - </programlisting> - </para> - <tip> - <para> - Currently, to create a GROUP you have to insert - data manually into table pg_group as: + <para> + See the description of the <xref linkend="sql-grant"> command for + the meaning of the privilege types. + </para> + </refsect1> - <programlisting> -INSERT INTO pg_group VALUES ('todos'); -CREATE USER miriam IN GROUP todos; - </programlisting> - </para> - </tip> + <refsect1 id="SQL-REVOKE-notes"> + <title>Notes</title> - </refsect2> + <para> + Use <xref linkend="app-psql">'s <command>\z</command> command to + display the privileges granted on existing objects. See also <xref + linkend="sql-grant"> for information about the format. + </para> </refsect1> - <refsect1 id="R1-SQL-REVOKE-2"> - <title> - Usage - </title> + <refsect1 id="SQL-REVOKE-examples"> + <title>Examples</title> + <para> Revoke insert privilege from all users on table <literal>films</literal>: - <programlisting> +<programlisting> REVOKE INSERT ON films FROM PUBLIC; - </programlisting> +</programlisting> </para> <para> Revoke all privileges from user <literal>manuel</literal> on view <literal>kinds</literal>: - <programlisting> -REVOKE ALL ON kinds FROM manuel; - </programlisting> +<programlisting> +REVOKE ALL PRIVILEGES ON kinds FROM manuel; +</programlisting> </para> </refsect1> - <refsect1 id="R1-SQL-REVOKE-3"> - <title> - Compatibility - </title> + <refsect1 id="SQL-REVOKE-compatibility"> + <title>Compatibility</title> - <refsect2 id="R2-SQL-REVOKE-4"> - <refsect2info> - <date>1998-09-01</date> - </refsect2info> - <title> - SQL92 - </title> + <refsect2> + <title>SQL92</title> <para> - The SQL92 syntax for <command>REVOKE</command> - has additional capabilities for rescinding - privileges, including those on individual columns in tables: - - <variablelist> - <varlistentry> - <term> - <synopsis> -REVOKE { SELECT | DELETE | USAGE | ALL PRIVILEGES } [, ...] - ON <replaceable class="parameter">object</replaceable> - FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] } { RESTRICT | CASCADE } -REVOKE { INSERT | UPDATE | REFERENCES } [, ...] [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ] - ON <replaceable class="parameter">object</replaceable> - FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] } { RESTRICT | CASCADE } - </synopsis> - </term> - <listitem> - <para> - Refer to - <xref linkend="sql-grant" endterm="sql-grant-title"> - for details on individual fields. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <synopsis> -REVOKE GRANT OPTION FOR <replaceable class="parameter">privilege</replaceable> [, ...] - ON <replaceable class="parameter">object</replaceable> - FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] } { RESTRICT | CASCADE } - </synopsis> - </term> - <listitem> - <para> - Rescinds authority for a user to grant the specified privilege - to others. - Refer to - <xref linkend="sql-grant" endterm="sql-grant-title"> - for details on individual fields. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - - <para> - The possible objects are: - <simplelist> - <member> - [ TABLE ] table/view - </member> - <member> - CHARACTER SET character-set - </member> - <member> - COLLATION collation - </member> - <member> - TRANSLATION translation - </member> - <member> - DOMAIN domain - </member> - </simplelist> + The compatibility notes of the <xref linkend="sql-grant"> command + apply analogously to <command>REVOKE</command>. The syntax summary is: + +<synopsis> +REVOKE [ GRANT OPTION FOR ] { SELECT | INSERT | UPDATE | DELETE | REFERENCES } + ON <replaceable class="parameter">object</replaceable> [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ] + FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] } + { RESTRICT | CASCADE } +</synopsis> </para> <para> If user1 gives a privilege WITH GRANT OPTION to user2, and user2 gives it to user3 then user1 can revoke this privilege in cascade using the CASCADE keyword. - </para> - - <para> If user1 gives a privilege WITH GRANT OPTION to user2, and user2 gives it to user3, then if user1 tries to revoke this privilege it fails if he specify the RESTRICT @@ -381,6 +98,15 @@ REVOKE GRANT OPTION FOR <replaceable class="parameter">privilege</replaceable> [ </para> </refsect2> </refsect1> + + <refsect1> + <title>See Also</title> + + <simpara> + <xref linkend="sql-grant"> + </simpara> + </refsect1> + </refentry> <!-- Keep this comment at the end of the file diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index d9311c95a07..1106798d4a2 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/select.sgml,v 1.40 2001/03/24 23:03:26 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/select.sgml,v 1.41 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-SELECT"> <refmeta> - <refentrytitle id="sql-select-title"> - SELECT - </refentrytitle> + <refentrytitle id="sql-select-title">SELECT</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml index 58966c9b4ab..f47b2663ac3 100644 --- a/doc/src/sgml/ref/update.sgml +++ b/doc/src/sgml/ref/update.sgml @@ -1,13 +1,11 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.14 2001/01/13 23:58:55 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.15 2001/05/27 09:59:28 petere Exp $ Postgres documentation --> <refentry id="SQL-UPDATE"> <refmeta> - <refentrytitle id="SQL-UPDATE-TITLE"> - UPDATE - </refentrytitle> + <refentrytitle id="SQL-UPDATE-TITLE">UPDATE</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> <refnamediv> diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index bfc4cc2a454..5ef74cb1d55 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.47 2001/03/22 03:59:18 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.48 2001/05/27 09:59:28 petere Exp $ * * NOTES * See acl.h. @@ -46,7 +46,7 @@ char *aclcheck_error_strings[] = { }; -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG static dumpacl(Acl *acl) { @@ -62,7 +62,7 @@ dumpacl(Acl *acl) PointerGetDatum(aip + i)))); } -#endif +#endif /* ACLDEBUG */ /* * ChangeAcl @@ -116,13 +116,13 @@ ChangeAcl(char *relname, old_acl = DatumGetAclPCopy(aclDatum); } -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG dumpacl(old_acl); #endif new_acl = aclinsert3(old_acl, mod_aip, modechg); -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG dumpacl(new_acl); #endif @@ -285,7 +285,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) { if (aip->ai_id == id) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "aclcheck: found user %u/%d", aip->ai_id, aip->ai_mode); #endif @@ -301,7 +301,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) { if (in_group(id, aip->ai_id)) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "aclcheck: found group %u/%d", aip->ai_id, aip->ai_mode); #endif @@ -324,7 +324,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) { if (aip->ai_id == id) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "aclcheck: found group %u/%d", aip->ai_id, aip->ai_mode); #endif @@ -341,7 +341,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) break; } -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode); #endif return (aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV; @@ -371,7 +371,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) * pg_shadow.usecatupd is set. (This is to let superusers protect * themselves from themselves.) */ - if (((mode & ACL_WR) || (mode & ACL_AP)) && + if (((mode & ACL_UPDATE) || (mode & ACL_INSERT) || (mode & ACL_DELETE)) && !allowSystemTableMods && IsSystemRelationName(relname) && strncmp(relname, "pg_temp.", strlen("pg_temp.")) != 0 && !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd) @@ -387,7 +387,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) */ if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "pg_aclcheck: \"%s\" is superuser", usename); #endif @@ -454,7 +454,7 @@ pg_ownercheck(Oid userid, */ if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", usename); #endif @@ -528,7 +528,7 @@ pg_func_ownercheck(Oid userid, */ if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", usename); #endif @@ -576,7 +576,7 @@ pg_aggr_ownercheck(Oid userid, */ if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) { -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser", usename); #endif diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index bc5153b8005..90cfba50be5 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.128 2001/05/21 14:22:11 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.129 2001/05/27 09:59:28 petere Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -1939,9 +1939,10 @@ LockTableCommand(LockStmt *lockstmt) elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname); if (lockstmt->mode == AccessShareLock) - aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_RD); + aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT); else - aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_WR); + aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), + ACL_UPDATE | ACL_DELETE); if (aclresult != ACLCHECK_OK) elog(ERROR, "LOCK TABLE: permission denied"); diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 06397ab323f..7d3ba9b5618 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1999, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.27 2001/03/22 03:59:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.28 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -468,7 +468,7 @@ CommentRewrite(char *rule, char *comment) #ifndef NO_SECURITY relation = RewriteGetRuleEventRel(rule); - aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RU); + aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RULE); if (aclcheck != ACLCHECK_OK) { elog(ERROR, "you are not permitted to comment on rule '%s'", diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 0f249fa385c..fbbade10331 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.136 2001/03/22 06:16:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.137 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -271,7 +271,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, FILE *fp; Relation rel; - const AclMode required_access = from ? ACL_WR : ACL_RD; + const AclMode required_access = from ? ACL_INSERT : ACL_SELECT; int result; /* diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index f1dbbf6d251..f37b6199b24 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.55 2001/05/10 20:38:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.56 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -243,7 +243,7 @@ nextval(PG_FUNCTION_ARGS) rescnt = 0; bool logit = false; - if (pg_aclcheck(seqname, GetUserId(), ACL_WR) != ACLCHECK_OK) + if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK) elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s", seqname, seqname); @@ -390,7 +390,7 @@ currval(PG_FUNCTION_ARGS) SeqTable elm; int32 result; - if (pg_aclcheck(seqname, GetUserId(), ACL_RD) != ACLCHECK_OK) + if (pg_aclcheck(seqname, GetUserId(), ACL_SELECT) != ACLCHECK_OK) elog(ERROR, "%s.currval: you don't have permissions to read sequence %s", seqname, seqname); @@ -428,7 +428,7 @@ do_setval(char *seqname, int32 next, bool iscalled) Buffer buf; Form_pg_sequence seq; - if (pg_aclcheck(seqname, GetUserId(), ACL_WR) != ACLCHECK_OK) + if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK) elog(ERROR, "%s.setval: you don't have permissions to set sequence %s", seqname, seqname); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 70f2e1b2957..70c146530f1 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.90 2001/03/22 06:16:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.91 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -69,8 +69,10 @@ CreateTrigger(CreateTrigStmt *stmt) if (!allowSystemTableMods && IsSystemRelationName(stmt->relname)) elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relname); - if (!pg_ownercheck(GetUserId(), stmt->relname, RELNAME)) - elog(ERROR, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]); + if (pg_aclcheck(stmt->relname, GetUserId(), + stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER) + != ACLCHECK_OK) + elog(ERROR, "permission denied"); /* * If trigger is a constraint, user trigger name as constraint name diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index eda6ce518d2..f87b674b074 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.140 2001/05/15 00:33:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.141 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -420,7 +420,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation) if (rte->checkForRead) { - aclcheck_result = CHECK(ACL_RD); + aclcheck_result = CHECK(ACL_SELECT); if (aclcheck_result != ACLCHECK_OK) elog(ERROR, "%s: %s", relName, aclcheck_error_strings[aclcheck_result]); @@ -437,15 +437,14 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation) switch (operation) { case CMD_INSERT: - /* Accept either APPEND or WRITE access for this */ - aclcheck_result = CHECK(ACL_AP); - if (aclcheck_result != ACLCHECK_OK) - aclcheck_result = CHECK(ACL_WR); + aclcheck_result = CHECK(ACL_INSERT); break; case CMD_SELECT: - case CMD_DELETE: case CMD_UPDATE: - aclcheck_result = CHECK(ACL_WR); + aclcheck_result = CHECK(ACL_UPDATE); + break; + case CMD_DELETE: + aclcheck_result = CHECK(ACL_DELETE); break; default: elog(ERROR, "ExecCheckRTEPerms: bogus operation %d", diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 5857f6ee642..37c28495e54 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.226 2001/05/14 20:30:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.227 2001/05/27 09:59:29 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -2234,19 +2234,19 @@ from_in: IN * *****************************************************************************/ -GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant +GrantStmt: GRANT privileges ON opt_table relation_name_list TO grantee opt_with_grant { - $$ = (Node*)makeAclStmt($2,$4,$6,'+'); + $$ = (Node*)makeAclStmt($2,$5,$7,'+'); } ; privileges: ALL PRIVILEGES { - $$ = aclmakepriv("rwaR",0); + $$ = aclmakepriv(ACL_MODE_STR,0); } | ALL { - $$ = aclmakepriv("rwaR",0); + $$ = aclmakepriv(ACL_MODE_STR,0); } | operation_commalist { @@ -2266,23 +2266,31 @@ operation_commalist: operation operation: SELECT { - $$ = ACL_MODE_RD_CHR; + $$ = ACL_MODE_SELECT_CHR; } | INSERT { - $$ = ACL_MODE_AP_CHR; + $$ = ACL_MODE_INSERT_CHR; } | UPDATE { - $$ = ACL_MODE_WR_CHR; + $$ = ACL_MODE_UPDATE_CHR; } | DELETE { - $$ = ACL_MODE_WR_CHR; + $$ = ACL_MODE_DELETE_CHR; } | RULE { - $$ = ACL_MODE_RU_CHR; + $$ = ACL_MODE_RULE_CHR; + } + | REFERENCES + { + $$ = ACL_MODE_REFERENCES_CHR; + } + | TRIGGER + { + $$ = ACL_MODE_TRIGGER_CHR; } ; @@ -2315,9 +2323,9 @@ opt_with_grant: WITH GRANT OPTION * *****************************************************************************/ -RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee +RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee { - $$ = (Node*)makeAclStmt($2,$4,$6,'-'); + $$ = (Node*)makeAclStmt($2,$5,$7,'-'); } ; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index b616f7e68ef..dc569455b26 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.110 2001/05/07 00:43:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.111 2001/05/27 09:59:29 petere Exp $ * *------------------------------------------------------------------------- */ @@ -267,7 +267,7 @@ ProcessUtility(Node *parsetree, int aclcheck_result; relationName = RewriteGetRuleEventRel(rulename); - aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RU); + aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RULE); if (aclcheck_result != ACLCHECK_OK) elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]); @@ -550,7 +550,7 @@ ProcessUtility(Node *parsetree, int aclcheck_result; relname = stmt->object->relname; - aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RU); + aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE); if (aclcheck_result != ACLCHECK_OK) elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]); set_ps_display(commandTag = "CREATE"); diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 10e2f13bc32..f4e3fe9986d 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.58 2001/03/22 03:59:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.59 2001/05/27 09:59:30 petere Exp $ * *------------------------------------------------------------------------- */ @@ -113,8 +113,8 @@ aclparse(char *s, AclItem *aip, unsigned *modechg) Assert(s && aip && modechg); -#ifdef ACLDEBUG_TRACE - printf("aclparse: input = '%s'\n", s); +#ifdef ACLDEBUG + elog(DEBUG, "aclparse: input = '%s'", s); #endif aip->ai_idtype = ACL_IDTYPE_UID; s = getid(s, name); @@ -155,17 +155,26 @@ aclparse(char *s, AclItem *aip, unsigned *modechg) { switch (*s) { - case ACL_MODE_AP_CHR: - aip->ai_mode |= ACL_AP; + case ACL_MODE_INSERT_CHR: + aip->ai_mode |= ACL_INSERT; break; - case ACL_MODE_RD_CHR: - aip->ai_mode |= ACL_RD; + case ACL_MODE_SELECT_CHR: + aip->ai_mode |= ACL_SELECT; break; - case ACL_MODE_WR_CHR: - aip->ai_mode |= ACL_WR; + case ACL_MODE_UPDATE_CHR: + aip->ai_mode |= ACL_UPDATE; break; - case ACL_MODE_RU_CHR: - aip->ai_mode |= ACL_RU; + case ACL_MODE_DELETE_CHR: + aip->ai_mode |= ACL_DELETE; + break; + case ACL_MODE_RULE_CHR: + aip->ai_mode |= ACL_RULE; + break; + case ACL_MODE_REFERENCES_CHR: + aip->ai_mode |= ACL_REFERENCES; + break; + case ACL_MODE_TRIGGER_CHR: + aip->ai_mode |= ACL_TRIGGER; break; default: elog(ERROR, "aclparse: mode flags must use \"%s\"", @@ -192,7 +201,7 @@ aclparse(char *s, AclItem *aip, unsigned *modechg) break; } -#ifdef ACLDEBUG_TRACE +#ifdef ACLDEBUG elog(DEBUG, "aclparse: correctly read [%x %d %x], modechg=%x", aip->ai_idtype, aip->ai_id, aip->ai_mode, *modechg); #endif @@ -269,7 +278,7 @@ aclitemout(PG_FUNCTION_ARGS) unsigned i; char *tmpname; - p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN); + p = out = palloc(strlen("group =" ACL_MODE_STR " ") + 1 + NAMEDATALEN); *p = '\0'; switch (aip->ai_idtype) @@ -368,14 +377,13 @@ acldefault(char *relname, AclId ownerid) AclItem *aip; #define ACL_WORLD_DEFAULT (ACL_NO) -/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */ -#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) +#define ACL_OWNER_DEFAULT (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER) acl = makeacl(2); aip = ACL_DAT(acl); aip[0].ai_idtype = ACL_IDTYPE_WORLD; aip[0].ai_id = ACL_ID_WORLD; - aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_RD : ACL_WORLD_DEFAULT; + aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_SELECT : ACL_WORLD_DEFAULT; aip[1].ai_idtype = ACL_IDTYPE_UID; aip[1].ai_id = ownerid; aip[1].ai_mode = ACL_OWNER_DEFAULT; @@ -651,8 +659,8 @@ aclmakepriv(char *old_privlist, char new_priv) int i; int l; - Assert(strlen(old_privlist) < 5); - priv = palloc(5); /* at most "rwaR" */ ; + Assert(strlen(old_privlist) <= strlen(ACL_MODE_STR)); + priv = palloc(strlen(ACL_MODE_STR)+1); if (old_privlist == NULL || old_privlist[0] == '\0') { @@ -665,7 +673,7 @@ aclmakepriv(char *old_privlist, char new_priv) l = strlen(old_privlist); - if (l == 4) + if (l == strlen(ACL_MODE_STR)) { /* can't add any more privileges */ return priv; } diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 7e09390c3ca..02e6094c51e 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: acl.h,v 1.31 2001/03/22 04:01:10 momjian Exp $ + * $Id: acl.h,v 1.32 2001/05/27 09:59:30 petere Exp $ * * NOTES * For backward-compatibility purposes we have to allow there @@ -52,11 +52,14 @@ typedef uint8 AclIdType; typedef uint8 AclMode; #define ACL_NO 0 /* no permissions */ -#define ACL_AP (1<<0) /* append */ -#define ACL_RD (1<<1) /* read */ -#define ACL_WR (1<<2) /* write (append/delete/replace) */ -#define ACL_RU (1<<3) /* place rules */ -#define N_ACL_MODES 4 +#define ACL_INSERT (1<<0) +#define ACL_SELECT (1<<1) +#define ACL_UPDATE (1<<2) +#define ACL_DELETE (1<<3) +#define ACL_RULE (1<<4) +#define ACL_REFERENCES (1<<5) +#define ACL_TRIGGER (1<<6) +#define N_ACL_MODES 7 /* 1 plus the last 1<<x */ /* * AclItem @@ -146,11 +149,14 @@ typedef ArrayType IdList; #define ACL_MODECHG_ADD_CHR '+' #define ACL_MODECHG_DEL_CHR '-' #define ACL_MODECHG_EQL_CHR '=' -#define ACL_MODE_STR "arwR" /* list of valid characters */ -#define ACL_MODE_AP_CHR 'a' -#define ACL_MODE_RD_CHR 'r' -#define ACL_MODE_WR_CHR 'w' -#define ACL_MODE_RU_CHR 'R' +#define ACL_MODE_STR "arwdRxt" /* list of valid characters */ +#define ACL_MODE_INSERT_CHR 'a' /* formerly known as "append" */ +#define ACL_MODE_SELECT_CHR 'r' /* formerly known as "read" */ +#define ACL_MODE_UPDATE_CHR 'w' /* formerly known as "write" */ +#define ACL_MODE_DELETE_CHR 'd' +#define ACL_MODE_RULE_CHR 'R' +#define ACL_MODE_REFERENCES_CHR 'x' +#define ACL_MODE_TRIGGER_CHR 't' /* result codes for pg_aclcheck */ #define ACLCHECK_OK 0 @@ -161,11 +167,6 @@ typedef ArrayType IdList; /* warning messages. set these in aclchk.c. */ extern char *aclcheck_error_strings[]; -/* - * Enable ACL execution tracing and table dumps - */ -/*#define ACLDEBUG_TRACE*/ - /* * routines used internally */ diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out new file mode 100644 index 00000000000..cb376e0bbc8 --- /dev/null +++ b/src/test/regress/expected/privileges.out @@ -0,0 +1,198 @@ +-- +-- Test access privileges +-- +CREATE USER regressuser1; +CREATE USER regressuser2; +CREATE USER regressuser3; +CREATE USER regressuser4; +CREATE USER regressuser4; -- duplicate +ERROR: CREATE USER: user name "regressuser4" already exists +CREATE GROUP regressgroup1; +CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; +ALTER GROUP regressgroup1 ADD USER regressuser4; +ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate +NOTICE: ALTER GROUP: user "regressuser2" is already in group "regressgroup2" +ALTER GROUP regressgroup2 DROP USER regressuser2; +ALTER GROUP regressgroup2 ADD USER regressuser4; +-- test owner privileges +SET SESSION AUTHORIZATION regressuser1; +SELECT session_user, current_user; + session_user | current_user +--------------+-------------- + regressuser1 | regressuser1 +(1 row) + +CREATE TABLE atest1 ( a int, b text ); +SELECT * FROM atest1; + a | b +---+--- +(0 rows) + +INSERT INTO atest1 VALUES (1, 'one'); +DELETE FROM atest1; +UPDATE atest1 SET a = 1 WHERE b = 'blech'; +LOCK atest1 IN ACCESS EXCLUSIVE MODE; +REVOKE ALL ON atest1 FROM PUBLIC; +SELECT * FROM atest1; + a | b +---+--- +(0 rows) + +GRANT ALL ON atest1 TO regressuser2; +GRANT SELECT ON atest1 TO regressuser3; +SELECT * FROM atest1; + a | b +---+--- +(0 rows) + +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); +GRANT SELECT ON atest2 TO regressuser2; +GRANT UPDATE ON atest2 TO regressuser3; +GRANT INSERT ON atest2 TO regressuser4; +SET SESSION AUTHORIZATION regressuser2; +SELECT session_user, current_user; + session_user | current_user +--------------+-------------- + regressuser2 | regressuser2 +(1 row) + +-- try various combinations of queries on atest1 and atest2 +SELECT * FROM atest1; -- ok + a | b +---+--- +(0 rows) + +SELECT * FROM atest2; -- ok + col1 | col2 +------+------ +(0 rows) + +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest2 VALUES ('foo', true); -- fail +ERROR: atest2: Permission denied. +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok +UPDATE atest1 SET a = 1 WHERE a = 2; -- ok +UPDATE atest2 SET col2 = NOT col2; -- fail +ERROR: atest2: Permission denied. +SELECT * FROM atest1 FOR UPDATE; -- ok + a | b +---+----- + 1 | two + 1 | two +(2 rows) + +SELECT * FROM atest2 FOR UPDATE; -- fail +ERROR: atest2: Permission denied. +DELETE FROM atest2; -- fail +ERROR: atest2: Permission denied. +LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail +ERROR: LOCK TABLE: permission denied +COPY atest2 FROM stdin; -- fail +ERROR: atest2: Permission denied. +GRANT ALL ON atest1 TO PUBLIC; -- fail +ERROR: you do not own class "atest1" +-- checks in subquery, both ok +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); + a | b +---+--- +(0 rows) + +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + col1 | col2 +------+------ +(0 rows) + +SET SESSION AUTHORIZATION regressuser3; +SELECT session_user, current_user; + session_user | current_user +--------------+-------------- + regressuser3 | regressuser3 +(1 row) + +SELECT * FROM atest1; -- ok + a | b +---+----- + 1 | two + 1 | two +(2 rows) + +SELECT * FROM atest2; -- fail +ERROR: atest2: Permission denied. +INSERT INTO atest1 VALUES (2, 'two'); -- fail +ERROR: atest1: Permission denied. +INSERT INTO atest2 VALUES ('foo', true); -- fail +ERROR: atest2: Permission denied. +INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail +ERROR: atest1: Permission denied. +UPDATE atest1 SET a = 1 WHERE a = 2; -- fail +ERROR: atest1: Permission denied. +UPDATE atest2 SET col2 = NULL; -- ok +UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2 +ERROR: atest2: Permission denied. +UPDATE atest2 SET col2 = true WHERE atest1.a = 5; -- ok +SELECT * FROM atest1 FOR UPDATE; -- fail +ERROR: atest1: Permission denied. +SELECT * FROM atest2 FOR UPDATE; -- fail +ERROR: atest2: Permission denied. +DELETE FROM atest2; -- fail +ERROR: atest2: Permission denied. +LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok +COPY atest2 FROM stdin; -- fail +ERROR: atest2: Permission denied. +-- checks in subquery, both fail +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); +ERROR: atest2: Permission denied. +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); +ERROR: atest2: Permission denied. +SET SESSION AUTHORIZATION regressuser4; +COPY atest2 FROM stdin; -- ok +-- groups +SET SESSION AUTHORIZATION regressuser3; +CREATE TABLE atest3 (one int, two int, three int); +GRANT DELETE ON atest3 TO GROUP regressgroup2; +SET SESSION AUTHORIZATION regressuser1; +SELECT * FROM atest3; -- fail +ERROR: atest3: Permission denied. +DELETE FROM atest3; -- ok +-- views +SET SESSION AUTHORIZATION regressuser3; +CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok +/* The next *should* fail, but it's not implemented that way yet. */ +CREATE VIEW atestv2 AS SELECT * FROM atest2; +CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok +SELECT * FROM atestv1; -- ok + a | b +---+----- + 1 | two + 1 | two +(2 rows) + +GRANT SELECT ON atestv1 TO regressuser4; +GRANT SELECT ON atestv3 TO regressuser4; +SET SESSION AUTHORIZATION regressuser4; +SELECT * FROM atestv1; -- ok + a | b +---+----- + 1 | two + 1 | two +(2 rows) + +SELECT * FROM atestv3; -- ok + one | two | three +-----+-----+------- +(0 rows) + +-- clean up +\c regression +DROP TABLE atest1; +DROP TABLE atest2; +DROP TABLE atest3; +DROP VIEW atestv1; +DROP VIEW atestv2; +DROP VIEW atestv3; +DROP GROUP regressgroup1; +DROP GROUP regressgroup2; +DROP USER regressuser1; +DROP USER regressuser2; +DROP USER regressuser3; +DROP USER regressuser4; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index f37b2054e40..08e97511ac9 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -61,6 +61,7 @@ test: select ignore: random test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index +test: privileges test: misc # ---------- diff --git a/src/test/regress/pg_regress.sh b/src/test/regress/pg_regress.sh index 8eb74b28010..552724a10f1 100644 --- a/src/test/regress/pg_regress.sh +++ b/src/test/regress/pg_regress.sh @@ -1,5 +1,5 @@ #! /bin/sh -# $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.20 2001/03/24 23:32:25 petere Exp $ +# $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.21 2001/05/27 09:59:30 petere Exp $ me=`basename $0` : ${TMPDIR=/tmp} @@ -432,6 +432,18 @@ if [ $? -ne 0 ]; then fi +# ---------- +# Remove regressuser* and regressgroup* user accounts. +# ---------- + +message "dropping regression test user accounts" +"$bindir/psql" $psql_options -c 'drop group regressgroup1; drop group regressgroup2; drop user regressuser1, regressuser2, regressuser3, regressuser4;' $dbname 2>/dev/null +if [ $? -eq 2 ]; then + echo "$me: could not drop user accounts" + (exit 2); exit +fi + + # ---------- # Install the PL/pgSQL language in it # ---------- diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 14ad6f505e0..afb0090cdad 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.3 2000/11/22 13:37:44 petere Exp $ +# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.4 2001/05/27 09:59:30 petere Exp $ # This should probably be in an order similar to parallel_schedule. test: boolean test: char @@ -68,6 +68,7 @@ test: portals test: arrays test: btree_index test: hash_index +test: privileges test: misc test: select_views test: alter_table diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql new file mode 100644 index 00000000000..1558273f7b2 --- /dev/null +++ b/src/test/regress/sql/privileges.sql @@ -0,0 +1,146 @@ +-- +-- Test access privileges +-- + +CREATE USER regressuser1; +CREATE USER regressuser2; +CREATE USER regressuser3; +CREATE USER regressuser4; +CREATE USER regressuser4; -- duplicate + +CREATE GROUP regressgroup1; +CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; + +ALTER GROUP regressgroup1 ADD USER regressuser4; + +ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate +ALTER GROUP regressgroup2 DROP USER regressuser2; +ALTER GROUP regressgroup2 ADD USER regressuser4; + + +-- test owner privileges + +SET SESSION AUTHORIZATION regressuser1; +SELECT session_user, current_user; + +CREATE TABLE atest1 ( a int, b text ); +SELECT * FROM atest1; +INSERT INTO atest1 VALUES (1, 'one'); +DELETE FROM atest1; +UPDATE atest1 SET a = 1 WHERE b = 'blech'; +LOCK atest1 IN ACCESS EXCLUSIVE MODE; + +REVOKE ALL ON atest1 FROM PUBLIC; +SELECT * FROM atest1; + +GRANT ALL ON atest1 TO regressuser2; +GRANT SELECT ON atest1 TO regressuser3; +SELECT * FROM atest1; + +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); +GRANT SELECT ON atest2 TO regressuser2; +GRANT UPDATE ON atest2 TO regressuser3; +GRANT INSERT ON atest2 TO regressuser4; + + +SET SESSION AUTHORIZATION regressuser2; +SELECT session_user, current_user; + +-- try various combinations of queries on atest1 and atest2 + +SELECT * FROM atest1; -- ok +SELECT * FROM atest2; -- ok +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest2 VALUES ('foo', true); -- fail +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok +UPDATE atest1 SET a = 1 WHERE a = 2; -- ok +UPDATE atest2 SET col2 = NOT col2; -- fail +SELECT * FROM atest1 FOR UPDATE; -- ok +SELECT * FROM atest2 FOR UPDATE; -- fail +DELETE FROM atest2; -- fail +LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail +COPY atest2 FROM stdin; -- fail +GRANT ALL ON atest1 TO PUBLIC; -- fail + +-- checks in subquery, both ok +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + + +SET SESSION AUTHORIZATION regressuser3; +SELECT session_user, current_user; + +SELECT * FROM atest1; -- ok +SELECT * FROM atest2; -- fail +INSERT INTO atest1 VALUES (2, 'two'); -- fail +INSERT INTO atest2 VALUES ('foo', true); -- fail +INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail +UPDATE atest1 SET a = 1 WHERE a = 2; -- fail +UPDATE atest2 SET col2 = NULL; -- ok +UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2 +UPDATE atest2 SET col2 = true WHERE atest1.a = 5; -- ok +SELECT * FROM atest1 FOR UPDATE; -- fail +SELECT * FROM atest2 FOR UPDATE; -- fail +DELETE FROM atest2; -- fail +LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok +COPY atest2 FROM stdin; -- fail + +-- checks in subquery, both fail +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + +SET SESSION AUTHORIZATION regressuser4; +COPY atest2 FROM stdin; -- ok +bar true +\. + + +-- groups + +SET SESSION AUTHORIZATION regressuser3; +CREATE TABLE atest3 (one int, two int, three int); +GRANT DELETE ON atest3 TO GROUP regressgroup2; + +SET SESSION AUTHORIZATION regressuser1; + +SELECT * FROM atest3; -- fail +DELETE FROM atest3; -- ok + + +-- views + +SET SESSION AUTHORIZATION regressuser3; + +CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok +/* The next *should* fail, but it's not implemented that way yet. */ +CREATE VIEW atestv2 AS SELECT * FROM atest2; +CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok + +SELECT * FROM atestv1; -- ok +GRANT SELECT ON atestv1 TO regressuser4; +GRANT SELECT ON atestv3 TO regressuser4; + +SET SESSION AUTHORIZATION regressuser4; + +SELECT * FROM atestv1; -- ok +SELECT * FROM atestv3; -- ok + + +-- clean up + +\c regression +DROP TABLE atest1; +DROP TABLE atest2; +DROP TABLE atest3; + +DROP VIEW atestv1; +DROP VIEW atestv2; +DROP VIEW atestv3; + +DROP GROUP regressgroup1; +DROP GROUP regressgroup2; + +DROP USER regressuser1; +DROP USER regressuser2; +DROP USER regressuser3; +DROP USER regressuser4; -- GitLab