Commit 7bae5a28 authored by Tom Lane's avatar Tom Lane

Get rid of the separate RULE privilege for tables: now only a table's owner

can create or modify rules for the table.  Do setRuleCheckAsUser() while
loading rules into the relcache, rather than when defining a rule.  This
ensures that permission checks for tables referenced in a rule are done with
respect to the current owner of the rule's table, whereas formerly ALTER TABLE
OWNER would fail to update the permission checking for associated rules.
Removal of separate RULE privilege is needed to prevent various scenarios
in which a grantee of RULE privilege could effectively have any privilege
of the table owner.  For backwards compatibility, GRANT/REVOKE RULE is still
accepted, but it doesn't do anything.  Per discussion here:
http://archives.postgresql.org/pgsql-hackers/2006-04/msg01138.php
parent d5eb52a5
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.60 2006/07/14 00:13:05 neilc Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.61 2006/09/05 21:08:33 tgl Exp $ -->
<chapter id="ddl"> <chapter id="ddl">
<title>Data Definition</title> <title>Data Definition</title>
...@@ -1342,7 +1342,7 @@ ALTER TABLE products RENAME TO items; ...@@ -1342,7 +1342,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>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, <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
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.333 2006/09/04 21:47:25 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.334 2006/09/05 21:08:33 tgl Exp $ -->
<chapter id="functions"> <chapter id="functions">
<title>Functions and Operators</title> <title>Functions and Operators</title>
...@@ -9543,9 +9543,10 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); ...@@ -9543,9 +9543,10 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
the name can be schema-qualified if necessary. the name can be schema-qualified if necessary.
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>, <literal>UPDATE</literal>, values <literal>SELECT</literal>, <literal>INSERT</literal>,
<literal>DELETE</literal>, <literal>RULE</literal>, <literal>REFERENCES</literal>, or <literal>UPDATE</literal>, <literal>DELETE</literal>,
<literal>TRIGGER</literal>. (Case of the string is not significant, however.) <literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
(Case of the string is not significant, however.)
An example is: An example is:
<programlisting> <programlisting>
SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('myschema.mytable', 'select');
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.26 2006/05/02 18:07:51 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.27 2006/09/05 21:08:34 tgl Exp $ -->
<chapter id="information-schema"> <chapter id="information-schema">
<title>The Information Schema</title> <title>The Information Schema</title>
...@@ -2832,7 +2832,7 @@ ORDER BY c.ordinal_position; ...@@ -2832,7 +2832,7 @@ ORDER BY c.ordinal_position;
Type of the privilege: <literal>SELECT</literal>, Type of the privilege: <literal>SELECT</literal>,
<literal>DELETE</literal>, <literal>INSERT</literal>, <literal>DELETE</literal>, <literal>INSERT</literal>,
<literal>UPDATE</literal>, <literal>REFERENCES</literal>, <literal>UPDATE</literal>, <literal>REFERENCES</literal>,
<literal>RULE</literal>, or <literal>TRIGGER</literal> or <literal>TRIGGER</literal>
</entry> </entry>
</row> </row>
...@@ -4418,7 +4418,7 @@ ORDER BY c.ordinal_position; ...@@ -4418,7 +4418,7 @@ ORDER BY c.ordinal_position;
Type of the privilege: <literal>SELECT</literal>, Type of the privilege: <literal>SELECT</literal>,
<literal>DELETE</literal>, <literal>INSERT</literal>, <literal>DELETE</literal>, <literal>INSERT</literal>,
<literal>UPDATE</literal>, <literal>REFERENCES</literal>, <literal>UPDATE</literal>, <literal>REFERENCES</literal>,
<literal>RULE</literal>, or <literal>TRIGGER</literal> or <literal>TRIGGER</literal>
</entry> </entry>
</row> </row>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.46 2006/09/02 17:06:52 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_rule.sgml,v 1.47 2006/09/05 21:08:35 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -200,8 +200,7 @@ CREATE [ OR REPLACE ] RULE <replaceable class="parameter">name</replaceable> AS ...@@ -200,8 +200,7 @@ CREATE [ OR REPLACE ] RULE <replaceable class="parameter">name</replaceable> AS
<title>Notes</title> <title>Notes</title>
<para> <para>
You must have the privilege <literal>RULE</literal> on a table to You must be the owner of a table to create or change rules for it.
be allowed to define a rule on it.
</para> </para>
<para> <para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.60 2006/08/02 16:29:49 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.61 2006/09/05 21:08:35 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -20,7 +20,7 @@ PostgreSQL documentation ...@@ -20,7 +20,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } GRANT { { SELECT | INSERT | UPDATE | DELETE | 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 } [, ...] [ WITH GRANT OPTION ] TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
...@@ -178,16 +178,6 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable ...@@ -178,16 +178,6 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>RULE</term>
<listitem>
<para>
Allows the creation of a rule on the table/view. (See the <xref
linkend="sql-createrule" endterm="sql-createrule-title"> statement.)
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>REFERENCES</term> <term>REFERENCES</term>
<listitem> <listitem>
...@@ -418,8 +408,8 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable ...@@ -418,8 +408,8 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
Access privileges for database "lusitania" Access privileges for database "lusitania"
Schema | Name | Type | Access privileges Schema | Name | Type | Access privileges
--------+---------+-------+------------------------------------------------------------ --------+---------+-------+-----------------------------------------------------------
public | mytable | table | {miriam=arwdRxt/miriam,=r/miriam,"group todos=arw/miriam"} public | mytable | table | {miriam=arwdxt/miriam,=r/miriam,"group todos=arw/miriam"}
(1 row) (1 row)
</programlisting> </programlisting>
The entries shown by <command>\z</command> are interpreted thus: The entries shown by <command>\z</command> are interpreted thus:
...@@ -432,7 +422,6 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable ...@@ -432,7 +422,6 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
w -- UPDATE ("write") w -- UPDATE ("write")
a -- INSERT ("append") a -- INSERT ("append")
d -- DELETE d -- DELETE
R -- RULE
x -- REFERENCES x -- REFERENCES
t -- TRIGGER t -- TRIGGER
X -- EXECUTE X -- EXECUTE
...@@ -440,7 +429,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable ...@@ -440,7 +429,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] TO <replaceable
C -- CREATE C -- CREATE
c -- CONNECT c -- CONNECT
T -- TEMPORARY T -- TEMPORARY
arwdRxt -- ALL PRIVILEGES (for tables) arwdxt -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege * -- grant option for preceding privilege
/yyyy -- user who granted this privilege /yyyy -- user who granted this privilege
...@@ -463,7 +452,7 @@ and may include some privileges for <literal>PUBLIC</> depending on the ...@@ -463,7 +452,7 @@ and may include some privileges for <literal>PUBLIC</> depending on the
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=arwdRxt/miriam}</>) and then modify them per the <literal>{miriam=arwdxt/miriam}</>) and then modify them per the
specified request. specified request.
</para> </para>
...@@ -548,8 +537,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable> ...@@ -548,8 +537,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable>
</para> </para>
<para> <para>
The <literal>RULE</literal> privilege, and privileges on Privileges on databases, tablespaces, schemas, and languages are
databases, tablespaces, schemas, and languages are
<productname>PostgreSQL</productname> extensions. <productname>PostgreSQL</productname> extensions.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.39 2006/08/02 16:29:49 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.40 2006/09/05 21:08:35 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -21,7 +21,7 @@ PostgreSQL documentation ...@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } { { SELECT | INSERT | UPDATE | DELETE | 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 } [, ...]
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.36 2006/08/02 16:29:49 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.37 2006/09/05 21:08:34 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; ...@@ -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>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, <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 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.130 2006/07/14 14:52:17 momjian Exp $ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.131 2006/09/05 21:08:35 tgl Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
...@@ -1328,8 +1328,6 @@ string_to_privilege(const char *privname) ...@@ -1328,8 +1328,6 @@ 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, "rule") == 0)
return ACL_RULE;
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)
...@@ -1346,6 +1344,8 @@ string_to_privilege(const char *privname) ...@@ -1346,6 +1344,8 @@ string_to_privilege(const char *privname)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (strcmp(privname, "connect") == 0) if (strcmp(privname, "connect") == 0)
return ACL_CONNECT; return ACL_CONNECT;
if (strcmp(privname, "rule") == 0)
return 0; /* ignore old RULE privileges */
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized privilege type \"%s\"", privname))); errmsg("unrecognized privilege type \"%s\"", privname)));
...@@ -1365,8 +1365,6 @@ privilege_to_string(AclMode privilege) ...@@ -1365,8 +1365,6 @@ privilege_to_string(AclMode privilege)
return "UPDATE"; return "UPDATE";
case ACL_DELETE: case ACL_DELETE:
return "DELETE"; return "DELETE";
case ACL_RULE:
return "RULE";
case ACL_REFERENCES: case ACL_REFERENCES:
return "REFERENCES"; return "REFERENCES";
case ACL_TRIGGER: case ACL_TRIGGER:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 2003-2006, PostgreSQL Global Development Group * Copyright (c) 2003-2006, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.35 2006/09/04 23:13:01 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.36 2006/09/05 21:08:35 tgl Exp $
*/ */
/* /*
...@@ -1194,7 +1194,6 @@ CREATE VIEW role_table_grants AS ...@@ -1194,7 +1194,6 @@ CREATE VIEW role_table_grants AS
SELECT 'INSERT' UNION ALL SELECT 'INSERT' UNION ALL
SELECT 'UPDATE' UNION ALL SELECT 'UPDATE' UNION ALL
SELECT 'REFERENCES' UNION ALL SELECT 'REFERENCES' UNION ALL
SELECT 'RULE' UNION ALL
SELECT 'TRIGGER') AS pr (type) SELECT 'TRIGGER') AS pr (type)
WHERE c.relnamespace = nc.oid WHERE c.relnamespace = nc.oid
...@@ -1705,7 +1704,6 @@ CREATE VIEW table_constraints AS ...@@ -1705,7 +1704,6 @@ 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, 'RULE')
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') )
...@@ -1739,7 +1737,6 @@ CREATE VIEW table_constraints AS ...@@ -1739,7 +1737,6 @@ 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, 'RULE')
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') );
...@@ -1785,7 +1782,6 @@ CREATE VIEW table_privileges AS ...@@ -1785,7 +1782,6 @@ CREATE VIEW table_privileges AS
SELECT 'INSERT' UNION ALL SELECT 'INSERT' UNION ALL
SELECT 'UPDATE' UNION ALL SELECT 'UPDATE' UNION ALL
SELECT 'REFERENCES' UNION ALL SELECT 'REFERENCES' UNION ALL
SELECT 'RULE' UNION ALL
SELECT 'TRIGGER') AS pr (type) SELECT 'TRIGGER') AS pr (type)
WHERE c.relnamespace = nc.oid WHERE c.relnamespace = nc.oid
...@@ -1841,7 +1837,6 @@ CREATE VIEW tables AS ...@@ -1841,7 +1837,6 @@ 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, 'RULE')
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') );
...@@ -1963,7 +1958,6 @@ CREATE VIEW triggers AS ...@@ -1963,7 +1958,6 @@ 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, 'RULE')
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') );
...@@ -2162,7 +2156,6 @@ CREATE VIEW views AS ...@@ -2162,7 +2156,6 @@ 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, 'RULE')
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') );
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 1996-2006, PostgreSQL Global Development Group * Copyright (c) 1996-2006, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.90 2006/07/14 14:52:18 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.91 2006/09/05 21:08:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -741,7 +741,6 @@ CommentRule(List *qualname, char *comment) ...@@ -741,7 +741,6 @@ CommentRule(List *qualname, char *comment)
HeapTuple tuple; HeapTuple tuple;
Oid reloid; Oid reloid;
Oid ruleoid; Oid ruleoid;
AclResult aclcheck;
/* Separate relname and trig name */ /* Separate relname and trig name */
nnames = list_length(qualname); nnames = list_length(qualname);
...@@ -819,9 +818,8 @@ CommentRule(List *qualname, char *comment) ...@@ -819,9 +818,8 @@ CommentRule(List *qualname, char *comment)
} }
/* Check object security */ /* Check object security */
aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE); if (!pg_class_ownercheck(reloid, GetUserId()))
if (aclcheck != ACLCHECK_OK) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
aclcheck_error(aclcheck, ACL_KIND_CLASS,
get_rel_name(reloid)); get_rel_name(reloid));
/* Call CreateComments() to create/drop the comments */ /* Call CreateComments() to create/drop the comments */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.113 2006/09/02 17:06:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.114 2006/09/05 21:08:35 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,9 +33,8 @@ ...@@ -33,9 +33,8 @@
static void checkRuleResultList(List *targetList, TupleDesc resultDesc, static void checkRuleResultList(List *targetList, TupleDesc resultDesc,
bool isSelect); bool isSelect);
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
static void setRuleCheckAsUser_Expr(Node *node, Oid userid);
static bool setRuleCheckAsUser_walker(Node *node, Oid *context); static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
/* /*
...@@ -193,7 +192,6 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -193,7 +192,6 @@ DefineQueryRewrite(RuleStmt *stmt)
int event_attno; int event_attno;
ListCell *l; ListCell *l;
Query *query; Query *query;
AclResult aclresult;
bool RelisBecomingView = false; bool RelisBecomingView = false;
/* /*
...@@ -209,9 +207,8 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -209,9 +207,8 @@ DefineQueryRewrite(RuleStmt *stmt)
/* /*
* Check user has permission to apply rules to this relation. * Check user has permission to apply rules to this relation.
*/ */
aclresult = pg_class_aclcheck(ev_relid, GetUserId(), ACL_RULE); if (!pg_class_ownercheck(ev_relid, GetUserId()))
if (aclresult != ACLCHECK_OK) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
aclcheck_error(aclresult, ACL_KIND_CLASS,
RelationGetRelationName(event_relation)); RelationGetRelationName(event_relation));
/* /*
...@@ -411,19 +408,6 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -411,19 +408,6 @@ DefineQueryRewrite(RuleStmt *stmt)
*/ */
event_attno = -1; event_attno = -1;
/*
* We want the rule's table references to be checked as though by the rule
* owner, not the user referencing the rule. Therefore, scan through the
* rule's rtables and set the checkAsUser field on all rtable entries. We
* have to look at event_qual as well, in case it contains sublinks.
*/
foreach(l, action)
{
query = (Query *) lfirst(l);
setRuleCheckAsUser_Query(query, GetUserId());
}
setRuleCheckAsUser_Expr(event_qual, GetUserId());
/* discard rule if it's null action and not INSTEAD; it's a no-op */ /* discard rule if it's null action and not INSTEAD; it's a no-op */
if (action != NIL || is_instead) if (action != NIL || is_instead)
{ {
...@@ -554,9 +538,9 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect) ...@@ -554,9 +538,9 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
} }
/* /*
* setRuleCheckAsUser_Query * setRuleCheckAsUser
* Recursively scan a query and set the checkAsUser field to the * Recursively scan a query or expression tree and set the checkAsUser
* given userid in all rtable entries. * field to the given userid in all rtable entries.
* *
* Note: for a view (ON SELECT rule), the checkAsUser field of the *OLD* * Note: for a view (ON SELECT rule), the checkAsUser field of the *OLD*
* RTE entry will be overridden when the view rule is expanded, and the * RTE entry will be overridden when the view rule is expanded, and the
...@@ -565,6 +549,26 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect) ...@@ -565,6 +549,26 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect)
* it's important to set these fields to match the rule owner. So we just set * it's important to set these fields to match the rule owner. So we just set
* them always. * them always.
*/ */
void
setRuleCheckAsUser(Node *node, Oid userid)
{
(void) setRuleCheckAsUser_walker(node, &userid);
}
static bool
setRuleCheckAsUser_walker(Node *node, Oid *context)
{
if (node == NULL)
return false;
if (IsA(node, Query))
{
setRuleCheckAsUser_Query((Query *) node, *context);
return false;
}
return expression_tree_walker(node, setRuleCheckAsUser_walker,
(void *) context);
}
static void static void
setRuleCheckAsUser_Query(Query *qry, Oid userid) setRuleCheckAsUser_Query(Query *qry, Oid userid)
{ {
...@@ -591,31 +595,6 @@ setRuleCheckAsUser_Query(Query *qry, Oid userid) ...@@ -591,31 +595,6 @@ setRuleCheckAsUser_Query(Query *qry, Oid userid)
QTW_IGNORE_RT_SUBQUERIES); QTW_IGNORE_RT_SUBQUERIES);
} }
/*
* Expression-tree walker to find sublink queries
*/
static void
setRuleCheckAsUser_Expr(Node *node, Oid userid)
{
(void) setRuleCheckAsUser_walker(node, &userid);
}
static bool
setRuleCheckAsUser_walker(Node *node, Oid *context)
{
if (node == NULL)
return false;
if (IsA(node, Query))
{
Query *qry = (Query *) node;
setRuleCheckAsUser_Query(qry, *context);
return false;
}
return expression_tree_walker(node, setRuleCheckAsUser_walker,
(void *) context);
}
/* /*
* Rename an existing rewrite rule. * Rename an existing rewrite rule.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.65 2006/06/16 20:23:44 adunstan Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.66 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -39,7 +39,6 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior, ...@@ -39,7 +39,6 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior,
{ {
HeapTuple tuple; HeapTuple tuple;
Oid eventRelationOid; Oid eventRelationOid;
AclResult aclresult;
ObjectAddress object; ObjectAddress object;
/* /*
...@@ -72,9 +71,8 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior, ...@@ -72,9 +71,8 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior,
*/ */
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
Assert(eventRelationOid == owningRel); Assert(eventRelationOid == owningRel);
aclresult = pg_class_aclcheck(eventRelationOid, GetUserId(), ACL_RULE); if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
if (aclresult != ACLCHECK_OK) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
aclcheck_error(aclresult, ACL_KIND_CLASS,
get_rel_name(eventRelationOid)); get_rel_name(eventRelationOid));
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.134 2006/07/14 14:52:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.135 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -265,9 +265,6 @@ aclparse(const char *s, AclItem *aip) ...@@ -265,9 +265,6 @@ aclparse(const char *s, AclItem *aip)
case ACL_DELETE_CHR: case ACL_DELETE_CHR:
read = ACL_DELETE; read = ACL_DELETE;
break; break;
case ACL_RULE_CHR:
read = ACL_RULE;
break;
case ACL_REFERENCES_CHR: case ACL_REFERENCES_CHR:
read = ACL_REFERENCES; read = ACL_REFERENCES;
break; break;
...@@ -289,6 +286,9 @@ aclparse(const char *s, AclItem *aip) ...@@ -289,6 +286,9 @@ aclparse(const char *s, AclItem *aip)
case ACL_CONNECT_CHR: case ACL_CONNECT_CHR:
read = ACL_CONNECT; read = ACL_CONNECT;
break; break;
case 'R': /* ignore old RULE privileges */
read = 0;
break;
default: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
...@@ -1325,8 +1325,6 @@ convert_priv_string(text *priv_type_text) ...@@ -1325,8 +1325,6 @@ 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, "RULE") == 0)
return ACL_RULE;
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)
...@@ -1343,6 +1341,8 @@ convert_priv_string(text *priv_type_text) ...@@ -1343,6 +1341,8 @@ convert_priv_string(text *priv_type_text)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (pg_strcasecmp(priv_type, "CONNECT") == 0) if (pg_strcasecmp(priv_type, "CONNECT") == 0)
return ACL_CONNECT; return ACL_CONNECT;
if (pg_strcasecmp(priv_type, "RULE") == 0)
return 0; /* ignore old RULE privileges */
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
...@@ -1553,11 +1553,6 @@ convert_table_priv_string(text *priv_type_text) ...@@ -1553,11 +1553,6 @@ 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, "RULE") == 0)
return ACL_RULE;
if (pg_strcasecmp(priv_type, "RULE WITH GRANT OPTION") == 0)
return ACL_GRANT_OPTION_FOR(ACL_RULE);
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)
...@@ -1568,6 +1563,11 @@ convert_table_priv_string(text *priv_type_text) ...@@ -1568,6 +1563,11 @@ convert_table_priv_string(text *priv_type_text)
if (pg_strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0) if (pg_strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0)
return ACL_GRANT_OPTION_FOR(ACL_TRIGGER); return ACL_GRANT_OPTION_FOR(ACL_TRIGGER);
if (pg_strcasecmp(priv_type, "RULE") == 0)
return 0; /* ignore old RULE privileges */
if (pg_strcasecmp(priv_type, "RULE WITH GRANT OPTION") == 0)
return 0;
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized privilege type: \"%s\"", priv_type))); errmsg("unrecognized privilege type: \"%s\"", priv_type)));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.247 2006/07/31 20:09:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.248 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "rewrite/rewriteDefine.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/builtins.h" #include "utils/builtins.h"
...@@ -683,6 +684,22 @@ RelationBuildRuleLock(Relation relation) ...@@ -683,6 +684,22 @@ RelationBuildRuleLock(Relation relation)
if ((Pointer) rule_text != DatumGetPointer(rule_datum)) if ((Pointer) rule_text != DatumGetPointer(rule_datum))
pfree(rule_text); pfree(rule_text);
/*
* We want the rule's table references to be checked as though by the
* table owner, not the user referencing the rule. Therefore, scan
* through the rule's actions and set the checkAsUser field on all
* rtable entries. We have to look at the qual as well, in case it
* contains sublinks.
*
* The reason for doing this when the rule is loaded, rather than
* when it is stored, is that otherwise ALTER TABLE OWNER would have
* to grovel through stored rules to update checkAsUser fields.
* Scanning the rule tree during load is relatively cheap (compared
* to constructing it in the first place), so we do it here.
*/
setRuleCheckAsUser((Node *) rule->actions, relation->rd_rel->relowner);
setRuleCheckAsUser(rule->qual, relation->rd_rel->relowner);
if (numlocks >= maxlocks) if (numlocks >= maxlocks)
{ {
maxlocks *= 2; maxlocks *= 2;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, 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.353 2006/08/25 04:06:54 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.354 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200608211 #define CATALOG_VERSION_NO 200609051
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, 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.329 2006/09/03 03:19:45 momjian Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.330 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -50,7 +50,7 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */ ...@@ -50,7 +50,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) /* #define ACL_RULE (1<<4) unused, available */
#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 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, 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/rewrite/rewriteDefine.h,v 1.21 2006/03/05 15:58:58 momjian Exp $ * $PostgreSQL: pgsql/src/include/rewrite/rewriteDefine.h,v 1.22 2006/09/05 21:08:36 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,4 +21,6 @@ extern void DefineQueryRewrite(RuleStmt *args); ...@@ -21,4 +21,6 @@ extern void DefineQueryRewrite(RuleStmt *args);
extern void RenameRewriteRule(Oid owningRel, const char *oldName, extern void RenameRewriteRule(Oid owningRel, const char *oldName,
const char *newName); const char *newName);
extern void setRuleCheckAsUser(Node *node, Oid userid);
#endif /* REWRITEDEFINE_H */ #endif /* REWRITEDEFINE_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, 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.96 2006/05/03 22:45:26 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.97 2006/09/05 21:08:36 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,7 +128,6 @@ typedef ArrayType Acl; ...@@ -128,7 +128,6 @@ 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_RULE_CHR 'R'
#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'
...@@ -143,7 +142,7 @@ typedef ArrayType Acl; ...@@ -143,7 +142,7 @@ typedef ArrayType Acl;
/* /*
* 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_RULE|ACL_REFERENCES|ACL_TRIGGER) #define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|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)
......
...@@ -68,19 +68,19 @@ NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "deptest_pkey" fo ...@@ -68,19 +68,19 @@ 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 for database "regression" Access privileges for database "regression"
Schema | Name | Type | Access privileges Schema | Name | Type | Access privileges
--------+----------+-------+---------------------------------------------------------------------------------------------------------------------------------------- --------+----------+-------+------------------------------------------------------------------------------------------------------------------------------------
public | deptest1 | table | {regression_user0=arwdRxt/regression_user0,regression_user1=a*r*w*d*R*x*t*/regression_user0,regression_user2=arwdRxt/regression_user1} public | deptest1 | table | {regression_user0=arwdxt/regression_user0,regression_user1=a*r*w*d*x*t*/regression_user0,regression_user2=arwdxt/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 for database "regression" Access privileges for database "regression"
Schema | Name | Type | Access privileges Schema | Name | Type | Access privileges
--------+----------+-------+--------------------------------------------- --------+----------+-------+--------------------------------------------
public | deptest1 | table | {regression_user0=arwdRxt/regression_user0} public | deptest1 | table | {regression_user0=arwdxt/regression_user0}
(1 row) (1 row)
-- table was dropped -- table was dropped
......
...@@ -301,7 +301,7 @@ select has_table_privilege('pg_authid','sel'); ...@@ -301,7 +301,7 @@ select has_table_privilege('pg_authid','sel');
ERROR: unrecognized privilege type: "sel" ERROR: unrecognized privilege type: "sel"
select has_table_privilege(-999999,'pg_authid','update'); select has_table_privilege(-999999,'pg_authid','update');
ERROR: role with OID 4293967297 does not exist ERROR: role with OID 4293967297 does not exist
select has_table_privilege(1,'rule'); select has_table_privilege(1,'select');
ERROR: relation with OID 1 does not exist ERROR: relation with OID 1 does not exist
-- superuser -- superuser
\c - \c -
...@@ -331,11 +331,13 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -331,11 +331,13 @@ from (select oid from pg_roles where rolname = current_user) as t2;
t t
(1 row) (1 row)
-- 'rule' privilege no longer exists, but for backwards compatibility
-- has_table_privilege still recognizes the keyword and says FALSE
select has_table_privilege(current_user,t1.oid,'rule') select has_table_privilege(current_user,t1.oid,'rule')
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
--------------------- ---------------------
t f
(1 row) (1 row)
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
...@@ -415,13 +417,6 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -415,13 +417,6 @@ from (select oid from pg_roles where rolname = current_user) as t2;
f f
(1 row) (1 row)
select has_table_privilege(current_user,t1.oid,'rule')
from (select oid from pg_class where relname = 'pg_class') as t1;
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
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
...@@ -497,13 +492,6 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -497,13 +492,6 @@ from (select oid from pg_roles where rolname = current_user) as t2;
f f
(1 row) (1 row)
select has_table_privilege(current_user,t1.oid,'rule')
from (select oid from pg_class where relname = 'atest1') as t1;
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
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
......
...@@ -214,7 +214,7 @@ select has_table_privilege('pg_shad','select'); ...@@ -214,7 +214,7 @@ select has_table_privilege('pg_shad','select');
select has_table_privilege('nosuchuser','pg_authid','select'); select has_table_privilege('nosuchuser','pg_authid','select');
select has_table_privilege('pg_authid','sel'); select has_table_privilege('pg_authid','sel');
select has_table_privilege(-999999,'pg_authid','update'); select has_table_privilege(-999999,'pg_authid','update');
select has_table_privilege(1,'rule'); select has_table_privilege(1,'select');
-- superuser -- superuser
\c - \c -
...@@ -227,6 +227,8 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -227,6 +227,8 @@ from (select oid from pg_roles where rolname = current_user) as t2;
select has_table_privilege(t2.oid,'pg_authid','delete') select has_table_privilege(t2.oid,'pg_authid','delete')
from (select oid from pg_roles where rolname = current_user) as t2; from (select oid from pg_roles where rolname = current_user) as t2;
-- 'rule' privilege no longer exists, but for backwards compatibility
-- has_table_privilege still recognizes the keyword and says FALSE
select has_table_privilege(current_user,t1.oid,'rule') select has_table_privilege(current_user,t1.oid,'rule')
from (select oid from pg_class where relname = 'pg_authid') as t1; from (select oid from pg_class where relname = 'pg_authid') as t1;
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
...@@ -258,8 +260,6 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -258,8 +260,6 @@ from (select oid from pg_roles where rolname = current_user) as t2;
select has_table_privilege(t2.oid,'pg_class','delete') select has_table_privilege(t2.oid,'pg_class','delete')
from (select oid from pg_roles where rolname = current_user) as t2; from (select oid from pg_roles where rolname = current_user) as t2;
select has_table_privilege(current_user,t1.oid,'rule')
from (select oid from pg_class where relname = 'pg_class') as t1;
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
from (select oid from pg_class where relname = 'pg_class') as t1; from (select oid from pg_class where relname = 'pg_class') as t1;
...@@ -286,8 +286,6 @@ from (select oid from pg_roles where rolname = current_user) as t2; ...@@ -286,8 +286,6 @@ from (select oid from pg_roles where rolname = current_user) as t2;
select has_table_privilege(t2.oid,'atest1','delete') select has_table_privilege(t2.oid,'atest1','delete')
from (select oid from pg_roles where rolname = current_user) as t2; from (select oid from pg_roles where rolname = current_user) as t2;
select has_table_privilege(current_user,t1.oid,'rule')
from (select oid from pg_class where relname = 'atest1') as t1;
select has_table_privilege(current_user,t1.oid,'references') select has_table_privilege(current_user,t1.oid,'references')
from (select oid from pg_class where relname = 'atest1') as t1; from (select oid from pg_class where relname = 'atest1') as t1;
......
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