Create a separate grantable privilege for TRUNCATE, rather than having it be
always owner-only. The TRUNCATE privilege works identically to the DELETE privilege so far as interactions with the rest of the system go. Robert Haas
This commit is contained in:
parent
a26c7e3d71
commit
a0b76dc662
|
@ -1,4 +1,4 @@
|
||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.82 2008/05/09 23:32:03 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.83 2008/09/08 00:47:40 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="ddl">
|
<chapter id="ddl">
|
||||||
<title>Data Definition</title>
|
<title>Data Definition</title>
|
||||||
|
@ -1356,7 +1356,7 @@ ALTER TABLE products RENAME TO items;
|
||||||
<para>
|
<para>
|
||||||
There are several different privileges: <literal>SELECT</>,
|
There are several different privileges: <literal>SELECT</>,
|
||||||
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
|
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
|
||||||
<literal>REFERENCES</>, <literal>TRIGGER</>,
|
<literal>TRUNCATE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
|
||||||
<literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
|
<literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
|
||||||
<literal>EXECUTE</>, and <literal>USAGE</>.
|
<literal>EXECUTE</>, and <literal>USAGE</>.
|
||||||
The privileges applicable to a particular
|
The privileges applicable to a particular
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.445 2008/09/07 01:29:36 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.446 2008/09/08 00:47:40 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="functions">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<title>Functions and Operators</title>
|
||||||
|
@ -11369,7 +11369,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
|
||||||
The desired access privilege type
|
The desired access privilege type
|
||||||
is specified by a text string, which must evaluate to one of the
|
is specified by a text string, which must evaluate to one of the
|
||||||
values <literal>SELECT</literal>, <literal>INSERT</literal>,
|
values <literal>SELECT</literal>, <literal>INSERT</literal>,
|
||||||
<literal>UPDATE</literal>, <literal>DELETE</literal>,
|
<literal>UPDATE</literal>, <literal>DELETE</literal>, <literal>TRUNCATE</>,
|
||||||
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
|
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
|
||||||
(Case of the string is not significant, however.)
|
(Case of the string is not significant, however.)
|
||||||
An example is:
|
An example is:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.33 2007/02/20 23:14:19 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.34 2008/09/08 00:47:40 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="information-schema">
|
<chapter id="information-schema">
|
||||||
<title>The Information Schema</title>
|
<title>The Information Schema</title>
|
||||||
|
@ -2820,9 +2820,9 @@ ORDER BY c.ordinal_position;
|
||||||
<entry><type>character_data</type></entry>
|
<entry><type>character_data</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Type of the privilege: <literal>SELECT</literal>,
|
Type of the privilege: <literal>SELECT</literal>,
|
||||||
<literal>DELETE</literal>, <literal>INSERT</literal>,
|
<literal>INSERT</literal>, <literal>UPDATE</literal>,
|
||||||
<literal>UPDATE</literal>, <literal>REFERENCES</literal>,
|
<literal>DELETE</literal>, <literal>TRUNCATE</literal>,
|
||||||
or <literal>TRIGGER</literal>
|
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -4406,9 +4406,9 @@ ORDER BY c.ordinal_position;
|
||||||
<entry><type>character_data</type></entry>
|
<entry><type>character_data</type></entry>
|
||||||
<entry>
|
<entry>
|
||||||
Type of the privilege: <literal>SELECT</literal>,
|
Type of the privilege: <literal>SELECT</literal>,
|
||||||
<literal>DELETE</literal>, <literal>INSERT</literal>,
|
<literal>INSERT</literal>, <literal>UPDATE</literal>,
|
||||||
<literal>UPDATE</literal>, <literal>REFERENCES</literal>,
|
<literal>DELETE</literal>, <literal>TRUNCATE</literal>,
|
||||||
or <literal>TRIGGER</literal>
|
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.70 2008/07/03 15:59:55 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.71 2008/09/08 00:47:40 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ PostgreSQL documentation
|
||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
GRANT { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }
|
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
|
||||||
[,...] | ALL [ PRIVILEGES ] }
|
[,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
||||||
TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
||||||
|
@ -192,6 +192,16 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>TRUNCATE</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows <xref linkend="sql-truncate" endterm="sql-truncate-title"> on
|
||||||
|
the specified table.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>REFERENCES</term>
|
<term>REFERENCES</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -421,8 +431,8 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
|
||||||
=> \z mytable
|
=> \z mytable
|
||||||
Access privileges
|
Access privileges
|
||||||
Schema | Name | Type | Access privileges
|
Schema | Name | Type | Access privileges
|
||||||
--------+---------+-------+----------------------
|
--------+---------+-------+-----------------------
|
||||||
public | mytable | table | miriam=arwdxt/miriam
|
public | mytable | table | miriam=arwdDxt/miriam
|
||||||
: =r/miriam
|
: =r/miriam
|
||||||
: admin=arw/miriam
|
: admin=arw/miriam
|
||||||
(1 row)
|
(1 row)
|
||||||
|
@ -436,6 +446,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
|
||||||
w -- UPDATE ("write")
|
w -- UPDATE ("write")
|
||||||
a -- INSERT ("append")
|
a -- INSERT ("append")
|
||||||
d -- DELETE
|
d -- DELETE
|
||||||
|
D -- TRUNCATE
|
||||||
x -- REFERENCES
|
x -- REFERENCES
|
||||||
t -- TRIGGER
|
t -- TRIGGER
|
||||||
X -- EXECUTE
|
X -- EXECUTE
|
||||||
|
@ -443,7 +454,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
|
||||||
C -- CREATE
|
C -- CREATE
|
||||||
c -- CONNECT
|
c -- CONNECT
|
||||||
T -- TEMPORARY
|
T -- TEMPORARY
|
||||||
arwdxt -- ALL PRIVILEGES (for tables)
|
arwdDxt -- ALL PRIVILEGES (for tables)
|
||||||
* -- grant option for preceding privilege
|
* -- grant option for preceding privilege
|
||||||
|
|
||||||
/yyyy -- role that granted this privilege
|
/yyyy -- role that granted this privilege
|
||||||
|
@ -466,7 +477,7 @@ GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
|
||||||
object type, as explained above. The first <command>GRANT</> or
|
object type, as explained above. The first <command>GRANT</> or
|
||||||
<command>REVOKE</> on an object
|
<command>REVOKE</> on an object
|
||||||
will instantiate the default privileges (producing, for example,
|
will instantiate the default privileges (producing, for example,
|
||||||
<literal>{miriam=arwdxt/miriam}</>) and then modify them per the
|
<literal>{miriam=arwdDxt/miriam}</>) and then modify them per the
|
||||||
specified request.
|
specified request.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -524,7 +535,8 @@ GRANT admins TO joe;
|
||||||
<para>
|
<para>
|
||||||
<productname>PostgreSQL</productname> allows an object owner to revoke his
|
<productname>PostgreSQL</productname> allows an object owner to revoke his
|
||||||
own ordinary privileges: for example, a table owner can make the table
|
own ordinary privileges: for example, a table owner can make the table
|
||||||
read-only to himself by revoking his own INSERT, UPDATE, and DELETE
|
read-only to himself by revoking his own <literal>INSERT</>,
|
||||||
|
<literal>UPDATE</>, <literal>DELETE</>, and <literal>TRUNCATE</>
|
||||||
privileges. This is not possible according to the SQL standard. The
|
privileges. This is not possible according to the SQL standard. The
|
||||||
reason is that <productname>PostgreSQL</productname> treats the owner's
|
reason is that <productname>PostgreSQL</productname> treats the owner's
|
||||||
privileges as having been granted by the owner to himself; therefore he
|
privileges as having been granted by the owner to himself; therefore he
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.48 2006/09/16 00:30:19 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.49 2008/09/08 00:47:40 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -155,7 +155,8 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
|
||||||
<para>
|
<para>
|
||||||
<literal>LOCK TABLE ... IN ACCESS SHARE MODE</> requires <literal>SELECT</>
|
<literal>LOCK TABLE ... IN ACCESS SHARE MODE</> requires <literal>SELECT</>
|
||||||
privileges on the target table. All other forms of <command>LOCK</>
|
privileges on the target table. All other forms of <command>LOCK</>
|
||||||
require <literal>UPDATE</> and/or <literal>DELETE</> privileges.
|
require at least one of <literal>UPDATE</>, <literal>DELETE</>, or
|
||||||
|
<literal>TRUNCATE</> privileges.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.47 2008/03/03 19:17:27 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.48 2008/09/08 00:47:40 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ PostgreSQL documentation
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
REVOKE [ GRANT OPTION FOR ]
|
REVOKE [ GRANT OPTION FOR ]
|
||||||
{ { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }
|
{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
|
||||||
[,...] | ALL [ PRIVILEGES ] }
|
[,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
||||||
FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...]
|
FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/truncate.sgml,v 1.27 2008/05/17 23:36:27 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/truncate.sgml,v 1.28 2008/09/08 00:47:40 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -97,7 +97,8 @@ TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ... ]
|
||||||
<title>Notes</title>
|
<title>Notes</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Only the owner of a table can <command>TRUNCATE</> it.
|
You must have the <literal>TRUNCATE</literal> privilege on a table
|
||||||
|
to truncate it.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.39 2007/02/01 00:28:18 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.40 2008/09/08 00:47:40 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="user-manag">
|
<chapter id="user-manag">
|
||||||
<title>Database Roles and Privileges</title>
|
<title>Database Roles and Privileges</title>
|
||||||
|
@ -293,7 +293,7 @@ ALTER ROLE myname SET enable_indexscan TO off;
|
||||||
granted.
|
granted.
|
||||||
There are several different kinds of privilege: <literal>SELECT</>,
|
There are several different kinds of privilege: <literal>SELECT</>,
|
||||||
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
|
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
|
||||||
<literal>REFERENCES</>, <literal>TRIGGER</>,
|
<literal>TRUNCATE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
|
||||||
<literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
|
<literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
|
||||||
<literal>EXECUTE</>, and <literal>USAGE</>.
|
<literal>EXECUTE</>, and <literal>USAGE</>.
|
||||||
For more information on the different types of privileges supported by
|
For more information on the different types of privileges supported by
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.147 2008/06/19 00:46:03 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.148 2008/09/08 00:47:40 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
|
@ -1331,6 +1331,8 @@ string_to_privilege(const char *privname)
|
||||||
return ACL_UPDATE;
|
return ACL_UPDATE;
|
||||||
if (strcmp(privname, "delete") == 0)
|
if (strcmp(privname, "delete") == 0)
|
||||||
return ACL_DELETE;
|
return ACL_DELETE;
|
||||||
|
if (strcmp(privname, "truncate") == 0)
|
||||||
|
return ACL_TRUNCATE;
|
||||||
if (strcmp(privname, "references") == 0)
|
if (strcmp(privname, "references") == 0)
|
||||||
return ACL_REFERENCES;
|
return ACL_REFERENCES;
|
||||||
if (strcmp(privname, "trigger") == 0)
|
if (strcmp(privname, "trigger") == 0)
|
||||||
|
@ -1368,6 +1370,8 @@ privilege_to_string(AclMode privilege)
|
||||||
return "UPDATE";
|
return "UPDATE";
|
||||||
case ACL_DELETE:
|
case ACL_DELETE:
|
||||||
return "DELETE";
|
return "DELETE";
|
||||||
|
case ACL_TRUNCATE:
|
||||||
|
return "TRUNCATE";
|
||||||
case ACL_REFERENCES:
|
case ACL_REFERENCES:
|
||||||
return "REFERENCES";
|
return "REFERENCES";
|
||||||
case ACL_TRIGGER:
|
case ACL_TRIGGER:
|
||||||
|
@ -1582,7 +1586,7 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
||||||
* protected in this way. Assume the view rules can take care of
|
* protected in this way. Assume the view rules can take care of
|
||||||
* themselves. ACL_USAGE is if we ever have system sequences.
|
* themselves. ACL_USAGE is if we ever have system sequences.
|
||||||
*/
|
*/
|
||||||
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE)) &&
|
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
|
||||||
IsSystemClass(classForm) &&
|
IsSystemClass(classForm) &&
|
||||||
classForm->relkind != RELKIND_VIEW &&
|
classForm->relkind != RELKIND_VIEW &&
|
||||||
!has_rolcatupdate(roleid) &&
|
!has_rolcatupdate(roleid) &&
|
||||||
|
@ -1591,7 +1595,7 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
||||||
#ifdef ACLDEBUG
|
#ifdef ACLDEBUG
|
||||||
elog(DEBUG2, "permission denied for system catalog update");
|
elog(DEBUG2, "permission denied for system catalog update");
|
||||||
#endif
|
#endif
|
||||||
mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE);
|
mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2008, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2008, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.45 2008/07/18 03:32:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.46 2008/09/08 00:47:40 tgl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1214,9 +1214,10 @@ CREATE VIEW role_table_grants AS
|
||||||
pg_authid u_grantor,
|
pg_authid u_grantor,
|
||||||
pg_authid g_grantee,
|
pg_authid g_grantee,
|
||||||
(SELECT 'SELECT' UNION ALL
|
(SELECT 'SELECT' UNION ALL
|
||||||
SELECT 'DELETE' UNION ALL
|
|
||||||
SELECT 'INSERT' UNION ALL
|
SELECT 'INSERT' UNION ALL
|
||||||
SELECT 'UPDATE' UNION ALL
|
SELECT 'UPDATE' UNION ALL
|
||||||
|
SELECT 'DELETE' UNION ALL
|
||||||
|
SELECT 'TRUNCATE' UNION ALL
|
||||||
SELECT 'REFERENCES' UNION ALL
|
SELECT 'REFERENCES' UNION ALL
|
||||||
SELECT 'TRIGGER') AS pr (type)
|
SELECT 'TRIGGER') AS pr (type)
|
||||||
|
|
||||||
|
@ -1728,6 +1729,7 @@ CREATE VIEW table_constraints AS
|
||||||
OR has_table_privilege(r.oid, 'INSERT')
|
OR has_table_privilege(r.oid, 'INSERT')
|
||||||
OR has_table_privilege(r.oid, 'UPDATE')
|
OR has_table_privilege(r.oid, 'UPDATE')
|
||||||
OR has_table_privilege(r.oid, 'DELETE')
|
OR has_table_privilege(r.oid, 'DELETE')
|
||||||
|
OR has_table_privilege(r.oid, 'TRUNCATE')
|
||||||
OR has_table_privilege(r.oid, 'REFERENCES')
|
OR has_table_privilege(r.oid, 'REFERENCES')
|
||||||
OR has_table_privilege(r.oid, 'TRIGGER') )
|
OR has_table_privilege(r.oid, 'TRIGGER') )
|
||||||
|
|
||||||
|
@ -1761,6 +1763,7 @@ CREATE VIEW table_constraints AS
|
||||||
OR has_table_privilege(r.oid, 'INSERT')
|
OR has_table_privilege(r.oid, 'INSERT')
|
||||||
OR has_table_privilege(r.oid, 'UPDATE')
|
OR has_table_privilege(r.oid, 'UPDATE')
|
||||||
OR has_table_privilege(r.oid, 'DELETE')
|
OR has_table_privilege(r.oid, 'DELETE')
|
||||||
|
OR has_table_privilege(r.oid, 'TRUNCATE')
|
||||||
OR has_table_privilege(r.oid, 'REFERENCES')
|
OR has_table_privilege(r.oid, 'REFERENCES')
|
||||||
OR has_table_privilege(r.oid, 'TRIGGER') );
|
OR has_table_privilege(r.oid, 'TRIGGER') );
|
||||||
|
|
||||||
|
@ -1802,9 +1805,10 @@ CREATE VIEW table_privileges AS
|
||||||
SELECT 0::oid, 'PUBLIC'
|
SELECT 0::oid, 'PUBLIC'
|
||||||
) AS grantee (oid, rolname),
|
) AS grantee (oid, rolname),
|
||||||
(SELECT 'SELECT' UNION ALL
|
(SELECT 'SELECT' UNION ALL
|
||||||
SELECT 'DELETE' UNION ALL
|
|
||||||
SELECT 'INSERT' UNION ALL
|
SELECT 'INSERT' UNION ALL
|
||||||
SELECT 'UPDATE' UNION ALL
|
SELECT 'UPDATE' UNION ALL
|
||||||
|
SELECT 'DELETE' UNION ALL
|
||||||
|
SELECT 'TRUNCATE' UNION ALL
|
||||||
SELECT 'REFERENCES' UNION ALL
|
SELECT 'REFERENCES' UNION ALL
|
||||||
SELECT 'TRIGGER') AS pr (type)
|
SELECT 'TRIGGER') AS pr (type)
|
||||||
|
|
||||||
|
@ -1861,6 +1865,7 @@ CREATE VIEW tables AS
|
||||||
OR has_table_privilege(c.oid, 'INSERT')
|
OR has_table_privilege(c.oid, 'INSERT')
|
||||||
OR has_table_privilege(c.oid, 'UPDATE')
|
OR has_table_privilege(c.oid, 'UPDATE')
|
||||||
OR has_table_privilege(c.oid, 'DELETE')
|
OR has_table_privilege(c.oid, 'DELETE')
|
||||||
|
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||||
|
|
||||||
|
@ -1982,6 +1987,7 @@ CREATE VIEW triggers AS
|
||||||
OR has_table_privilege(c.oid, 'INSERT')
|
OR has_table_privilege(c.oid, 'INSERT')
|
||||||
OR has_table_privilege(c.oid, 'UPDATE')
|
OR has_table_privilege(c.oid, 'UPDATE')
|
||||||
OR has_table_privilege(c.oid, 'DELETE')
|
OR has_table_privilege(c.oid, 'DELETE')
|
||||||
|
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||||
|
|
||||||
|
@ -2180,6 +2186,7 @@ CREATE VIEW views AS
|
||||||
OR has_table_privilege(c.oid, 'INSERT')
|
OR has_table_privilege(c.oid, 'INSERT')
|
||||||
OR has_table_privilege(c.oid, 'UPDATE')
|
OR has_table_privilege(c.oid, 'UPDATE')
|
||||||
OR has_table_privilege(c.oid, 'DELETE')
|
OR has_table_privilege(c.oid, 'DELETE')
|
||||||
|
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.18 2008/06/19 00:46:04 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.19 2008/09/08 00:47:40 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -54,7 +54,7 @@ LockTableCommand(LockStmt *lockstmt)
|
||||||
ACL_SELECT);
|
ACL_SELECT);
|
||||||
else
|
else
|
||||||
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
||||||
ACL_UPDATE | ACL_DELETE);
|
ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE);
|
||||||
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.265 2008/09/01 20:42:44 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.266 2008/09/08 00:47:40 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -989,6 +989,8 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||||
static void
|
static void
|
||||||
truncate_check_rel(Relation rel)
|
truncate_check_rel(Relation rel)
|
||||||
{
|
{
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
/* Only allow truncate on regular tables */
|
/* Only allow truncate on regular tables */
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
@ -997,8 +999,10 @@ truncate_check_rel(Relation rel)
|
||||||
RelationGetRelationName(rel))));
|
RelationGetRelationName(rel))));
|
||||||
|
|
||||||
/* Permissions checks */
|
/* Permissions checks */
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
|
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
ACL_TRUNCATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!allowSystemTableMods && IsSystemRelation(rel))
|
if (!allowSystemTableMods && IsSystemRelation(rel))
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.140 2008/03/25 22:42:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.141 2008/09/08 00:47:40 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -265,6 +265,9 @@ aclparse(const char *s, AclItem *aip)
|
||||||
case ACL_DELETE_CHR:
|
case ACL_DELETE_CHR:
|
||||||
read = ACL_DELETE;
|
read = ACL_DELETE;
|
||||||
break;
|
break;
|
||||||
|
case ACL_TRUNCATE_CHR:
|
||||||
|
read = ACL_TRUNCATE;
|
||||||
|
break;
|
||||||
case ACL_REFERENCES_CHR:
|
case ACL_REFERENCES_CHR:
|
||||||
read = ACL_REFERENCES;
|
read = ACL_REFERENCES;
|
||||||
break;
|
break;
|
||||||
|
@ -1323,6 +1326,8 @@ convert_priv_string(text *priv_type_text)
|
||||||
return ACL_UPDATE;
|
return ACL_UPDATE;
|
||||||
if (pg_strcasecmp(priv_type, "DELETE") == 0)
|
if (pg_strcasecmp(priv_type, "DELETE") == 0)
|
||||||
return ACL_DELETE;
|
return ACL_DELETE;
|
||||||
|
if (pg_strcasecmp(priv_type, "TRUNCATE") == 0)
|
||||||
|
return ACL_TRUNCATE;
|
||||||
if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
|
if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
|
||||||
return ACL_REFERENCES;
|
return ACL_REFERENCES;
|
||||||
if (pg_strcasecmp(priv_type, "TRIGGER") == 0)
|
if (pg_strcasecmp(priv_type, "TRIGGER") == 0)
|
||||||
|
@ -1548,6 +1553,11 @@ convert_table_priv_string(text *priv_type_text)
|
||||||
if (pg_strcasecmp(priv_type, "DELETE WITH GRANT OPTION") == 0)
|
if (pg_strcasecmp(priv_type, "DELETE WITH GRANT OPTION") == 0)
|
||||||
return ACL_GRANT_OPTION_FOR(ACL_DELETE);
|
return ACL_GRANT_OPTION_FOR(ACL_DELETE);
|
||||||
|
|
||||||
|
if (pg_strcasecmp(priv_type, "TRUNCATE") == 0)
|
||||||
|
return ACL_TRUNCATE;
|
||||||
|
if (pg_strcasecmp(priv_type, "TRUNCATE WITH GRANT OPTION") == 0)
|
||||||
|
return ACL_GRANT_OPTION_FOR(ACL_TRUNCATE);
|
||||||
|
|
||||||
if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
|
if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
|
||||||
return ACL_REFERENCES;
|
return ACL_REFERENCES;
|
||||||
if (pg_strcasecmp(priv_type, "REFERENCES WITH GRANT OPTION") == 0)
|
if (pg_strcasecmp(priv_type, "REFERENCES WITH GRANT OPTION") == 0)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.40 2008/01/01 19:45:55 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.41 2008/09/08 00:47:40 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -659,6 +659,8 @@ do { \
|
||||||
CONVERT_PRIV('x', "REFERENCES");
|
CONVERT_PRIV('x', "REFERENCES");
|
||||||
CONVERT_PRIV('t', "TRIGGER");
|
CONVERT_PRIV('t', "TRIGGER");
|
||||||
}
|
}
|
||||||
|
if (remoteVersion >= 80400)
|
||||||
|
CONVERT_PRIV('D', "TRUNCATE");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UPDATE */
|
/* UPDATE */
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.171 2008/08/16 01:36:35 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.172 2008/09/08 00:47:40 tgl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
|
@ -1610,9 +1610,9 @@ psql_completion(char *text, int start, int end)
|
||||||
pg_strcasecmp(prev_wd, "REVOKE") == 0)
|
pg_strcasecmp(prev_wd, "REVOKE") == 0)
|
||||||
{
|
{
|
||||||
static const char *const list_privileg[] =
|
static const char *const list_privileg[] =
|
||||||
{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",
|
{"SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES",
|
||||||
"TRIGGER", "CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE",
|
"TRIGGER", "CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE",
|
||||||
"ALL", NULL};
|
"ALL", NULL};
|
||||||
|
|
||||||
COMPLETE_WITH_LIST(list_privileg);
|
COMPLETE_WITH_LIST(list_privileg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.483 2008/09/06 00:01:24 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.484 2008/09/08 00:47:41 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -53,6 +53,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200809051
|
#define CATALOG_VERSION_NO 200809071
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.374 2008/09/01 20:42:45 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.375 2008/09/08 00:47:41 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */
|
||||||
#define ACL_SELECT (1<<1)
|
#define ACL_SELECT (1<<1)
|
||||||
#define ACL_UPDATE (1<<2)
|
#define ACL_UPDATE (1<<2)
|
||||||
#define ACL_DELETE (1<<3)
|
#define ACL_DELETE (1<<3)
|
||||||
/* #define ACL_RULE (1<<4) unused, available */
|
#define ACL_TRUNCATE (1<<4)
|
||||||
#define ACL_REFERENCES (1<<5)
|
#define ACL_REFERENCES (1<<5)
|
||||||
#define ACL_TRIGGER (1<<6)
|
#define ACL_TRIGGER (1<<6)
|
||||||
#define ACL_EXECUTE (1<<7) /* for functions */
|
#define ACL_EXECUTE (1<<7) /* for functions */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.103 2008/01/01 19:45:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.104 2008/09/08 00:47:41 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* An ACL array is simply an array of AclItems, representing the union
|
* An ACL array is simply an array of AclItems, representing the union
|
||||||
|
@ -128,6 +128,7 @@ typedef ArrayType Acl;
|
||||||
#define ACL_SELECT_CHR 'r' /* formerly known as "read" */
|
#define ACL_SELECT_CHR 'r' /* formerly known as "read" */
|
||||||
#define ACL_UPDATE_CHR 'w' /* formerly known as "write" */
|
#define ACL_UPDATE_CHR 'w' /* formerly known as "write" */
|
||||||
#define ACL_DELETE_CHR 'd'
|
#define ACL_DELETE_CHR 'd'
|
||||||
|
#define ACL_TRUNCATE_CHR 'D' /* super-delete, as it were */
|
||||||
#define ACL_REFERENCES_CHR 'x'
|
#define ACL_REFERENCES_CHR 'x'
|
||||||
#define ACL_TRIGGER_CHR 't'
|
#define ACL_TRIGGER_CHR 't'
|
||||||
#define ACL_EXECUTE_CHR 'X'
|
#define ACL_EXECUTE_CHR 'X'
|
||||||
|
@ -137,12 +138,12 @@ typedef ArrayType Acl;
|
||||||
#define ACL_CONNECT_CHR 'c'
|
#define ACL_CONNECT_CHR 'c'
|
||||||
|
|
||||||
/* string holding all privilege code chars, in order by bitmask position */
|
/* string holding all privilege code chars, in order by bitmask position */
|
||||||
#define ACL_ALL_RIGHTS_STR "arwdRxtXUCTc"
|
#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTc"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bitmasks defining "all rights" for each supported object type
|
* Bitmasks defining "all rights" for each supported object type
|
||||||
*/
|
*/
|
||||||
#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_REFERENCES|ACL_TRIGGER)
|
#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER)
|
||||||
#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
|
#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
|
||||||
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
|
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
|
||||||
#define ACL_ALL_RIGHTS_FUNCTION (ACL_EXECUTE)
|
#define ACL_ALL_RIGHTS_FUNCTION (ACL_EXECUTE)
|
||||||
|
|
|
@ -21,7 +21,7 @@ DETAIL: access to table deptest
|
||||||
REVOKE SELECT ON deptest FROM GROUP regression_group;
|
REVOKE SELECT ON deptest FROM GROUP regression_group;
|
||||||
DROP GROUP regression_group;
|
DROP GROUP regression_group;
|
||||||
-- can't drop the user if we revoke the privileges partially
|
-- can't drop the user if we revoke the privileges partially
|
||||||
REVOKE SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES ON deptest FROM regression_user;
|
REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ON deptest FROM regression_user;
|
||||||
DROP USER regression_user;
|
DROP USER regression_user;
|
||||||
ERROR: role "regression_user" cannot be dropped because some objects depend on it
|
ERROR: role "regression_user" cannot be dropped because some objects depend on it
|
||||||
DETAIL: access to table deptest
|
DETAIL: access to table deptest
|
||||||
|
@ -68,21 +68,21 @@ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "deptest_pkey" fo
|
||||||
GRANT ALL ON deptest1 TO regression_user2;
|
GRANT ALL ON deptest1 TO regression_user2;
|
||||||
RESET SESSION AUTHORIZATION;
|
RESET SESSION AUTHORIZATION;
|
||||||
\z deptest1
|
\z deptest1
|
||||||
Access privileges
|
Access privileges
|
||||||
Schema | Name | Type | Access privileges
|
Schema | Name | Type | Access privileges
|
||||||
--------+----------+-------+------------------------------------------------
|
--------+----------+-------+--------------------------------------------------
|
||||||
public | deptest1 | table | regression_user0=arwdxt/regression_user0
|
public | deptest1 | table | regression_user0=arwdDxt/regression_user0
|
||||||
: regression_user1=a*r*w*d*x*t*/regression_user0
|
: regression_user1=a*r*w*d*D*x*t*/regression_user0
|
||||||
: regression_user2=arwdxt/regression_user1
|
: regression_user2=arwdDxt/regression_user1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP OWNED BY regression_user1;
|
DROP OWNED BY regression_user1;
|
||||||
-- all grants revoked
|
-- all grants revoked
|
||||||
\z deptest1
|
\z deptest1
|
||||||
Access privileges
|
Access privileges
|
||||||
Schema | Name | Type | Access privileges
|
Schema | Name | Type | Access privileges
|
||||||
--------+----------+-------+------------------------------------------
|
--------+----------+-------+-------------------------------------------
|
||||||
public | deptest1 | table | regression_user0=arwdxt/regression_user0
|
public | deptest1 | table | regression_user0=arwdDxt/regression_user0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- table was dropped
|
-- table was dropped
|
||||||
|
|
|
@ -10,14 +10,16 @@ DROP ROLE IF EXISTS regressuser1;
|
||||||
DROP ROLE IF EXISTS regressuser2;
|
DROP ROLE IF EXISTS regressuser2;
|
||||||
DROP ROLE IF EXISTS regressuser3;
|
DROP ROLE IF EXISTS regressuser3;
|
||||||
DROP ROLE IF EXISTS regressuser4;
|
DROP ROLE IF EXISTS regressuser4;
|
||||||
|
DROP ROLE IF EXISTS regressuser5;
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
-- test proper begins here
|
-- test proper begins here
|
||||||
CREATE USER regressuser1;
|
CREATE USER regressuser1;
|
||||||
CREATE USER regressuser2;
|
CREATE USER regressuser2;
|
||||||
CREATE USER regressuser3;
|
CREATE USER regressuser3;
|
||||||
CREATE USER regressuser4;
|
CREATE USER regressuser4;
|
||||||
CREATE USER regressuser4; -- duplicate
|
CREATE USER regressuser5;
|
||||||
ERROR: role "regressuser4" already exists
|
CREATE USER regressuser5; -- duplicate
|
||||||
|
ERROR: role "regressuser5" already exists
|
||||||
CREATE GROUP regressgroup1;
|
CREATE GROUP regressgroup1;
|
||||||
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
|
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
|
||||||
ALTER GROUP regressgroup1 ADD USER regressuser4;
|
ALTER GROUP regressgroup1 ADD USER regressuser4;
|
||||||
|
@ -42,6 +44,7 @@ SELECT * FROM atest1;
|
||||||
INSERT INTO atest1 VALUES (1, 'one');
|
INSERT INTO atest1 VALUES (1, 'one');
|
||||||
DELETE FROM atest1;
|
DELETE FROM atest1;
|
||||||
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
||||||
|
TRUNCATE atest1;
|
||||||
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
||||||
REVOKE ALL ON atest1 FROM PUBLIC;
|
REVOKE ALL ON atest1 FROM PUBLIC;
|
||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
|
@ -60,6 +63,7 @@ CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
|
||||||
GRANT SELECT ON atest2 TO regressuser2;
|
GRANT SELECT ON atest2 TO regressuser2;
|
||||||
GRANT UPDATE ON atest2 TO regressuser3;
|
GRANT UPDATE ON atest2 TO regressuser3;
|
||||||
GRANT INSERT ON atest2 TO regressuser4;
|
GRANT INSERT ON atest2 TO regressuser4;
|
||||||
|
GRANT TRUNCATE ON atest2 TO regressuser5;
|
||||||
SET SESSION AUTHORIZATION regressuser2;
|
SET SESSION AUTHORIZATION regressuser2;
|
||||||
SELECT session_user, current_user;
|
SELECT session_user, current_user;
|
||||||
session_user | current_user
|
session_user | current_user
|
||||||
|
@ -96,6 +100,8 @@ SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
TRUNCATE atest2; -- fail
|
||||||
|
ERROR: permission denied for relation atest2
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
|
@ -147,6 +153,8 @@ SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
TRUNCATE atest2; -- fail
|
||||||
|
ERROR: permission denied for relation atest2
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
@ -285,6 +293,11 @@ ERROR: must be owner of function testfunc1
|
||||||
DROP FUNCTION testfunc1(int); -- ok
|
DROP FUNCTION testfunc1(int); -- ok
|
||||||
-- restore to sanity
|
-- restore to sanity
|
||||||
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
||||||
|
-- truncate
|
||||||
|
SET SESSION AUTHORIZATION regressuser5;
|
||||||
|
TRUNCATE atest2; -- ok
|
||||||
|
TRUNCATE atest3; -- fail
|
||||||
|
ERROR: permission denied for relation atest3
|
||||||
-- has_table_privilege function
|
-- has_table_privilege function
|
||||||
-- bad-input checks
|
-- bad-input checks
|
||||||
select has_table_privilege(NULL,'pg_authid','select');
|
select has_table_privilege(NULL,'pg_authid','select');
|
||||||
|
@ -375,6 +388,12 @@ select has_table_privilege('pg_authid','delete');
|
||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
select has_table_privilege('pg_authid','truncate');
|
||||||
|
has_table_privilege
|
||||||
|
---------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'pg_authid') as t1;
|
from (select oid from pg_class where relname = 'pg_authid') as t1;
|
||||||
has_table_privilege
|
has_table_privilege
|
||||||
|
@ -452,6 +471,12 @@ select has_table_privilege('pg_class','delete');
|
||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
select has_table_privilege('pg_class','truncate');
|
||||||
|
has_table_privilege
|
||||||
|
---------------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'pg_class') as t1;
|
from (select oid from pg_class where relname = 'pg_class') as t1;
|
||||||
has_table_privilege
|
has_table_privilege
|
||||||
|
@ -527,6 +552,12 @@ select has_table_privilege('atest1','delete');
|
||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
select has_table_privilege('atest1','truncate');
|
||||||
|
has_table_privilege
|
||||||
|
---------------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'atest1') as t1;
|
from (select oid from pg_class where relname = 'atest1') as t1;
|
||||||
has_table_privilege
|
has_table_privilege
|
||||||
|
@ -604,3 +635,4 @@ DROP USER regressuser1;
|
||||||
DROP USER regressuser2;
|
DROP USER regressuser2;
|
||||||
DROP USER regressuser3;
|
DROP USER regressuser3;
|
||||||
DROP USER regressuser4;
|
DROP USER regressuser4;
|
||||||
|
DROP USER regressuser5;
|
||||||
|
|
|
@ -21,7 +21,7 @@ REVOKE SELECT ON deptest FROM GROUP regression_group;
|
||||||
DROP GROUP regression_group;
|
DROP GROUP regression_group;
|
||||||
|
|
||||||
-- can't drop the user if we revoke the privileges partially
|
-- can't drop the user if we revoke the privileges partially
|
||||||
REVOKE SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES ON deptest FROM regression_user;
|
REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ON deptest FROM regression_user;
|
||||||
DROP USER regression_user;
|
DROP USER regression_user;
|
||||||
|
|
||||||
-- now we are OK to drop him
|
-- now we are OK to drop him
|
||||||
|
|
|
@ -14,6 +14,7 @@ DROP ROLE IF EXISTS regressuser1;
|
||||||
DROP ROLE IF EXISTS regressuser2;
|
DROP ROLE IF EXISTS regressuser2;
|
||||||
DROP ROLE IF EXISTS regressuser3;
|
DROP ROLE IF EXISTS regressuser3;
|
||||||
DROP ROLE IF EXISTS regressuser4;
|
DROP ROLE IF EXISTS regressuser4;
|
||||||
|
DROP ROLE IF EXISTS regressuser5;
|
||||||
|
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
|
|
||||||
|
@ -23,7 +24,8 @@ CREATE USER regressuser1;
|
||||||
CREATE USER regressuser2;
|
CREATE USER regressuser2;
|
||||||
CREATE USER regressuser3;
|
CREATE USER regressuser3;
|
||||||
CREATE USER regressuser4;
|
CREATE USER regressuser4;
|
||||||
CREATE USER regressuser4; -- duplicate
|
CREATE USER regressuser5;
|
||||||
|
CREATE USER regressuser5; -- duplicate
|
||||||
|
|
||||||
CREATE GROUP regressgroup1;
|
CREATE GROUP regressgroup1;
|
||||||
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
|
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
|
||||||
|
@ -45,6 +47,7 @@ SELECT * FROM atest1;
|
||||||
INSERT INTO atest1 VALUES (1, 'one');
|
INSERT INTO atest1 VALUES (1, 'one');
|
||||||
DELETE FROM atest1;
|
DELETE FROM atest1;
|
||||||
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
||||||
|
TRUNCATE atest1;
|
||||||
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
||||||
|
|
||||||
REVOKE ALL ON atest1 FROM PUBLIC;
|
REVOKE ALL ON atest1 FROM PUBLIC;
|
||||||
|
@ -58,6 +61,7 @@ CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
|
||||||
GRANT SELECT ON atest2 TO regressuser2;
|
GRANT SELECT ON atest2 TO regressuser2;
|
||||||
GRANT UPDATE ON atest2 TO regressuser3;
|
GRANT UPDATE ON atest2 TO regressuser3;
|
||||||
GRANT INSERT ON atest2 TO regressuser4;
|
GRANT INSERT ON atest2 TO regressuser4;
|
||||||
|
GRANT TRUNCATE ON atest2 TO regressuser5;
|
||||||
|
|
||||||
|
|
||||||
SET SESSION AUTHORIZATION regressuser2;
|
SET SESSION AUTHORIZATION regressuser2;
|
||||||
|
@ -75,6 +79,7 @@ UPDATE atest2 SET col2 = NOT col2; -- fail
|
||||||
SELECT * FROM atest1 FOR UPDATE; -- ok
|
SELECT * FROM atest1 FOR UPDATE; -- ok
|
||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
|
TRUNCATE atest2; -- fail
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
|
@ -99,6 +104,7 @@ UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; -- ok
|
||||||
SELECT * FROM atest1 FOR UPDATE; -- fail
|
SELECT * FROM atest1 FOR UPDATE; -- fail
|
||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
|
TRUNCATE atest2; -- fail
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
|
|
||||||
|
@ -205,6 +211,10 @@ DROP FUNCTION testfunc1(int); -- ok
|
||||||
-- restore to sanity
|
-- restore to sanity
|
||||||
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
||||||
|
|
||||||
|
-- truncate
|
||||||
|
SET SESSION AUTHORIZATION regressuser5;
|
||||||
|
TRUNCATE atest2; -- ok
|
||||||
|
TRUNCATE atest3; -- fail
|
||||||
|
|
||||||
-- has_table_privilege function
|
-- has_table_privilege function
|
||||||
|
|
||||||
|
@ -243,6 +253,7 @@ from (select oid from pg_class where relname = 'pg_authid') as t1,
|
||||||
|
|
||||||
select has_table_privilege('pg_authid','update');
|
select has_table_privilege('pg_authid','update');
|
||||||
select has_table_privilege('pg_authid','delete');
|
select has_table_privilege('pg_authid','delete');
|
||||||
|
select has_table_privilege('pg_authid','truncate');
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'pg_authid') as t1;
|
from (select oid from pg_class where relname = 'pg_authid') as t1;
|
||||||
|
@ -272,6 +283,7 @@ from (select oid from pg_class where relname = 'pg_class') as t1,
|
||||||
|
|
||||||
select has_table_privilege('pg_class','update');
|
select has_table_privilege('pg_class','update');
|
||||||
select has_table_privilege('pg_class','delete');
|
select has_table_privilege('pg_class','delete');
|
||||||
|
select has_table_privilege('pg_class','truncate');
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'pg_class') as t1;
|
from (select oid from pg_class where relname = 'pg_class') as t1;
|
||||||
|
@ -298,6 +310,7 @@ from (select oid from pg_class where relname = 'atest1') as t1,
|
||||||
|
|
||||||
select has_table_privilege('atest1','update');
|
select has_table_privilege('atest1','update');
|
||||||
select has_table_privilege('atest1','delete');
|
select has_table_privilege('atest1','delete');
|
||||||
|
select has_table_privilege('atest1','truncate');
|
||||||
|
|
||||||
select has_table_privilege(t1.oid,'select')
|
select has_table_privilege(t1.oid,'select')
|
||||||
from (select oid from pg_class where relname = 'atest1') as t1;
|
from (select oid from pg_class where relname = 'atest1') as t1;
|
||||||
|
@ -359,3 +372,4 @@ DROP USER regressuser1;
|
||||||
DROP USER regressuser2;
|
DROP USER regressuser2;
|
||||||
DROP USER regressuser3;
|
DROP USER regressuser3;
|
||||||
DROP USER regressuser4;
|
DROP USER regressuser4;
|
||||||
|
DROP USER regressuser5;
|
||||||
|
|
Loading…
Reference in New Issue