Commit ef742251 authored by Peter Eisentraut's avatar Peter Eisentraut

Grant options, and cascading revoke. Grant options are allowed only for

users right now, not groups.  Extension of has_foo_privileges functions to
query the grant options.  Extension of aclitem type to store grantor.
parent aa78ca3a
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.135 2003/01/23 01:22:59 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.136 2003/01/23 23:38:51 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -5786,6 +5786,12 @@ SELECT has_table_privilege('myschema.mytable', 'select'); ...@@ -5786,6 +5786,12 @@ SELECT has_table_privilege('myschema.mytable', 'select');
<literal>USAGE</literal>. <literal>USAGE</literal>.
</para> </para>
<para>
To evaluate whether a user holds a grant option on the privilege,
append <literal> WITH GRANT OPTION</literal> to the privilege key
word; for example <literal>'UPDATE WITH GRANT OPTION'</literal>.
</para>
<para> <para>
<xref linkend="functions-misc-schema-table"> shows functions that <xref linkend="functions-misc-schema-table"> shows functions that
determine whether a certain object is <firstterm>visible</> in the determine whether a certain object is <firstterm>visible</> in the
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.31 2002/11/21 23:34:43 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.32 2003/01/23 23:38:53 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -19,23 +19,23 @@ PostgreSQL documentation ...@@ -19,23 +19,23 @@ PostgreSQL documentation
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] } [,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...] ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>dbname</replaceable> [, ...] ON DATABASE <replaceable>dbname</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] } GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...] ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>langname</replaceable> [, ...] ON LANGUAGE <replaceable>langname</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schemaname</replaceable> [, ...] ON SCHEMA <replaceable>schemaname</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -63,13 +63,18 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ...@@ -63,13 +63,18 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
<para> <para>
There is no need to grant privileges to the creator of an object, There is no need to grant privileges to the creator of an object,
as the creator has all privileges by default. as the creator has all privileges by default. (The creator could,
(The creator could, however, choose to revoke however, choose to revoke some of his own privileges for safety.)
some of his own privileges for safety.) Note that the ability to Note that the right to drop an object, or to alter it in any way is
grant and revoke privileges is inherent in the creator and cannot not described by a grantable right; it is inherent in the creator,
be lost. The right to drop an object, or to alter it in any way and cannot be granted or revoked.
not described by a grantable right, is likewise inherent in the </para>
creator, and cannot be granted or revoked.
<para>
If <literal>WITH GRANT OPTION</literal> is specified, the recipient
of the privilege may in turn grant it to others. By default this
is not possible. Grant options can only be granted to individual
users, not groups or <literal>PUBLIC</literal>.
</para> </para>
<para> <para>
...@@ -269,7 +274,7 @@ lusitania=> \dp mytable ...@@ -269,7 +274,7 @@ lusitania=> \dp mytable
Access privileges for database "lusitania" Access privileges for database "lusitania"
Schema | Table | Access privileges Schema | Table | Access privileges
--------+---------+--------------------------------------- --------+---------+---------------------------------------
public | mytable | {=r,miriam=arwdRxt,"group todos=arw"} public | mytable | {=r/postgres,miriam=arwdRxt/postgres,"group todos=arw/postgres"}
(1 row) (1 row)
</programlisting> </programlisting>
The entries shown by <command>\dp</command> are interpreted thus: The entries shown by <command>\dp</command> are interpreted thus:
...@@ -290,6 +295,9 @@ lusitania=> \dp mytable ...@@ -290,6 +295,9 @@ lusitania=> \dp mytable
C -- CREATE C -- CREATE
T -- TEMPORARY T -- TEMPORARY
arwdRxt -- ALL PRIVILEGES (for tables) arwdRxt -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege
/yyyy -- user who granted this privilege
</programlisting> </programlisting>
The above example display would be seen by user <literal>miriam</> after The above example display would be seen by user <literal>miriam</> after
...@@ -346,13 +354,12 @@ GRANT ALL PRIVILEGES ON kinds TO manuel; ...@@ -346,13 +354,12 @@ GRANT ALL PRIVILEGES ON kinds TO manuel;
</para> </para>
<para> <para>
The <acronym>SQL92</acronym> syntax for GRANT allows setting The <acronym>SQL</acronym> syntax for <literal>GRANT</literal>
privileges for individual columns within a table, and allows allows setting privileges for individual columns within a table:
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">table</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>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.24 2003/01/10 11:02:51 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.25 2003/01/23 23:38:53 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -16,31 +16,36 @@ PostgreSQL documentation ...@@ -16,31 +16,36 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] } [,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...] ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] } REVOKE [ GRANT OPTION FOR ]
{ { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>dbname</replaceable> [, ...] ON DATABASE <replaceable>dbname</replaceable> [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE { EXECUTE | ALL [ PRIVILEGES ] } REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...] ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE { USAGE | ALL [ PRIVILEGES ] } REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>langname</replaceable> [, ...] ON LANGUAGE <replaceable>langname</replaceable> [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schemaname</replaceable> [, ...] ON SCHEMA <replaceable>schemaname</replaceable> [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ RESTRICT ] [ CASCADE | RESTRICT ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -70,8 +75,22 @@ REVOKE { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ...@@ -70,8 +75,22 @@ REVOKE { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
</para> </para>
<para> <para>
The <literal>RESTRICT</literal> key word is currently only noise. If <literal>GRANT OPTION FOR</literal> is specified, only the grant
See also the compatibility notes below. option for the privilege is revoked, not the privilege itself.
</para>
<para>
If a user holds a privilege with grant option and has granted it to
other users then the privileges held by those other users are
called dependent privileges. If the privilege or the grant option
held by the first user is being revoked and dependent privileges
exist, those dependent privileges are also revoked if
<literal>CASCADE</literal> is specified, else the revoke action
will fail. This recursive revocation only affects privileges that
were granted through a chain of users that is traceable to the user
that is the subject of this <literal>REVOKE</literal> command.
Thus, the affected users may effectively keep the privilege if it
was also granted through other users.
</para> </para>
</refsect1> </refsect1>
...@@ -83,6 +102,16 @@ REVOKE { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } ...@@ -83,6 +102,16 @@ REVOKE { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
display the privileges granted on existing objects. See also <xref display the privileges granted on existing objects. See also <xref
linkend="sql-grant" endterm="sql-grant-title"> for information about the format. linkend="sql-grant" endterm="sql-grant-title"> for information about the format.
</para> </para>
<para>
A user can only revoke privileges that were granted directly by
that user. If, for example, user A has granted a privilege with
grant option to user B, and user B has in turned granted it to user
C, then user A cannot revoke the privilege directly from C.
Instead, user A could revoke the grant option from user B and use
the <literal>CASCADE</literal> option so that the privilege is
automatically revoked from user C.
</para>
</refsect1> </refsect1>
<refsect1 id="SQL-REVOKE-examples"> <refsect1 id="SQL-REVOKE-examples">
...@@ -122,16 +151,8 @@ REVOKE [ GRANT OPTION FOR ] { SELECT | INSERT | UPDATE | DELETE | REFERENCES } ...@@ -122,16 +151,8 @@ REVOKE [ GRANT OPTION FOR ] { SELECT | INSERT | UPDATE | DELETE | REFERENCES }
FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] } FROM { PUBLIC | <replaceable class="parameter">username</replaceable> [, ...] }
{ RESTRICT | CASCADE } { RESTRICT | CASCADE }
</synopsis> </synopsis>
</para> One of <literal>RESTRICT</literal> or <literal>CASCADE</literal>
is required.
<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.
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 specifies the RESTRICT
keyword.
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.179 2003/01/20 18:54:44 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.180 2003/01/23 23:38:51 petere Exp $
--> -->
<appendix id="release"> <appendix id="release">
...@@ -38,6 +38,7 @@ ON COMMIT options for temp tables ...@@ -38,6 +38,7 @@ ON COMMIT options for temp tables
extra_float_digits option allows pg_dump to dump float data accurately extra_float_digits option allows pg_dump to dump float data accurately
Long options for psql and pg_dump are now available on all platforms Long options for psql and pg_dump are now available on all platforms
Read-only transactions Read-only transactions
Object owners can allow grantees to grant the privilege to others (grant option)
]]></literallayout> ]]></literallayout>
</sect1> </sect1>
......
This diff is collapsed.
...@@ -72,7 +72,7 @@ E081 Basic Privileges 04 UPDATE privilege at the table level YES ...@@ -72,7 +72,7 @@ E081 Basic Privileges 04 UPDATE privilege at the table level YES
E081 Basic Privileges 05 UPDATE privilege at the column level NO E081 Basic Privileges 05 UPDATE privilege at the column level NO
E081 Basic Privileges 06 REFERENCES privilege at the table level YES E081 Basic Privileges 06 REFERENCES privilege at the table level YES
E081 Basic Privileges 07 REFERENCES privilege at the column level NO E081 Basic Privileges 07 REFERENCES privilege at the column level NO
E081 Basic Privileges 08 WITH GRANT OPTION NO E081 Basic Privileges 08 WITH GRANT OPTION YES
E091 Set functions YES E091 Set functions YES
E091 Set functions 01 AVG YES E091 Set functions 01 AVG YES
E091 Set functions 02 COUNT YES E091 Set functions 02 COUNT YES
...@@ -133,10 +133,10 @@ F031 Basic schema manipulation 16 DROP VIEW statement: RESTRICT clause YES ...@@ -133,10 +133,10 @@ F031 Basic schema manipulation 16 DROP VIEW statement: RESTRICT clause YES
F031 Basic schema manipulation 19 REVOKE statement: RESTRICT clause YES F031 Basic schema manipulation 19 REVOKE statement: RESTRICT clause YES
F032 CASCADE drop behavior YES F032 CASCADE drop behavior YES
F033 ALTER TABLE statement: DROP COLUMN clause YES F033 ALTER TABLE statement: DROP COLUMN clause YES
F034 Extended REVOKE statement NO F034 Extended REVOKE statement YES
F034 Extended REVOKE statement 01 REVOKE statement performed by other than the owner of a schema object NO F034 Extended REVOKE statement 01 REVOKE statement performed by other than the owner of a schema object YES
F034 Extended REVOKE statement 02 REVOKE statement: GRANT OPTION FOR clause NO F034 Extended REVOKE statement 02 REVOKE statement: GRANT OPTION FOR clause YES
F034 Extended REVOKE statement 03 REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION NO F034 Extended REVOKE statement 03 REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION YES
F041 Basic joined table YES F041 Basic joined table YES
F041 Basic joined table 01 Inner join (but not necessarily the INNER keyword) YES F041 Basic joined table 01 Inner join (but not necessarily the INNER keyword) YES
F041 Basic joined table 02 INNER keyword YES F041 Basic joined table 02 INNER keyword YES
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,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/nodes/copyfuncs.c,v 1.237 2003/01/20 18:54:46 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.238 2003/01/23 23:38:56 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1563,6 +1563,8 @@ _copyGrantStmt(GrantStmt *from) ...@@ -1563,6 +1563,8 @@ _copyGrantStmt(GrantStmt *from)
COPY_NODE_FIELD(objects); COPY_NODE_FIELD(objects);
COPY_INTLIST_FIELD(privileges); COPY_INTLIST_FIELD(privileges);
COPY_NODE_FIELD(grantees); COPY_NODE_FIELD(grantees);
COPY_SCALAR_FIELD(grant_option);
COPY_SCALAR_FIELD(behavior);
return newnode; return newnode;
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,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/nodes/equalfuncs.c,v 1.181 2003/01/20 18:54:46 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.182 2003/01/23 23:38:56 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -635,6 +635,8 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b) ...@@ -635,6 +635,8 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
COMPARE_NODE_FIELD(objects); COMPARE_NODE_FIELD(objects);
COMPARE_INTLIST_FIELD(privileges); COMPARE_INTLIST_FIELD(privileges);
COMPARE_NODE_FIELD(grantees); COMPARE_NODE_FIELD(grantees);
COMPARE_SCALAR_FIELD(grant_option);
COMPARE_SCALAR_FIELD(behavior);
return true; return true;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.395 2003/01/10 22:03:27 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.396 2003/01/23 23:38:56 petere Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -163,6 +163,7 @@ static void doNegateFloat(Value *v); ...@@ -163,6 +163,7 @@ static void doNegateFloat(Value *v);
%type <ival> opt_lock lock_type cast_context %type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace transaction_access_mode %type <boolean> opt_force opt_or_replace transaction_access_mode
opt_grant_grant_option opt_revoke_grant_option
%type <list> user_list %type <list> user_list
...@@ -2737,6 +2738,7 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list ...@@ -2737,6 +2738,7 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list
n->objtype = ($4)->objtype; n->objtype = ($4)->objtype;
n->objects = ($4)->objs; n->objects = ($4)->objs;
n->grantees = $6; n->grantees = $6;
n->grant_option = $7;
$$ = (Node*)n; $$ = (Node*)n;
} }
; ;
...@@ -2750,9 +2752,8 @@ RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target ...@@ -2750,9 +2752,8 @@ RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target
n->objtype = ($5)->objtype; n->objtype = ($5)->objtype;
n->objects = ($5)->objs; n->objects = ($5)->objs;
n->grantees = $7; n->grantees = $7;
n->grant_option = $2;
if ($8 == DROP_CASCADE) n->behavior = $8;
elog(ERROR, "REVOKE ... CASCADE is not implemented");
$$ = (Node *)n; $$ = (Node *)n;
} }
...@@ -2867,19 +2868,13 @@ grantee: ColId ...@@ -2867,19 +2868,13 @@ grantee: ColId
opt_grant_grant_option: opt_grant_grant_option:
WITH GRANT OPTION WITH GRANT OPTION { $$ = TRUE; }
{ | /*EMPTY*/ { $$ = FALSE; }
elog(ERROR, "grant options are not implemented");
}
| /*EMPTY*/
; ;
opt_revoke_grant_option: opt_revoke_grant_option:
GRANT OPTION FOR GRANT OPTION FOR { $$ = TRUE; }
{ | /*EMPTY*/ { $$ = FALSE; }
elog(ERROR, "grant options are not implemented");
}
| /*EMPTY*/
; ;
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.181 2003/01/21 10:11:52 petere Exp $ # $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.182 2003/01/23 23:39:01 petere Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -1029,14 +1029,12 @@ echo "ok" ...@@ -1029,14 +1029,12 @@ echo "ok"
$ECHO_N "setting privileges on built-in objects... "$ECHO_C $ECHO_N "setting privileges on built-in objects... "$ECHO_C
( (
cat <<EOF cat <<EOF
UPDATE pg_class SET relacl = '{"=r"}' \ UPDATE pg_class SET relacl = '{"=r/$POSTGRES_SUPERUSERNAME"}' \
WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL; WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL;
UPDATE pg_proc SET proacl = '{"=X"}' \ UPDATE pg_proc SET proacl = '{"=X/$POSTGRES_SUPERUSERNAME"}' \
WHERE proacl IS NULL; WHERE proacl IS NULL;
UPDATE pg_language SET lanacl = '{"=U"}' \ UPDATE pg_language SET lanacl = '{"=U/$POSTGRES_SUPERUSERNAME"}' \
WHERE lanpltrusted; WHERE lanpltrusted;
UPDATE pg_language SET lanacl = '{"="}' \
WHERE NOT lanpltrusted;
EOF EOF
) \ ) \
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely | "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
......
This diff is collapsed.
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* catversion.h * catversion.h
* "Catalog version number" for Postgres. * "Catalog version number" for PostgreSQL.
* *
* The catalog version number is used to flag incompatible changes in * The catalog version number is used to flag incompatible changes in
* the Postgres system catalogs. Whenever anyone changes the format of * the PostgreSQL system catalogs. Whenever anyone changes the format of
* a system catalog relation, or adds, deletes, or modifies standard * a system catalog relation, or adds, deletes, or modifies standard
* catalog entries in such a way that an updated backend wouldn't work * catalog entries in such a way that an updated backend wouldn't work
* with an old database (or vice versa), the catalog version number * with an old database (or vice versa), the catalog version number
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, 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: catversion.h,v 1.172 2003/01/10 21:08:15 tgl Exp $ * $Id: catversion.h,v 1.173 2003/01/23 23:39:04 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200301101 #define CATALOG_VERSION_NO 200301241
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, 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: pg_type.h,v 1.138 2003/01/08 21:40:39 tgl Exp $ * $Id: pg_type.h,v 1.139 2003/01/23 23:39:06 petere Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -412,7 +412,7 @@ DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in arr ...@@ -412,7 +412,7 @@ DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b t \054 0 702 array_in arr
DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1024 ( _reltime PGNSP PGUID -1 f b t \054 0 703 array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out d x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 8 f b t \054 0 0 aclitemin aclitemout i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b t \054 0 0 aclitemin aclitemout i p f 0 -1 0 _null_ _null_ ));
DESCR("access control list"); DESCR("access control list");
#define ACLITEMOID 1033 #define ACLITEMOID 1033
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out i x f 0 -1 0 _null_ _null_ ));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, 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: parsenodes.h,v 1.226 2003/01/20 18:55:00 tgl Exp $ * $Id: parsenodes.h,v 1.227 2003/01/23 23:39:07 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -750,7 +750,7 @@ typedef enum GrantObjectType ...@@ -750,7 +750,7 @@ typedef enum GrantObjectType
/* /*
* Grantable rights are encoded so that we can OR them together in a bitmask. * Grantable rights are encoded so that we can OR them together in a bitmask.
* The present representation of AclItem limits us to 30 distinct rights. * The present representation of AclItem limits us to 15 distinct rights.
* Caution: changing these codes breaks stored ACLs, hence forces initdb. * Caution: changing these codes breaks stored ACLs, hence forces initdb.
*/ */
#define ACL_INSERT (1<<0) /* for relations */ #define ACL_INSERT (1<<0) /* for relations */
...@@ -778,6 +778,8 @@ typedef struct GrantStmt ...@@ -778,6 +778,8 @@ typedef struct GrantStmt
* strings) */ * strings) */
List *privileges; /* integer list of privilege codes */ List *privileges; /* integer list of privilege codes */
List *grantees; /* list of PrivGrantee nodes */ List *grantees; /* list of PrivGrantee nodes */
bool grant_option; /* grant or revoke grant option */
DropBehavior behavior; /* drop behavior (for REVOKE) */
} GrantStmt; } GrantStmt;
typedef struct PrivGrantee typedef struct PrivGrantee
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, 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.50 2003/01/09 18:00:24 tgl Exp $ * $Id: acl.h,v 1.51 2003/01/23 23:39:07 petere Exp $
* *
* NOTES * NOTES
* For backward-compatibility purposes we have to allow there * For backward-compatibility purposes we have to allow there
...@@ -50,27 +50,37 @@ typedef uint32 AclMode; ...@@ -50,27 +50,37 @@ typedef uint32 AclMode;
*/ */
typedef struct AclItem typedef struct AclItem
{ {
AclId ai_id; /* ID that this item applies to */ AclId ai_grantee; /* ID that this item applies to */
AclId ai_grantor;
AclMode ai_privs; /* AclIdType plus privilege bits */ AclMode ai_privs; /* AclIdType plus privilege bits */
} AclItem; } AclItem;
/* /*
* The AclIdType is stored in the top two bits of the ai_privs field of an * The AclIdType is stored in the top two bits of the ai_privs field
* AclItem, leaving us with thirty usable privilege bits. * of an AclItem. The middle 15 bits are the grant option markers,
* and the lower 15 bits are the actual privileges.
*/ */
#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0x3FFFFFFF) #define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0x7FFF)
#define ACLITEM_GET_IDTYPE(item) ((item).ai_privs >> 30) #define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 15) & 0x7FFF)
#define ACLITEM_SET_PRIVS_IDTYPE(item,privs,idtype) \ #define ACLITEM_GET_IDTYPE(item) ((item).ai_privs >> 30)
((item).ai_privs = ((privs) & 0x3FFFFFFF) | ((idtype) << 30))
#define ACL_GRANT_OPTION_FOR(privs) (((privs) & 0x7FFF) << 15)
#define ACLITEM_SET_PRIVS(item,privs) \
((item).ai_privs = (ACLITEM_GET_IDTYPE(item)<<30) | (ACLITEM_GET_GOPTIONS(item)<<15) | ((privs) & 0x7FFF))
#define ACLITEM_SET_GOPTIONS(item,goptions) \
((item).ai_privs = (ACLITEM_GET_IDTYPE(item)<<30) | (((goptions) & 0x7FFF) << 15) | ACLITEM_GET_PRIVS(item))
#define ACLITEM_SET_PRIVS_IDTYPE(item,privs,goption,idtype) \
((item).ai_privs = ((privs) & 0x7FFF) |(((goption) & 0x7FFF) << 15) | ((idtype) << 30))
/* /*
* Definitions for convenient access to Acl (array of AclItem) and IdList * Definitions for convenient access to Acl (array of AclItem) and IdList
* (array of AclId). These are standard Postgres arrays, but are restricted * (array of AclId). These are standard PostgreSQL arrays, but are restricted
* to have one dimension. We also ignore the lower bound when reading, * to have one dimension. We also ignore the lower bound when reading,
* and set it to zero when writing. * and set it to zero when writing.
* *
* CAUTION: as of Postgres 7.1, these arrays are toastable (just like all * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
* other array types). Therefore, be careful to detoast them with the * other array types). Therefore, be careful to detoast them with the
* macros provided, unless you know for certain that a particular array * macros provided, unless you know for certain that a particular array
* can't have been toasted. Presently, we do not provide toast tables for * can't have been toasted. Presently, we do not provide toast tables for
...@@ -80,7 +90,7 @@ typedef struct AclItem ...@@ -80,7 +90,7 @@ typedef struct AclItem
/* /*
* Acl a one-dimensional POSTGRES array of AclItem * Acl a one-dimensional array of AclItem
*/ */
typedef ArrayType Acl; typedef ArrayType Acl;
...@@ -90,7 +100,7 @@ typedef ArrayType Acl; ...@@ -90,7 +100,7 @@ typedef ArrayType Acl;
#define ACL_SIZE(ACL) ARR_SIZE(ACL) #define ACL_SIZE(ACL) ARR_SIZE(ACL)
/* /*
* IdList a one-dimensional POSTGRES array of AclId * IdList a one-dimensional array of AclId
*/ */
typedef ArrayType IdList; typedef ArrayType IdList;
...@@ -126,11 +136,6 @@ typedef ArrayType IdList; ...@@ -126,11 +136,6 @@ typedef ArrayType IdList;
#define ACL_MODECHG_DEL 2 #define ACL_MODECHG_DEL 2
#define ACL_MODECHG_EQL 3 #define ACL_MODECHG_EQL 3
/* external representation of mode indicators for I/O */
#define ACL_MODECHG_ADD_CHR '+'
#define ACL_MODECHG_DEL_CHR '-'
#define ACL_MODECHG_EQL_CHR '='
/* /*
* External representations of the privilege bits --- aclitemin/aclitemout * External representations of the privilege bits --- aclitemin/aclitemout
* represent each possible privilege bit with a distinct 1-character code * represent each possible privilege bit with a distinct 1-character code
...@@ -173,7 +178,7 @@ typedef enum ...@@ -173,7 +178,7 @@ typedef enum
*/ */
extern Acl *acldefault(GrantObjectType objtype, AclId ownerid); extern Acl *acldefault(GrantObjectType objtype, AclId ownerid);
extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip, extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip,
unsigned modechg); unsigned modechg, DropBehavior behavior);
/* /*
* SQL functions (from acl.c) * SQL functions (from acl.c)
......
...@@ -90,7 +90,7 @@ ERROR: atest2: permission denied ...@@ -90,7 +90,7 @@ ERROR: atest2: permission denied
COPY atest2 FROM stdin; -- fail COPY atest2 FROM stdin; -- fail
ERROR: atest2: permission denied ERROR: atest2: permission denied
GRANT ALL ON atest1 TO PUBLIC; -- fail GRANT ALL ON atest1 TO PUBLIC; -- fail
ERROR: atest1: must be owner ERROR: atest1: permission denied
-- checks in subquery, both ok -- checks in subquery, both ok
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
a | b a | b
...@@ -227,7 +227,7 @@ GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail ...@@ -227,7 +227,7 @@ GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
ERROR: language "c" is not trusted ERROR: language "c" is not trusted
SET SESSION AUTHORIZATION regressuser1; SET SESSION AUTHORIZATION regressuser1;
GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
ERROR: permission denied ERROR: sql: permission denied
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql; CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC; REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
...@@ -544,6 +544,46 @@ from (select oid from pg_class where relname = 'atest1') as t1; ...@@ -544,6 +544,46 @@ from (select oid from pg_class where relname = 'atest1') as t1;
f f
(1 row) (1 row)
-- Grant options
SET SESSION AUTHORIZATION regressuser1;
CREATE TABLE atest4 (a int);
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2;
GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail
ERROR: grant options can only be granted to individual users
SET SESSION AUTHORIZATION regressuser2;
GRANT SELECT ON atest4 TO regressuser3;
GRANT UPDATE ON atest4 TO regressuser3; -- fail
ERROR: atest4: permission denied
SET SESSION AUTHORIZATION regressuser1;
REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
has_table_privilege
---------------------
t
(1 row)
REVOKE SELECT ON atest4 FROM regressuser2; -- fail
ERROR: dependent privileges exist (use CASCADE to revoke them too)
REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regressuser2 CASCADE; -- ok
SELECT has_table_privilege('regressuser2', 'atest4', 'SELECT'); -- true
has_table_privilege
---------------------
t
(1 row)
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- false
has_table_privilege
---------------------
f
(1 row)
SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
has_table_privilege
---------------------
t
(1 row)
-- clean up -- clean up
\c regression \c regression
SET autocommit TO 'on'; SET autocommit TO 'on';
...@@ -561,6 +601,7 @@ ERROR: view "atestv4" does not exist ...@@ -561,6 +601,7 @@ ERROR: view "atestv4" does not exist
DROP TABLE atest1; DROP TABLE atest1;
DROP TABLE atest2; DROP TABLE atest2;
DROP TABLE atest3; DROP TABLE atest3;
DROP TABLE atest4;
DROP GROUP regressgroup1; DROP GROUP regressgroup1;
DROP GROUP regressgroup2; DROP GROUP regressgroup2;
DROP USER regressuser1; DROP USER regressuser1;
......
...@@ -293,6 +293,33 @@ select has_table_privilege(t1.oid,'trigger') ...@@ -293,6 +293,33 @@ select has_table_privilege(t1.oid,'trigger')
from (select oid from pg_class where relname = 'atest1') as t1; from (select oid from pg_class where relname = 'atest1') as t1;
-- Grant options
SET SESSION AUTHORIZATION regressuser1;
CREATE TABLE atest4 (a int);
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2;
GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail
SET SESSION AUTHORIZATION regressuser2;
GRANT SELECT ON atest4 TO regressuser3;
GRANT UPDATE ON atest4 TO regressuser3; -- fail
SET SESSION AUTHORIZATION regressuser1;
REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
REVOKE SELECT ON atest4 FROM regressuser2; -- fail
REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regressuser2 CASCADE; -- ok
SELECT has_table_privilege('regressuser2', 'atest4', 'SELECT'); -- true
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- false
SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
-- clean up -- clean up
\c regression \c regression
...@@ -311,6 +338,7 @@ DROP VIEW atestv4; ...@@ -311,6 +338,7 @@ DROP VIEW atestv4;
DROP TABLE atest1; DROP TABLE atest1;
DROP TABLE atest2; DROP TABLE atest2;
DROP TABLE atest3; DROP TABLE atest3;
DROP TABLE atest4;
DROP GROUP regressgroup1; DROP GROUP regressgroup1;
DROP GROUP regressgroup2; DROP GROUP regressgroup2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment