Make UPDATE and DELETE privileges distinct. Add REFERENCES and TRIGGER

privileges.  INSERT and COPY FROM now require INSERT (only).  Add
privileges regression test.
This commit is contained in:
Peter Eisentraut 2001-05-27 09:59:30 +00:00
parent 52350c7ad9
commit 96147a6d1c
26 changed files with 725 additions and 827 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>
<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>
<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.
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>
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.
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>
<refsect2 id="R2-SQL-GRANT-3">
<refsect2info>
<date>1998-09-23</date>
</refsect2info>
<title>
Notes
</title>
<para>
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>
<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>
<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:
<refsect2>
<title>SQL92</title>
<synopsis>
<para>
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>
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>
Fields are compatible with those in the <acronym>Postgres</acronym>
implementation, with the following additions:
<acronym>SQL</acronym> allows to grant the USAGE privilege on
other kinds of objects: CHARACTER SET, COLLATION, TRANSLATION, DOMAIN.
</para>
<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>
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

View File

@ -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>

View File

@ -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>

View File

@ -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>
<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:
<programlisting>
INSERT INTO pg_group VALUES ('todos');
CREATE USER miriam IN GROUP todos;
</programlisting>
</para>
</tip>
</refsect2>
<para>
See the description of the <xref linkend="sql-grant"> command for
the meaning of the privilege types.
</para>
</refsect1>
<refsect1 id="R1-SQL-REVOKE-2">
<title>
Usage
</title>
<refsect1 id="SQL-REVOKE-notes">
<title>Notes</title>
<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="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:
The compatibility notes of the <xref linkend="sql-grant"> command
apply analogously to <command>REVOKE</command>. The syntax summary is:
<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>
<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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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");

View File

@ -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'",

View File

@ -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;
/*

View File

@ -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);

View File

@ -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

View File

@ -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",

View File

@ -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,'-');
}
;

View File

@ -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");

View File

@ -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;
}

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: acl.h,v 1.31 2001/03/22 04:01:10 momjian Exp $
* $Id: acl.h,v 1.32 2001/05/27 09:59:30 petere Exp $
*
* NOTES
* For backward-compatibility purposes we have to allow there
@ -52,11 +52,14 @@ typedef uint8 AclIdType;
typedef uint8 AclMode;
#define ACL_NO 0 /* no permissions */
#define ACL_AP (1<<0) /* append */
#define ACL_RD (1<<1) /* read */
#define ACL_WR (1<<2) /* write (append/delete/replace) */
#define ACL_RU (1<<3) /* place rules */
#define N_ACL_MODES 4
#define ACL_INSERT (1<<0)
#define ACL_SELECT (1<<1)
#define ACL_UPDATE (1<<2)
#define ACL_DELETE (1<<3)
#define ACL_RULE (1<<4)
#define ACL_REFERENCES (1<<5)
#define ACL_TRIGGER (1<<6)
#define N_ACL_MODES 7 /* 1 plus the last 1<<x */
/*
* AclItem
@ -146,11 +149,14 @@ typedef ArrayType IdList;
#define ACL_MODECHG_ADD_CHR '+'
#define ACL_MODECHG_DEL_CHR '-'
#define ACL_MODECHG_EQL_CHR '='
#define ACL_MODE_STR "arwR" /* list of valid characters */
#define ACL_MODE_AP_CHR 'a'
#define ACL_MODE_RD_CHR 'r'
#define ACL_MODE_WR_CHR 'w'
#define ACL_MODE_RU_CHR 'R'
#define ACL_MODE_STR "arwdRxt" /* list of valid characters */
#define ACL_MODE_INSERT_CHR 'a' /* formerly known as "append" */
#define ACL_MODE_SELECT_CHR 'r' /* formerly known as "read" */
#define ACL_MODE_UPDATE_CHR 'w' /* formerly known as "write" */
#define ACL_MODE_DELETE_CHR 'd'
#define ACL_MODE_RULE_CHR 'R'
#define ACL_MODE_REFERENCES_CHR 'x'
#define ACL_MODE_TRIGGER_CHR 't'
/* result codes for pg_aclcheck */
#define ACLCHECK_OK 0
@ -161,11 +167,6 @@ typedef ArrayType IdList;
/* warning messages. set these in aclchk.c. */
extern char *aclcheck_error_strings[];
/*
* Enable ACL execution tracing and table dumps
*/
/*#define ACLDEBUG_TRACE*/
/*
* routines used internally
*/

View File

@ -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;

View File

@ -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
# ----------

View File

@ -1,5 +1,5 @@
#! /bin/sh
# $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.20 2001/03/24 23:32:25 petere Exp $
# $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.21 2001/05/27 09:59:30 petere Exp $
me=`basename $0`
: ${TMPDIR=/tmp}
@ -432,6 +432,18 @@ if [ $? -ne 0 ]; then
fi
# ----------
# Remove regressuser* and regressgroup* user accounts.
# ----------
message "dropping regression test user accounts"
"$bindir/psql" $psql_options -c 'drop group regressgroup1; drop group regressgroup2; drop user regressuser1, regressuser2, regressuser3, regressuser4;' $dbname 2>/dev/null
if [ $? -eq 2 ]; then
echo "$me: could not drop user accounts"
(exit 2); exit
fi
# ----------
# Install the PL/pgSQL language in it
# ----------

View File

@ -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

View File

@ -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;