diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2001-05-27 09:59:30 +0000 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2001-05-27 09:59:30 +0000 |
commit | 96147a6d1c15b7604838dcd5de5ebd771f551d96 (patch) | |
tree | 54ad7d06fff6c8d331194285bf3a7718630f5976 | |
parent | 52350c7ad965d856da74514f89b88ce4ffbd18e7 (diff) | |
download | postgresql-96147a6d1c15b7604838dcd5de5ebd771f551d96.tar.gz postgresql-96147a6d1c15b7604838dcd5de5ebd771f551d96.zip |
Make UPDATE and DELETE privileges distinct. Add REFERENCES and TRIGGER
privileges. INSERT and COPY FROM now require INSERT (only). Add
privileges regression test.
26 files changed, 724 insertions, 826 deletions
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 @@ -162,11 +168,6 @@ typedef ArrayType IdList; extern char *aclcheck_error_strings[]; /* - * Enable ACL execution tracing and table dumps - */ -/*#define ACLDEBUG_TRACE*/ - -/* * routines used internally */ extern Acl *acldefault(char *relname, AclId ownerid); 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} @@ -433,6 +433,18 @@ 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; |