提交 96147a6d 编写于 作者: P Peter Eisentraut

Make UPDATE and DELETE privileges distinct. Add REFERENCES and TRIGGER

privileges.  INSERT and COPY FROM now require INSERT (only).  Add
privileges regression test.
上级 52350c7a
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-COPY"> <refentry id="SQL-COPY">
<refmeta> <refmeta>
<refentrytitle id="sql-copy-title"> <refentrytitle id="sql-copy-title">COPY</refentrytitle>
COPY
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-CREATERULE"> <refentry id="SQL-CREATERULE">
<refmeta> <refmeta>
<refentrytitle id="sql-createrule-title"> <refentrytitle id="sql-createrule-title">CREATE RULE</refentrytitle>
CREATE RULE
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-CREATETRIGGER"> <refentry id="SQL-CREATETRIGGER">
<refmeta> <refmeta>
<refentrytitle id="SQL-CREATETRIGGER-TITLE"> <refentrytitle id="SQL-CREATETRIGGER-TITLE">CREATE TRIGGER</refentrytitle>
CREATE TRIGGER
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-DELETE"> <refentry id="SQL-DELETE">
<refmeta> <refmeta>
<refentrytitle id="SQL-DELETE-TITLE"> <refentrytitle id="SQL-DELETE-TITLE">DELETE</refentrytitle>
DELETE
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-GRANT"> <refentry id="SQL-GRANT">
<refmeta> <refmeta>
<refentrytitle id="SQL-GRANT-TITLE"> <refentrytitle>GRANT</refentrytitle>
GRANT
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname> <refname>GRANT</refname>
GRANT <refpurpose>Grants access privileges to a user, a group, or all users</refpurpose>
</refname>
<refpurpose>
Grants access privilege to a user, a group or all users
</refpurpose>
</refnamediv> </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> <refsynopsisdiv>
<varlistentry> <synopsis>
<term><computeroutput> GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
CHANGE ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...]
</computeroutput></term> TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC }
<listitem> </synopsis>
<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> </refsynopsisdiv>
<refsect1 id="R1-SQL-GRANT-1"> <refsect1 id="sql-grant-description">
<refsect1info> <title>Description</title>
<date>1998-09-23</date>
</refsect1info> <para>
<title> The <command>GRANT</command> command gives specific permissions on
Description an object (table, view, sequence) to a user or a group of users.
</title> 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> <para>
<command>GRANT</command> allows the creator of an object to give specific permissions to Users other than the creator do not have any access privileges
all users (PUBLIC) or to a certain user or group. unless the creator grants permissions, after the object is created.
Users other than the creator don't have any access permission There is no need to grant privileges to the creator of an object,
unless the creator GRANTs permissions, after the object as the creator automatically holds all privileges, and can also
is created. drop the object.
</para> </para>
<para> <para>
Once a user has a privilege on an object, he is enabled to exercise The possible privileges are:
that privilege.
There is no need to GRANT privileges to the creator of <variablelist>
an object, the creator automatically holds ALL privileges, and can <varlistentry>
also drop the object. <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> </para>
</refsect1>
<refsect2 id="R2-SQL-GRANT-3"> <refsect1 id="SQL-GRANT-notes">
<refsect2info> <title>Notes</title>
<date>1998-09-23</date>
</refsect2info>
<title>
Notes
</title>
<para> <para>
Currently, to grant privileges in <productname>Postgres</productname> Currently, to grant privileges in <productname>Postgres</productname>
to only a few columns, you must 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. to that view.
</para> </para>
<para> <para>
Use <command>psql \z</command> Use <xref linkend="app-psql">'s <command>\z</command> command
for further information about permissions to obtain information about privileges
on existing objects: on existing objects:
<programlisting> <programlisting>
Database = lusitania Database = lusitania
+------------------+---------------------------------------------+ +------------------+---------------------------------------------+
| Relation | Grant/Revoke Permissions | | Relation | Grant/Revoke Permissions |
+------------------+---------------------------------------------+ +------------------+---------------------------------------------+
| mytable | {"=rw","miriam=arwR","group todos=rw"} | | mytable | {"=rw","miriam=arwdRxt","group todos=rw"} |
+------------------+---------------------------------------------+ +------------------+---------------------------------------------+
Legend: Legend:
uname=arwR -- privileges granted to a user 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 =arwR -- privileges granted to PUBLIC
r -- SELECT r -- SELECT ("read")
w -- UPDATE/DELETE w -- UPDATE ("write")
a -- INSERT a -- INSERT ("append")
d -- DELETE
R -- RULE R -- RULE
arwR -- ALL x -- REFERENCES
</programlisting> t -- TRIGGER
arwdRxt -- ALL PRIVILEGES
</programlisting>
</para> </para>
<para> <para>
Refer to REVOKE statements to revoke access privileges. The <xref linkend="sql-revoke"> command is used to revoke access
privileges.
</para> </para>
</refsect2>
</refsect1> </refsect1>
<refsect1 id="R1-SQL-GRANT-2"> <refsect1 id="sql-grant-examples">
<title> <title>Examples</title>
Usage
</title>
<para> <para>
Grant insert privilege to all users on table films: Grant insert privilege to all users on table films:
<programlisting> <programlisting>
GRANT INSERT ON films TO PUBLIC; GRANT INSERT ON films TO PUBLIC;
</programlisting> </programlisting>
</para> </para>
<para> <para>
Grant all privileges to user manuel on view kinds: Grant all privileges to user manuel on view kinds:
<programlisting> <programlisting>
GRANT ALL ON kinds TO manuel; GRANT ALL PRIVILEGES ON kinds TO manuel;
</programlisting> </programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1 id="R1-SQL-GRANT-3"> <refsect1 id="sql-grant-compatibility">
<title> <title>Compatibility</title>
Compatibility
</title>
<refsect2 id="R2-SQL-GRANT-4"> <refsect2>
<refsect2info> <title>SQL92</title>
<date>1998-09-23</date>
</refsect2info>
<title>
SQL92
</title>
<para> <para>
The <acronym>SQL92</acronym> syntax for GRANT allows setting privileges The <literal>PRIVILEGES</literal> key word in <literal>ALL
for individual columns PRIVILEGES</literal> is required. <acronym>SQL</acronym> does not
within a table, and allows setting a privilege to grant support setting the privileges on more than one table per command.
the same privileges to others: </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> [, ...] GRANT <replaceable class="PARAMETER">privilege</replaceable> [, ...]
ON <replaceable class="PARAMETER">object</replaceable> [ ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) ] [, ...] ON <replaceable class="PARAMETER">object</replaceable> [ ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) ] [, ...]
TO { PUBLIC | <replaceable class="PARAMETER">username</replaceable> [, ...] } [ WITH GRANT OPTION ] 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>
<para> <para>
Fields are compatible with those in the <acronym>Postgres</acronym> The TRIGGER privilege was introduced in SQL99. The RULE privilege
implementation, with the following additions: is a PostgreSQL extension.
<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>
</para> </para>
</refsect2> </refsect2>
</refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<xref linkend="sql-revoke">
</simpara>
</refsect1> </refsect1>
</refentry> </refentry>
<!-- Keep this comment at the end of the file <!-- Keep this comment at the end of the file
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-INSERT"> <refentry id="SQL-INSERT">
<refmeta> <refmeta>
<refentrytitle id="SQL-INSERT-TITLE"> <refentrytitle id="SQL-INSERT-TITLE">INSERT</refentrytitle>
INSERT
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -1187,8 +1187,8 @@ Access permissions for database "test" ...@@ -1187,8 +1187,8 @@ Access permissions for database "test"
</para> </para>
<para> <para>
The commands <xref linkend="SQL-GRANT" endterm="SQL-GRANT-title"> and The commands <xref linkend="SQL-GRANT"> and
<xref linkend="SQL-REVOKE" endterm="SQL-REVOKE-title"> <xref linkend="SQL-REVOKE">
are used to set access permissions. are used to set access permissions.
</para> </para>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-REVOKE"> <refentry id="SQL-REVOKE">
<refmeta> <refmeta>
<refentrytitle id="SQL-REVOKE-TITLE"> <refentrytitle>REVOKE</refentrytitle>
REVOKE
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
<refname> <refname>REVOKE</refname>
REVOKE <refpurpose>Revokes access privilege from a user, a group, or all users.</refpurpose>
</refname>
<refpurpose>
Revokes access privilege from a user, a group or all users.
</refpurpose>
</refnamediv> </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> <refsynopsisdiv>
<para> <synopsis>
view REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
</para> ON [ TABLE ] <replaceable class="PARAMETER">object</replaceable> [, ...]
</listitem> FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC }
</synopsis>
<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> </refsynopsisdiv>
<refsect1 id="R1-SQL-REVOKE-1"> <refsect1 id="SQL-REVOKE-description">
<refsect1info> <title>Description</title>
<date>1998-09-24</date>
</refsect1info>
<title>
Description
</title>
<para> <para>
<command>REVOKE</command> allows creator of an object to revoke permissions granted <command>REVOKE</command> allows the creator of an object to revoke
before, from all users (via PUBLIC) or a certain user or group. 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> </para>
<refsect2 id="R2-SQL-REVOKE-3"> <para>
<refsect2info> See the description of the <xref linkend="sql-grant"> command for
<date>1998-09-24</date> the meaning of the privilege types.
</refsect2info> </para>
<title> </refsect1>
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:
<programlisting> <refsect1 id="SQL-REVOKE-notes">
INSERT INTO pg_group VALUES ('todos'); <title>Notes</title>
CREATE USER miriam IN GROUP todos;
</programlisting>
</para>
</tip>
</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>
<refsect1 id="R1-SQL-REVOKE-2"> <refsect1 id="SQL-REVOKE-examples">
<title> <title>Examples</title>
Usage
</title>
<para> <para>
Revoke insert privilege from all users on table Revoke insert privilege from all users on table
<literal>films</literal>: <literal>films</literal>:
<programlisting> <programlisting>
REVOKE INSERT ON films FROM PUBLIC; REVOKE INSERT ON films FROM PUBLIC;
</programlisting> </programlisting>
</para> </para>
<para> <para>
Revoke all privileges from user <literal>manuel</literal> on view <literal>kinds</literal>: Revoke all privileges from user <literal>manuel</literal> on view <literal>kinds</literal>:
<programlisting> <programlisting>
REVOKE ALL ON kinds FROM manuel; REVOKE ALL PRIVILEGES ON kinds FROM manuel;
</programlisting> </programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1 id="R1-SQL-REVOKE-3"> <refsect1 id="SQL-REVOKE-compatibility">
<title> <title>Compatibility</title>
Compatibility
</title>
<refsect2 id="R2-SQL-REVOKE-4"> <refsect2>
<refsect2info> <title>SQL92</title>
<date>1998-09-01</date>
</refsect2info>
<title>
SQL92
</title>
<para> <para>
The SQL92 syntax for <command>REVOKE</command> The compatibility notes of the <xref linkend="sql-grant"> command
has additional capabilities for rescinding apply analogously to <command>REVOKE</command>. The syntax summary is:
privileges, including those on individual columns in tables:
<synopsis>
<variablelist> REVOKE [ GRANT OPTION FOR ] { SELECT | INSERT | UPDATE | DELETE | REFERENCES }
<varlistentry> ON <replaceable class="parameter">object</replaceable> [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
<term> FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] }
<synopsis> { RESTRICT | CASCADE }
REVOKE { SELECT | DELETE | USAGE | ALL PRIVILEGES } [, ...] </synopsis>
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>
</para> </para>
<para> <para>
If user1 gives a privilege WITH GRANT OPTION to user2, If user1 gives a privilege WITH GRANT OPTION to user2,
and user2 gives it to user3 then user1 can revoke and user2 gives it to user3 then user1 can revoke
this privilege in cascade using the CASCADE keyword. this privilege in cascade using the CASCADE keyword.
</para>
<para>
If user1 gives a privilege WITH GRANT OPTION to user2, If user1 gives a privilege WITH GRANT OPTION to user2,
and user2 gives it to user3, then if user1 tries to revoke and user2 gives it to user3, then if user1 tries to revoke
this privilege it fails if he specify the RESTRICT this privilege it fails if he specify the RESTRICT
...@@ -381,6 +98,15 @@ REVOKE GRANT OPTION FOR <replaceable class="parameter">privilege</replaceable> [ ...@@ -381,6 +98,15 @@ REVOKE GRANT OPTION FOR <replaceable class="parameter">privilege</replaceable> [
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<xref linkend="sql-grant">
</simpara>
</refsect1>
</refentry> </refentry>
<!-- Keep this comment at the end of the file <!-- Keep this comment at the end of the file
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-SELECT"> <refentry id="SQL-SELECT">
<refmeta> <refmeta>
<refentrytitle id="sql-select-title"> <refentrytitle id="sql-select-title">SELECT</refentrytitle>
SELECT
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
<!-- <!--
$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 Postgres documentation
--> -->
<refentry id="SQL-UPDATE"> <refentry id="SQL-UPDATE">
<refmeta> <refmeta>
<refentrytitle id="SQL-UPDATE-TITLE"> <refentrytitle id="SQL-UPDATE-TITLE">UPDATE</refentrytitle>
UPDATE
</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo> <refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
...@@ -46,7 +46,7 @@ char *aclcheck_error_strings[] = { ...@@ -46,7 +46,7 @@ char *aclcheck_error_strings[] = {
}; };
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
static static
dumpacl(Acl *acl) dumpacl(Acl *acl)
{ {
...@@ -62,7 +62,7 @@ dumpacl(Acl *acl) ...@@ -62,7 +62,7 @@ dumpacl(Acl *acl)
PointerGetDatum(aip + i)))); PointerGetDatum(aip + i))));
} }
#endif #endif /* ACLDEBUG */
/* /*
* ChangeAcl * ChangeAcl
...@@ -116,13 +116,13 @@ ChangeAcl(char *relname, ...@@ -116,13 +116,13 @@ ChangeAcl(char *relname,
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
} }
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
dumpacl(old_acl); dumpacl(old_acl);
#endif #endif
new_acl = aclinsert3(old_acl, mod_aip, modechg); new_acl = aclinsert3(old_acl, mod_aip, modechg);
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
dumpacl(new_acl); dumpacl(new_acl);
#endif #endif
...@@ -285,7 +285,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -285,7 +285,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
{ {
if (aip->ai_id == id) if (aip->ai_id == id)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "aclcheck: found user %u/%d", elog(DEBUG, "aclcheck: found user %u/%d",
aip->ai_id, aip->ai_mode); aip->ai_id, aip->ai_mode);
#endif #endif
...@@ -301,7 +301,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -301,7 +301,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
{ {
if (in_group(id, aip->ai_id)) if (in_group(id, aip->ai_id))
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "aclcheck: found group %u/%d", elog(DEBUG, "aclcheck: found group %u/%d",
aip->ai_id, aip->ai_mode); aip->ai_id, aip->ai_mode);
#endif #endif
...@@ -324,7 +324,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -324,7 +324,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
{ {
if (aip->ai_id == id) if (aip->ai_id == id)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "aclcheck: found group %u/%d", elog(DEBUG, "aclcheck: found group %u/%d",
aip->ai_id, aip->ai_mode); aip->ai_id, aip->ai_mode);
#endif #endif
...@@ -341,7 +341,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -341,7 +341,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
break; break;
} }
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode); elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
#endif #endif
return (aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV; return (aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV;
...@@ -371,7 +371,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) ...@@ -371,7 +371,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
* pg_shadow.usecatupd is set. (This is to let superusers protect * pg_shadow.usecatupd is set. (This is to let superusers protect
* themselves from themselves.) * themselves from themselves.)
*/ */
if (((mode & ACL_WR) || (mode & ACL_AP)) && if (((mode & ACL_UPDATE) || (mode & ACL_INSERT) || (mode & ACL_DELETE)) &&
!allowSystemTableMods && IsSystemRelationName(relname) && !allowSystemTableMods && IsSystemRelationName(relname) &&
strncmp(relname, "pg_temp.", strlen("pg_temp.")) != 0 && strncmp(relname, "pg_temp.", strlen("pg_temp.")) != 0 &&
!((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd) !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd)
...@@ -387,7 +387,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) ...@@ -387,7 +387,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
*/ */
if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "pg_aclcheck: \"%s\" is superuser", elog(DEBUG, "pg_aclcheck: \"%s\" is superuser",
usename); usename);
#endif #endif
...@@ -454,7 +454,7 @@ pg_ownercheck(Oid userid, ...@@ -454,7 +454,7 @@ pg_ownercheck(Oid userid,
*/ */
if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
usename); usename);
#endif #endif
...@@ -528,7 +528,7 @@ pg_func_ownercheck(Oid userid, ...@@ -528,7 +528,7 @@ pg_func_ownercheck(Oid userid,
*/ */
if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
usename); usename);
#endif #endif
...@@ -576,7 +576,7 @@ pg_aggr_ownercheck(Oid userid, ...@@ -576,7 +576,7 @@ pg_aggr_ownercheck(Oid userid,
*/ */
if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper) if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
{ {
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser", elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser",
usename); usename);
#endif #endif
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -1939,9 +1939,10 @@ LockTableCommand(LockStmt *lockstmt) ...@@ -1939,9 +1939,10 @@ LockTableCommand(LockStmt *lockstmt)
elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname); elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname);
if (lockstmt->mode == AccessShareLock) if (lockstmt->mode == AccessShareLock)
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_RD); aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT);
else else
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_WR); aclresult = pg_aclcheck(lockstmt->relname, GetUserId(),
ACL_UPDATE | ACL_DELETE);
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
elog(ERROR, "LOCK TABLE: permission denied"); elog(ERROR, "LOCK TABLE: permission denied");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 1999, PostgreSQL Global Development Group * Copyright (c) 1999, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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) ...@@ -468,7 +468,7 @@ CommentRewrite(char *rule, char *comment)
#ifndef NO_SECURITY #ifndef NO_SECURITY
relation = RewriteGetRuleEventRel(rule); relation = RewriteGetRuleEventRel(rule);
aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RU); aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RULE);
if (aclcheck != ACLCHECK_OK) if (aclcheck != ACLCHECK_OK)
{ {
elog(ERROR, "you are not permitted to comment on rule '%s'", elog(ERROR, "you are not permitted to comment on rule '%s'",
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -271,7 +271,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
FILE *fp; FILE *fp;
Relation rel; Relation rel;
const AclMode required_access = from ? ACL_WR : ACL_RD; const AclMode required_access = from ? ACL_INSERT : ACL_SELECT;
int result; int result;
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -243,7 +243,7 @@ nextval(PG_FUNCTION_ARGS)
rescnt = 0; rescnt = 0;
bool logit = false; 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", elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
seqname, seqname); seqname, seqname);
...@@ -390,7 +390,7 @@ currval(PG_FUNCTION_ARGS) ...@@ -390,7 +390,7 @@ currval(PG_FUNCTION_ARGS)
SeqTable elm; SeqTable elm;
int32 result; 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", elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
seqname, seqname); seqname, seqname);
...@@ -428,7 +428,7 @@ do_setval(char *seqname, int32 next, bool iscalled) ...@@ -428,7 +428,7 @@ do_setval(char *seqname, int32 next, bool iscalled)
Buffer buf; Buffer buf;
Form_pg_sequence seq; 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", elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
seqname, seqname); seqname, seqname);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -69,8 +69,10 @@ CreateTrigger(CreateTrigStmt *stmt)
if (!allowSystemTableMods && IsSystemRelationName(stmt->relname)) if (!allowSystemTableMods && IsSystemRelationName(stmt->relname))
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relname); elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
if (!pg_ownercheck(GetUserId(), stmt->relname, RELNAME)) if (pg_aclcheck(stmt->relname, GetUserId(),
elog(ERROR, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]); stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
!= ACLCHECK_OK)
elog(ERROR, "permission denied");
/* /*
* If trigger is a constraint, user trigger name as constraint name * If trigger is a constraint, user trigger name as constraint name
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -420,7 +420,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
if (rte->checkForRead) if (rte->checkForRead)
{ {
aclcheck_result = CHECK(ACL_RD); aclcheck_result = CHECK(ACL_SELECT);
if (aclcheck_result != ACLCHECK_OK) if (aclcheck_result != ACLCHECK_OK)
elog(ERROR, "%s: %s", elog(ERROR, "%s: %s",
relName, aclcheck_error_strings[aclcheck_result]); relName, aclcheck_error_strings[aclcheck_result]);
...@@ -437,15 +437,14 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation) ...@@ -437,15 +437,14 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
switch (operation) switch (operation)
{ {
case CMD_INSERT: case CMD_INSERT:
/* Accept either APPEND or WRITE access for this */ aclcheck_result = CHECK(ACL_INSERT);
aclcheck_result = CHECK(ACL_AP);
if (aclcheck_result != ACLCHECK_OK)
aclcheck_result = CHECK(ACL_WR);
break; break;
case CMD_SELECT: case CMD_SELECT:
case CMD_DELETE:
case CMD_UPDATE: case CMD_UPDATE:
aclcheck_result = CHECK(ACL_WR); aclcheck_result = CHECK(ACL_UPDATE);
break;
case CMD_DELETE:
aclcheck_result = CHECK(ACL_DELETE);
break; break;
default: default:
elog(ERROR, "ExecCheckRTEPerms: bogus operation %d", elog(ERROR, "ExecCheckRTEPerms: bogus operation %d",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -2234,19 +2234,19 @@ from_in: IN ...@@ -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 privileges: ALL PRIVILEGES
{ {
$$ = aclmakepriv("rwaR",0); $$ = aclmakepriv(ACL_MODE_STR,0);
} }
| ALL | ALL
{ {
$$ = aclmakepriv("rwaR",0); $$ = aclmakepriv(ACL_MODE_STR,0);
} }
| operation_commalist | operation_commalist
{ {
...@@ -2266,23 +2266,31 @@ operation_commalist: operation ...@@ -2266,23 +2266,31 @@ operation_commalist: operation
operation: SELECT operation: SELECT
{ {
$$ = ACL_MODE_RD_CHR; $$ = ACL_MODE_SELECT_CHR;
} }
| INSERT | INSERT
{ {
$$ = ACL_MODE_AP_CHR; $$ = ACL_MODE_INSERT_CHR;
} }
| UPDATE | UPDATE
{ {
$$ = ACL_MODE_WR_CHR; $$ = ACL_MODE_UPDATE_CHR;
} }
| DELETE | DELETE
{ {
$$ = ACL_MODE_WR_CHR; $$ = ACL_MODE_DELETE_CHR;
} }
| RULE | 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 ...@@ -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,'-');
} }
; ;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -267,7 +267,7 @@ ProcessUtility(Node *parsetree,
int aclcheck_result; int aclcheck_result;
relationName = RewriteGetRuleEventRel(rulename); relationName = RewriteGetRuleEventRel(rulename);
aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RU); aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RULE);
if (aclcheck_result != ACLCHECK_OK) if (aclcheck_result != ACLCHECK_OK)
elog(ERROR, "%s: %s", relationName, elog(ERROR, "%s: %s", relationName,
aclcheck_error_strings[aclcheck_result]); aclcheck_error_strings[aclcheck_result]);
...@@ -550,7 +550,7 @@ ProcessUtility(Node *parsetree, ...@@ -550,7 +550,7 @@ ProcessUtility(Node *parsetree,
int aclcheck_result; int aclcheck_result;
relname = stmt->object->relname; 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) if (aclcheck_result != ACLCHECK_OK)
elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]); elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
set_ps_display(commandTag = "CREATE"); set_ps_display(commandTag = "CREATE");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -113,8 +113,8 @@ aclparse(char *s, AclItem *aip, unsigned *modechg)
Assert(s && aip && modechg); Assert(s && aip && modechg);
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
printf("aclparse: input = '%s'\n", s); elog(DEBUG, "aclparse: input = '%s'", s);
#endif #endif
aip->ai_idtype = ACL_IDTYPE_UID; aip->ai_idtype = ACL_IDTYPE_UID;
s = getid(s, name); s = getid(s, name);
...@@ -155,17 +155,26 @@ aclparse(char *s, AclItem *aip, unsigned *modechg) ...@@ -155,17 +155,26 @@ aclparse(char *s, AclItem *aip, unsigned *modechg)
{ {
switch (*s) switch (*s)
{ {
case ACL_MODE_AP_CHR: case ACL_MODE_INSERT_CHR:
aip->ai_mode |= ACL_AP; aip->ai_mode |= ACL_INSERT;
break; break;
case ACL_MODE_RD_CHR: case ACL_MODE_SELECT_CHR:
aip->ai_mode |= ACL_RD; aip->ai_mode |= ACL_SELECT;
break; break;
case ACL_MODE_WR_CHR: case ACL_MODE_UPDATE_CHR:
aip->ai_mode |= ACL_WR; aip->ai_mode |= ACL_UPDATE;
break; break;
case ACL_MODE_RU_CHR: case ACL_MODE_DELETE_CHR:
aip->ai_mode |= ACL_RU; 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; break;
default: default:
elog(ERROR, "aclparse: mode flags must use \"%s\"", elog(ERROR, "aclparse: mode flags must use \"%s\"",
...@@ -192,7 +201,7 @@ aclparse(char *s, AclItem *aip, unsigned *modechg) ...@@ -192,7 +201,7 @@ aclparse(char *s, AclItem *aip, unsigned *modechg)
break; break;
} }
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG
elog(DEBUG, "aclparse: correctly read [%x %d %x], modechg=%x", elog(DEBUG, "aclparse: correctly read [%x %d %x], modechg=%x",
aip->ai_idtype, aip->ai_id, aip->ai_mode, *modechg); aip->ai_idtype, aip->ai_id, aip->ai_mode, *modechg);
#endif #endif
...@@ -269,7 +278,7 @@ aclitemout(PG_FUNCTION_ARGS) ...@@ -269,7 +278,7 @@ aclitemout(PG_FUNCTION_ARGS)
unsigned i; unsigned i;
char *tmpname; char *tmpname;
p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN); p = out = palloc(strlen("group =" ACL_MODE_STR " ") + 1 + NAMEDATALEN);
*p = '\0'; *p = '\0';
switch (aip->ai_idtype) switch (aip->ai_idtype)
...@@ -368,14 +377,13 @@ acldefault(char *relname, AclId ownerid) ...@@ -368,14 +377,13 @@ acldefault(char *relname, AclId ownerid)
AclItem *aip; AclItem *aip;
#define ACL_WORLD_DEFAULT (ACL_NO) #define ACL_WORLD_DEFAULT (ACL_NO)
/* #define ACL_WORLD_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)
#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
acl = makeacl(2); acl = makeacl(2);
aip = ACL_DAT(acl); aip = ACL_DAT(acl);
aip[0].ai_idtype = ACL_IDTYPE_WORLD; aip[0].ai_idtype = ACL_IDTYPE_WORLD;
aip[0].ai_id = ACL_ID_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_idtype = ACL_IDTYPE_UID;
aip[1].ai_id = ownerid; aip[1].ai_id = ownerid;
aip[1].ai_mode = ACL_OWNER_DEFAULT; aip[1].ai_mode = ACL_OWNER_DEFAULT;
...@@ -651,8 +659,8 @@ aclmakepriv(char *old_privlist, char new_priv) ...@@ -651,8 +659,8 @@ aclmakepriv(char *old_privlist, char new_priv)
int i; int i;
int l; int l;
Assert(strlen(old_privlist) < 5); Assert(strlen(old_privlist) <= strlen(ACL_MODE_STR));
priv = palloc(5); /* at most "rwaR" */ ; priv = palloc(strlen(ACL_MODE_STR)+1);
if (old_privlist == NULL || old_privlist[0] == '\0') if (old_privlist == NULL || old_privlist[0] == '\0')
{ {
...@@ -665,7 +673,7 @@ aclmakepriv(char *old_privlist, char new_priv) ...@@ -665,7 +673,7 @@ aclmakepriv(char *old_privlist, char new_priv)
l = strlen(old_privlist); l = strlen(old_privlist);
if (l == 4) if (l == strlen(ACL_MODE_STR))
{ /* can't add any more privileges */ { /* can't add any more privileges */
return priv; return priv;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* For backward-compatibility purposes we have to allow there * For backward-compatibility purposes we have to allow there
...@@ -52,11 +52,14 @@ typedef uint8 AclIdType; ...@@ -52,11 +52,14 @@ typedef uint8 AclIdType;
typedef uint8 AclMode; typedef uint8 AclMode;
#define ACL_NO 0 /* no permissions */ #define ACL_NO 0 /* no permissions */
#define ACL_AP (1<<0) /* append */ #define ACL_INSERT (1<<0)
#define ACL_RD (1<<1) /* read */ #define ACL_SELECT (1<<1)
#define ACL_WR (1<<2) /* write (append/delete/replace) */ #define ACL_UPDATE (1<<2)
#define ACL_RU (1<<3) /* place rules */ #define ACL_DELETE (1<<3)
#define N_ACL_MODES 4 #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 * AclItem
...@@ -146,11 +149,14 @@ typedef ArrayType IdList; ...@@ -146,11 +149,14 @@ typedef ArrayType IdList;
#define ACL_MODECHG_ADD_CHR '+' #define ACL_MODECHG_ADD_CHR '+'
#define ACL_MODECHG_DEL_CHR '-' #define ACL_MODECHG_DEL_CHR '-'
#define ACL_MODECHG_EQL_CHR '=' #define ACL_MODECHG_EQL_CHR '='
#define ACL_MODE_STR "arwR" /* list of valid characters */ #define ACL_MODE_STR "arwdRxt" /* list of valid characters */
#define ACL_MODE_AP_CHR 'a' #define ACL_MODE_INSERT_CHR 'a' /* formerly known as "append" */
#define ACL_MODE_RD_CHR 'r' #define ACL_MODE_SELECT_CHR 'r' /* formerly known as "read" */
#define ACL_MODE_WR_CHR 'w' #define ACL_MODE_UPDATE_CHR 'w' /* formerly known as "write" */
#define ACL_MODE_RU_CHR 'R' #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 */ /* result codes for pg_aclcheck */
#define ACLCHECK_OK 0 #define ACLCHECK_OK 0
...@@ -161,11 +167,6 @@ typedef ArrayType IdList; ...@@ -161,11 +167,6 @@ typedef ArrayType IdList;
/* warning messages. set these in aclchk.c. */ /* warning messages. set these in aclchk.c. */
extern char *aclcheck_error_strings[]; extern char *aclcheck_error_strings[];
/*
* Enable ACL execution tracing and table dumps
*/
/*#define ACLDEBUG_TRACE*/
/* /*
* routines used internally * routines used internally
*/ */
......
--
-- 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;
...@@ -61,6 +61,7 @@ test: select ...@@ -61,6 +61,7 @@ test: select
ignore: random 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: 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 test: misc
# ---------- # ----------
......
#! /bin/sh #! /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` me=`basename $0`
: ${TMPDIR=/tmp} : ${TMPDIR=/tmp}
...@@ -432,6 +432,18 @@ if [ $? -ne 0 ]; then ...@@ -432,6 +432,18 @@ if [ $? -ne 0 ]; then
fi 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 # Install the PL/pgSQL language in it
# ---------- # ----------
......
# $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. # This should probably be in an order similar to parallel_schedule.
test: boolean test: boolean
test: char test: char
...@@ -68,6 +68,7 @@ test: portals ...@@ -68,6 +68,7 @@ test: portals
test: arrays test: arrays
test: btree_index test: btree_index
test: hash_index test: hash_index
test: privileges
test: misc test: misc
test: select_views test: select_views
test: alter_table test: alter_table
......
--
-- 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;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册