Privileges on functions and procedural languages
This commit is contained in:
parent
5e03503126
commit
8adf56f77a
|
@ -1,6 +1,6 @@
|
||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.29 2001/11/21 05:53:40 thomas Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.30 2002/02/18 23:10:59 petere Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="catalogs">
|
<chapter id="catalogs">
|
||||||
|
@ -1261,6 +1261,13 @@
|
||||||
<entry></entry>
|
<entry></entry>
|
||||||
<entry>not currently used</entry>
|
<entry>not currently used</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>lanacl</entry>
|
||||||
|
<entry><type>aclitem[]</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Access permissions</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1699,6 +1706,13 @@
|
||||||
Again, the interpretation is language-specific.
|
Again, the interpretation is language-specific.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>proacl</entry>
|
||||||
|
<entry><type>aclitem[]</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>Access permissions</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.30 2001/12/08 03:24:34 thomas Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.31 2002/02/18 23:11:02 petere Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<refentry id="SQL-CREATEFUNCTION">
|
<refentry id="SQL-CREATEFUNCTION">
|
||||||
|
@ -270,6 +270,17 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
||||||
definition without breaking objects that refer to the function.
|
definition without breaking objects that refer to the function.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To be able to define a function, the user must have the
|
||||||
|
<literal>USAGE</literal> privilege on the language.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By default, only the owner (creator) of the function has the right
|
||||||
|
to execute it. Other users must be granted the
|
||||||
|
<literal>EXECUTE</literal> privilege on the function to be able to
|
||||||
|
use it.
|
||||||
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
|
@ -369,7 +380,9 @@ Point * complex_to_point (Complex *z)
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="sql-dropfunction">,
|
<xref linkend="sql-dropfunction">,
|
||||||
|
<xref linkend="sql-grant">,
|
||||||
<xref linkend="sql-load">,
|
<xref linkend="sql-load">,
|
||||||
|
<xref linkend="sql-revoke">,
|
||||||
<citetitle>PostgreSQL Programmer's Guide</citetitle>
|
<citetitle>PostgreSQL Programmer's Guide</citetitle>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.20 2001/12/08 03:24:34 thomas Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.21 2002/02/18 23:11:02 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -203,8 +203,8 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
|
||||||
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
|
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
|
||||||
-------------+---------+--------------+---------------+-------------
|
-------------+---------+--------------+---------------+-------------
|
||||||
internal | f | f | 0 | n/a
|
internal | f | f | 0 | n/a
|
||||||
C | f | f | 0 | /bin/cc
|
c | f | f | 0 | /bin/cc
|
||||||
sql | f | f | 0 | postgres
|
sql | f | t | 0 | postgres
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -212,6 +212,13 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
|
||||||
At present, the definition of a procedural language cannot be
|
At present, the definition of a procedural language cannot be
|
||||||
changed once it has been created.
|
changed once it has been created.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To be able to use a procedural language, a user must be granted the
|
||||||
|
<literal>USAGE</literal> privilege. The
|
||||||
|
<command>createlang</command> program automatically grants
|
||||||
|
permissions to everyone if the language is known to be trusted.
|
||||||
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1 id="sql-createlanguage-examples">
|
<refsect1 id="sql-createlanguage-examples">
|
||||||
|
@ -257,6 +264,8 @@ CREATE LANGUAGE plsample
|
||||||
<member><xref linkend="sql-createfunction"></member>
|
<member><xref linkend="sql-createfunction"></member>
|
||||||
<member><xref linkend="app-droplang"></member>
|
<member><xref linkend="app-droplang"></member>
|
||||||
<member><xref linkend="sql-droplanguage"></member>
|
<member><xref linkend="sql-droplanguage"></member>
|
||||||
|
<member><xref linkend="sql-grant"></member>
|
||||||
|
<member><xref linkend="sql-revoke"></member>
|
||||||
<member><citetitle>PostgreSQL Programmer's Guide</citetitle></member>
|
<member><citetitle>PostgreSQL Programmer's Guide</citetitle></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.19 2002/01/20 22:19:57 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.20 2002/02/18 23:11:02 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -19,6 +19,14 @@ PostgreSQL documentation
|
||||||
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">objectname</replaceable> [, ...]
|
||||||
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
|
|
||||||
|
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
|
||||||
|
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
|
||||||
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
|
|
||||||
|
GRANT { USAGE | ALL [ PRIVILEGES ] }
|
||||||
|
ON LANGUAGE <replaceable>langname</replaceable> [, ...]
|
||||||
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@ -27,8 +35,9 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,..
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <command>GRANT</command> command gives specific permissions on
|
The <command>GRANT</command> command gives specific permissions on
|
||||||
an object (table, view, sequence) to one or more users or groups of users.
|
an object (table, view, sequence, function, procedural language) to
|
||||||
These permissions are added to those already granted, if any.
|
one or more users or groups of users. These permissions are added
|
||||||
|
to those already granted, if any.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -134,14 +143,36 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,..
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>EXECUTE</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows the use of the specified function and the use of any
|
||||||
|
operators that are implemented on top of the function. This is
|
||||||
|
the only type of privilege that is applicable to functions.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>USAGE</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows the use of the specified procedural language for the
|
||||||
|
creation of functions in that language. This is the only type
|
||||||
|
of privilege that is applicable to procedural languages.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>ALL PRIVILEGES</term>
|
<term>ALL PRIVILEGES</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Grant all of the above privileges at once. The
|
Grant all of the privileges applicable to the object at once.
|
||||||
<literal>PRIVILEGES</literal> key word is optional in
|
The <literal>PRIVILEGES</literal> key word is optional in
|
||||||
<productname>PostgreSQL</productname>, though it is
|
<productname>PostgreSQL</productname>, though it is required by
|
||||||
required by strict SQL.
|
strict SQL.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.19 2001/12/08 03:24:39 thomas Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v 1.20 2002/02/18 23:11:03 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -19,6 +19,14 @@ PostgreSQL documentation
|
||||||
REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
REVOKE { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON [ TABLE ] <replaceable class="PARAMETER">object</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">object</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 } [, ...]
|
||||||
|
|
||||||
|
REVOKE { EXECUTE | ALL [ PRIVILEGES ] }
|
||||||
|
ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
|
||||||
|
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
|
|
||||||
|
REVOKE { USAGE | ALL [ PRIVILEGES ] }
|
||||||
|
ON LANGUAGE <replaceable>langname</replaceable> [, ...]
|
||||||
|
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,35 @@
|
||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.115 2002/01/31 21:20:03 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.116 2002/02/18 23:11:00 petere Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<appendix id="release">
|
<appendix id="release">
|
||||||
<title>Release Notes</title>
|
<title>Release Notes</title>
|
||||||
|
|
||||||
|
<sect1 id="release-devel">
|
||||||
|
<title>&version; Development Branch</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Below is a subset of the changes that have gone into the
|
||||||
|
development branch of PostgreSQL since version 7.2. For a complete
|
||||||
|
list of changes, consult the CVS logs.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Developers: When you add a feature, mention it here. This avoids
|
||||||
|
lossiness when digging out the information from the CVS logs, and
|
||||||
|
furthermore it advertises your feature to external parties at the
|
||||||
|
earliest possible moment.
|
||||||
|
|
||||||
|
CDATA means the content is "SGML-free", so you can write without
|
||||||
|
worries about funny characters.
|
||||||
|
-->
|
||||||
|
<literallayout><![CDATA[
|
||||||
|
Access privileges on functions
|
||||||
|
Access privileges on procedural languages
|
||||||
|
]]></literallayout>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="release-7-2">
|
<sect1 id="release-7-2">
|
||||||
<title>Release 7.2</title>
|
<title>Release 7.2</title>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.53 2001/11/05 17:46:24 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.54 2002/02/18 23:11:07 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
|
@ -18,22 +18,35 @@
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
|
#include "access/transam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_aggregate.h"
|
#include "catalog/pg_aggregate.h"
|
||||||
#include "catalog/pg_group.h"
|
#include "catalog/pg_group.h"
|
||||||
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_shadow.h"
|
#include "catalog/pg_shadow.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "parser/keywords.h"
|
||||||
|
#include "parser/parse.h"
|
||||||
#include "parser/parse_agg.h"
|
#include "parser/parse_agg.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
|
#include "parser/parse_expr.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/temprel.h"
|
#include "utils/temprel.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void ExecuteGrantStmt_Table(GrantStmt *stmt);
|
||||||
|
static void ExecuteGrantStmt_Function(GrantStmt *stmt);
|
||||||
|
static void ExecuteGrantStmt_Lang(GrantStmt *stmt);
|
||||||
|
|
||||||
|
static const char *privilege_token_string(int token);
|
||||||
|
|
||||||
static int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);
|
static int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);
|
||||||
|
|
||||||
/* warning messages, now more explicit. */
|
/* warning messages, now more explicit. */
|
||||||
|
@ -64,19 +77,128 @@ dumpacl(Acl *acl)
|
||||||
#endif /* ACLDEBUG */
|
#endif /* ACLDEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If is_grant is true, adds the given privileges for the list of
|
||||||
|
* grantees to the existing old_acl. If is_grant is false, the
|
||||||
|
* privileges for the given grantees are removed from old_acl.
|
||||||
|
*/
|
||||||
|
static Acl*
|
||||||
|
merge_acl_with_grant(Acl *old_acl, bool is_grant, List *grantees, char *privileges)
|
||||||
|
{
|
||||||
|
List *j;
|
||||||
|
Acl *new_acl;
|
||||||
|
|
||||||
|
#ifdef ACLDEBUG
|
||||||
|
dumpacl(old_acl);
|
||||||
|
#endif
|
||||||
|
new_acl = old_acl;
|
||||||
|
|
||||||
|
foreach(j, grantees)
|
||||||
|
{
|
||||||
|
PrivGrantee *grantee = (PrivGrantee *) lfirst(j);
|
||||||
|
char *granteeString;
|
||||||
|
char *aclString;
|
||||||
|
AclItem aclitem;
|
||||||
|
unsigned modechg;
|
||||||
|
|
||||||
|
if (grantee->username)
|
||||||
|
granteeString = aclmakeuser("U", grantee->username);
|
||||||
|
else if (grantee->groupname)
|
||||||
|
granteeString = aclmakeuser("G", grantee->groupname);
|
||||||
|
else
|
||||||
|
granteeString = aclmakeuser("A", "");
|
||||||
|
|
||||||
|
aclString = makeAclString(privileges, granteeString,
|
||||||
|
is_grant ? '+' : '-');
|
||||||
|
|
||||||
|
/* Convert string ACL spec into internal form */
|
||||||
|
aclparse(aclString, &aclitem, &modechg);
|
||||||
|
new_acl = aclinsert3(new_acl, &aclitem, modechg);
|
||||||
|
|
||||||
|
#ifdef ACLDEBUG
|
||||||
|
dumpacl(new_acl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_acl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called to execute the utility commands GRANT and REVOKE
|
* Called to execute the utility commands GRANT and REVOKE
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ExecuteGrantStmt(GrantStmt *stmt)
|
ExecuteGrantStmt(GrantStmt *stmt)
|
||||||
{
|
{
|
||||||
List *i;
|
|
||||||
List *j;
|
|
||||||
|
|
||||||
/* see comment in pg_type.h */
|
/* see comment in pg_type.h */
|
||||||
Assert(ACLITEMSIZE == sizeof(AclItem));
|
Assert(ACLITEMSIZE == sizeof(AclItem));
|
||||||
|
|
||||||
foreach(i, stmt->relnames)
|
switch(stmt->objtype)
|
||||||
|
{
|
||||||
|
case TABLE:
|
||||||
|
ExecuteGrantStmt_Table(stmt);
|
||||||
|
break;
|
||||||
|
case FUNCTION:
|
||||||
|
ExecuteGrantStmt_Function(stmt);
|
||||||
|
break;
|
||||||
|
case LANGUAGE:
|
||||||
|
ExecuteGrantStmt_Lang(stmt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "bogus GrantStmt.objtype %d", stmt->objtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ExecuteGrantStmt_Table(GrantStmt *stmt)
|
||||||
|
{
|
||||||
|
List *i;
|
||||||
|
char *privstring;
|
||||||
|
|
||||||
|
if (lfirsti(stmt->privileges) == ALL)
|
||||||
|
privstring = aclmakepriv(ACL_MODE_STR, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
privstring = "";
|
||||||
|
foreach(i, stmt->privileges)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
switch(lfirsti(i))
|
||||||
|
{
|
||||||
|
case SELECT:
|
||||||
|
c = ACL_MODE_SELECT_CHR;
|
||||||
|
break;
|
||||||
|
case INSERT:
|
||||||
|
c = ACL_MODE_INSERT_CHR;
|
||||||
|
break;
|
||||||
|
case UPDATE:
|
||||||
|
c = ACL_MODE_UPDATE_CHR;
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
c = ACL_MODE_DELETE_CHR;
|
||||||
|
break;
|
||||||
|
case RULE:
|
||||||
|
c = ACL_MODE_RULE_CHR;
|
||||||
|
break;
|
||||||
|
case REFERENCES:
|
||||||
|
c = ACL_MODE_REFERENCES_CHR;
|
||||||
|
break;
|
||||||
|
case TRIGGER:
|
||||||
|
c = ACL_MODE_TRIGGER_CHR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "invalid privilege type %s for table object",
|
||||||
|
privilege_token_string(lfirsti(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
privstring = aclmakepriv(privstring, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach(i, stmt->objects)
|
||||||
{
|
{
|
||||||
char *relname = strVal(lfirst(i));
|
char *relname = strVal(lfirst(i));
|
||||||
Relation relation;
|
Relation relation;
|
||||||
|
@ -120,41 +242,13 @@ ExecuteGrantStmt(GrantStmt *stmt)
|
||||||
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
|
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
old_acl = acldefault(relname, pg_class_tuple->relowner);
|
old_acl = acldefault(pg_class_tuple->relowner);
|
||||||
else
|
else
|
||||||
/* get a detoasted copy of the rel's ACL */
|
/* get a detoasted copy of the rel's ACL */
|
||||||
old_acl = DatumGetAclPCopy(aclDatum);
|
old_acl = DatumGetAclPCopy(aclDatum);
|
||||||
|
|
||||||
#ifdef ACLDEBUG
|
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
|
||||||
dumpacl(old_acl);
|
stmt->grantees, privstring);
|
||||||
#endif
|
|
||||||
new_acl = old_acl;
|
|
||||||
|
|
||||||
foreach(j, stmt->grantees)
|
|
||||||
{
|
|
||||||
PrivGrantee *grantee = (PrivGrantee *) lfirst(j);
|
|
||||||
char *granteeString;
|
|
||||||
char *aclString;
|
|
||||||
AclItem aclitem;
|
|
||||||
unsigned modechg;
|
|
||||||
|
|
||||||
if (grantee->username)
|
|
||||||
granteeString = aclmakeuser("U", grantee->username);
|
|
||||||
else if (grantee->groupname)
|
|
||||||
granteeString = aclmakeuser("G", grantee->groupname);
|
|
||||||
else
|
|
||||||
granteeString = aclmakeuser("A", "");
|
|
||||||
|
|
||||||
aclString = makeAclString(stmt->privileges, granteeString,
|
|
||||||
stmt->is_grant ? '+' : '-');
|
|
||||||
|
|
||||||
/* Convert string ACL spec into internal form */
|
|
||||||
aclparse(aclString, &aclitem, &modechg);
|
|
||||||
new_acl = aclinsert3(new_acl, &aclitem, modechg);
|
|
||||||
#ifdef ACLDEBUG
|
|
||||||
dumpacl(new_acl);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finished building new ACL value, now insert it */
|
/* finished building new ACL value, now insert it */
|
||||||
for (i = 0; i < Natts_pg_class; ++i)
|
for (i = 0; i < Natts_pg_class; ++i)
|
||||||
|
@ -190,6 +284,267 @@ ExecuteGrantStmt(GrantStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Oid
|
||||||
|
find_function_with_arglist(char *name, List *arguments)
|
||||||
|
{
|
||||||
|
Oid oid;
|
||||||
|
Oid argoids[FUNC_MAX_ARGS];
|
||||||
|
int i;
|
||||||
|
int16 argcount;
|
||||||
|
|
||||||
|
MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||||
|
argcount = length(arguments);
|
||||||
|
if (argcount > FUNC_MAX_ARGS)
|
||||||
|
elog(ERROR, "functions cannot have more than %d arguments",
|
||||||
|
FUNC_MAX_ARGS);
|
||||||
|
|
||||||
|
for (i = 0; i < argcount; i++)
|
||||||
|
{
|
||||||
|
TypeName *t = (TypeName *) lfirst(arguments);
|
||||||
|
char *typnam = TypeNameToInternalName(t);
|
||||||
|
|
||||||
|
arguments = lnext(arguments);
|
||||||
|
|
||||||
|
if (strcmp(typnam, "opaque") == 0)
|
||||||
|
argoids[i] = InvalidOid;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
argoids[i] = GetSysCacheOid(TYPENAME,
|
||||||
|
PointerGetDatum(typnam),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!OidIsValid(argoids[i]))
|
||||||
|
elog(ERROR, "type '%s' not found", typnam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oid = GetSysCacheOid(PROCNAME,
|
||||||
|
PointerGetDatum(name),
|
||||||
|
Int16GetDatum(argcount),
|
||||||
|
PointerGetDatum(argoids),
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (!OidIsValid(oid))
|
||||||
|
func_error(NULL, name, argcount, argoids, NULL);
|
||||||
|
|
||||||
|
return oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||||
|
{
|
||||||
|
List *i;
|
||||||
|
char *privstring = NULL;
|
||||||
|
|
||||||
|
if (lfirsti(stmt->privileges) == ALL)
|
||||||
|
privstring = aclmakepriv("", ACL_MODE_SELECT_CHR);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i, stmt->privileges)
|
||||||
|
{
|
||||||
|
if (lfirsti(i) != EXECUTE)
|
||||||
|
elog(ERROR, "invalid privilege type %s for function object",
|
||||||
|
privilege_token_string(lfirsti(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
privstring = aclmakepriv("", ACL_MODE_SELECT_CHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(i, stmt->objects)
|
||||||
|
{
|
||||||
|
FuncWithArgs *func = (FuncWithArgs *) lfirst(i);
|
||||||
|
Oid oid;
|
||||||
|
Relation relation;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Form_pg_proc pg_proc_tuple;
|
||||||
|
Datum aclDatum;
|
||||||
|
bool isNull;
|
||||||
|
Acl *old_acl;
|
||||||
|
Acl *new_acl;
|
||||||
|
unsigned i;
|
||||||
|
HeapTuple newtuple;
|
||||||
|
Datum values[Natts_pg_proc];
|
||||||
|
char nulls[Natts_pg_proc];
|
||||||
|
char replaces[Natts_pg_proc];
|
||||||
|
|
||||||
|
oid = find_function_with_arglist(func->funcname, func->funcargs);
|
||||||
|
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
||||||
|
tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(oid), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
elog(ERROR, "function %u not found", oid);
|
||||||
|
}
|
||||||
|
pg_proc_tuple = (Form_pg_proc) GETSTRUCT(tuple);
|
||||||
|
|
||||||
|
if (pg_proc_tuple->proowner != GetUserId())
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's no ACL, create a default using the pg_proc.proowner
|
||||||
|
* field.
|
||||||
|
*/
|
||||||
|
aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
old_acl = acldefault(pg_proc_tuple->proowner);
|
||||||
|
else
|
||||||
|
/* get a detoasted copy of the rel's ACL */
|
||||||
|
old_acl = DatumGetAclPCopy(aclDatum);
|
||||||
|
|
||||||
|
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
|
||||||
|
stmt->grantees, privstring);
|
||||||
|
|
||||||
|
/* finished building new ACL value, now insert it */
|
||||||
|
for (i = 0; i < Natts_pg_proc; ++i)
|
||||||
|
{
|
||||||
|
replaces[i] = ' ';
|
||||||
|
nulls[i] = ' '; /* ignored if replaces[i]==' ' anyway */
|
||||||
|
values[i] = (Datum) NULL; /* ignored if replaces[i]==' '
|
||||||
|
* anyway */
|
||||||
|
}
|
||||||
|
replaces[Anum_pg_proc_proacl - 1] = 'r';
|
||||||
|
values[Anum_pg_proc_proacl - 1] = PointerGetDatum(new_acl);
|
||||||
|
newtuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* keep the catalog indexes up to date */
|
||||||
|
Relation idescs[Num_pg_proc_indices];
|
||||||
|
|
||||||
|
CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices,
|
||||||
|
idescs);
|
||||||
|
CatalogIndexInsert(idescs, Num_pg_proc_indices, relation, newtuple);
|
||||||
|
CatalogCloseIndices(Num_pg_proc_indices, idescs);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(old_acl);
|
||||||
|
pfree(new_acl);
|
||||||
|
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ExecuteGrantStmt_Lang(GrantStmt *stmt)
|
||||||
|
{
|
||||||
|
List *i;
|
||||||
|
char *privstring = NULL;
|
||||||
|
|
||||||
|
if (lfirsti(stmt->privileges) == ALL)
|
||||||
|
privstring = aclmakepriv("", ACL_MODE_SELECT_CHR);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i, stmt->privileges)
|
||||||
|
{
|
||||||
|
if (lfirsti(i) != USAGE)
|
||||||
|
elog(ERROR, "invalid privilege type %s for language object",
|
||||||
|
privilege_token_string(lfirsti(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
privstring = aclmakepriv("", ACL_MODE_SELECT_CHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(i, stmt->objects)
|
||||||
|
{
|
||||||
|
char *langname = strVal(lfirst(i));
|
||||||
|
Relation relation;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Form_pg_language pg_language_tuple;
|
||||||
|
Datum aclDatum;
|
||||||
|
bool isNull;
|
||||||
|
Acl *old_acl;
|
||||||
|
Acl *new_acl;
|
||||||
|
unsigned i;
|
||||||
|
HeapTuple newtuple;
|
||||||
|
Datum values[Natts_pg_language];
|
||||||
|
char nulls[Natts_pg_language];
|
||||||
|
char replaces[Natts_pg_language];
|
||||||
|
|
||||||
|
if (!superuser())
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
|
relation = heap_openr(LanguageRelationName, RowExclusiveLock);
|
||||||
|
tuple = SearchSysCache(LANGNAME, PointerGetDatum(langname), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
elog(ERROR, "language \"%s\" not found", langname);
|
||||||
|
}
|
||||||
|
pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);
|
||||||
|
|
||||||
|
if (!pg_language_tuple->lanpltrusted)
|
||||||
|
{
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
elog(ERROR, "language \"%s\" is not trusted", langname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's no ACL, create a default.
|
||||||
|
*/
|
||||||
|
aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
old_acl = acldefault(InvalidOid);
|
||||||
|
else
|
||||||
|
/* get a detoasted copy of the rel's ACL */
|
||||||
|
old_acl = DatumGetAclPCopy(aclDatum);
|
||||||
|
|
||||||
|
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
|
||||||
|
stmt->grantees, privstring);
|
||||||
|
|
||||||
|
/* finished building new ACL value, now insert it */
|
||||||
|
for (i = 0; i < Natts_pg_language; ++i)
|
||||||
|
{
|
||||||
|
replaces[i] = ' ';
|
||||||
|
nulls[i] = ' '; /* ignored if replaces[i]==' ' anyway */
|
||||||
|
values[i] = (Datum) NULL; /* ignored if replaces[i]==' '
|
||||||
|
* anyway */
|
||||||
|
}
|
||||||
|
replaces[Anum_pg_language_lanacl - 1] = 'r';
|
||||||
|
values[Anum_pg_language_lanacl - 1] = PointerGetDatum(new_acl);
|
||||||
|
newtuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* keep the catalog indexes up to date */
|
||||||
|
Relation idescs[Num_pg_language_indices];
|
||||||
|
|
||||||
|
CatalogOpenIndices(Num_pg_language_indices, Name_pg_language_indices,
|
||||||
|
idescs);
|
||||||
|
CatalogIndexInsert(idescs, Num_pg_language_indices, relation, newtuple);
|
||||||
|
CatalogCloseIndices(Num_pg_language_indices, idescs);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(old_acl);
|
||||||
|
pfree(new_acl);
|
||||||
|
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
privilege_token_string(int token)
|
||||||
|
{
|
||||||
|
const char *s = TokenString(token);
|
||||||
|
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
else
|
||||||
|
elog(ERROR, "privilege_token_string: invalid token number");
|
||||||
|
return NULL; /* appease compiler */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AclId
|
AclId
|
||||||
get_grosysid(char *groname)
|
get_grosysid(char *groname)
|
||||||
|
@ -483,7 +838,7 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
|
||||||
AclId ownerId;
|
AclId ownerId;
|
||||||
|
|
||||||
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
||||||
acl = acldefault(relname, ownerId);
|
acl = acldefault(ownerId);
|
||||||
aclDatum = (Datum) 0;
|
aclDatum = (Datum) 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -721,3 +1076,142 @@ pg_aggr_ownercheck(Oid userid,
|
||||||
|
|
||||||
return userid == owner_id;
|
return userid == owner_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exported routine for checking a user's access privileges to a function
|
||||||
|
*
|
||||||
|
* Returns an ACLCHECK_* result code.
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
pg_proc_aclcheck(Oid proc_oid, Oid userid)
|
||||||
|
{
|
||||||
|
int32 result;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Datum aclDatum;
|
||||||
|
bool isNull;
|
||||||
|
Acl *acl;
|
||||||
|
|
||||||
|
if (superuser_arg(userid))
|
||||||
|
return ACLCHECK_OK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate userid
|
||||||
|
*/
|
||||||
|
tuple = SearchSysCache(SHADOWSYSID,
|
||||||
|
ObjectIdGetDatum(userid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "pg_proc_aclcheck: invalid user id %u",
|
||||||
|
(unsigned) userid);
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal case: get the function's ACL from pg_proc
|
||||||
|
*/
|
||||||
|
tuple = SearchSysCache(PROCOID,
|
||||||
|
ObjectIdGetDatum(proc_oid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "pg_proc_aclcheck: function %u not found", proc_oid);
|
||||||
|
|
||||||
|
aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
{
|
||||||
|
/* No ACL, so build default ACL */
|
||||||
|
AclId ownerId;
|
||||||
|
|
||||||
|
ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
|
||||||
|
acl = acldefault(ownerId);
|
||||||
|
aclDatum = (Datum) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* detoast ACL if necessary */
|
||||||
|
acl = DatumGetAclP(aclDatum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions only have one kind of privilege, which is encoded as
|
||||||
|
* "SELECT" here.
|
||||||
|
*/
|
||||||
|
result = aclcheck(acl, userid, (AclIdType) ACL_IDTYPE_UID, ACL_SELECT);
|
||||||
|
|
||||||
|
/* if we have a detoasted copy, free it */
|
||||||
|
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||||
|
pfree(acl);
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exported routine for checking a user's access privileges to a language
|
||||||
|
*
|
||||||
|
* Returns an ACLCHECK_* result code.
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
pg_language_aclcheck(Oid lang_oid, Oid userid)
|
||||||
|
{
|
||||||
|
int32 result;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Datum aclDatum;
|
||||||
|
bool isNull;
|
||||||
|
Acl *acl;
|
||||||
|
|
||||||
|
if (superuser_arg(userid))
|
||||||
|
return ACLCHECK_OK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate userid
|
||||||
|
*/
|
||||||
|
tuple = SearchSysCache(SHADOWSYSID,
|
||||||
|
ObjectIdGetDatum(userid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "pg_language_aclcheck: invalid user id %u",
|
||||||
|
(unsigned) userid);
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal case: get the function's ACL from pg_language
|
||||||
|
*/
|
||||||
|
tuple = SearchSysCache(LANGOID,
|
||||||
|
ObjectIdGetDatum(lang_oid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "pg_language_aclcheck: language %u not found", lang_oid);
|
||||||
|
|
||||||
|
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
{
|
||||||
|
/* No ACL, so build default ACL */
|
||||||
|
acl = acldefault(InvalidOid);
|
||||||
|
aclDatum = (Datum) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* detoast ACL if necessary */
|
||||||
|
acl = DatumGetAclP(aclDatum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Languages only have one kind of privilege, which is encoded as
|
||||||
|
* "SELECT" here.
|
||||||
|
*/
|
||||||
|
result = aclcheck(acl, userid, (AclIdType) ACL_IDTYPE_UID, ACL_SELECT);
|
||||||
|
|
||||||
|
/* if we have a detoasted copy, free it */
|
||||||
|
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||||
|
pfree(acl);
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.63 2001/11/05 17:46:24 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.64 2002/02/18 23:11:08 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -44,7 +44,7 @@ ProcedureCreate(char *procedureName,
|
||||||
bool replace,
|
bool replace,
|
||||||
bool returnsSet,
|
bool returnsSet,
|
||||||
char *returnTypeName,
|
char *returnTypeName,
|
||||||
char *languageName,
|
Oid languageObjectId,
|
||||||
char *prosrc,
|
char *prosrc,
|
||||||
char *probin,
|
char *probin,
|
||||||
bool trusted,
|
bool trusted,
|
||||||
|
@ -65,7 +65,6 @@ ProcedureCreate(char *procedureName,
|
||||||
char nulls[Natts_pg_proc];
|
char nulls[Natts_pg_proc];
|
||||||
Datum values[Natts_pg_proc];
|
Datum values[Natts_pg_proc];
|
||||||
char replaces[Natts_pg_proc];
|
char replaces[Natts_pg_proc];
|
||||||
Oid languageObjectId;
|
|
||||||
Oid typeObjectId;
|
Oid typeObjectId;
|
||||||
List *x;
|
List *x;
|
||||||
List *querytree_list;
|
List *querytree_list;
|
||||||
|
@ -82,12 +81,6 @@ ProcedureCreate(char *procedureName,
|
||||||
Assert(PointerIsValid(prosrc));
|
Assert(PointerIsValid(prosrc));
|
||||||
Assert(PointerIsValid(probin));
|
Assert(PointerIsValid(probin));
|
||||||
|
|
||||||
languageObjectId = GetSysCacheOid(LANGNAME,
|
|
||||||
PointerGetDatum(languageName),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(languageObjectId))
|
|
||||||
elog(ERROR, "language '%s' does not exist", languageName);
|
|
||||||
|
|
||||||
parameterCount = 0;
|
parameterCount = 0;
|
||||||
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||||
foreach(x, argList)
|
foreach(x, argList)
|
||||||
|
@ -320,6 +313,9 @@ ProcedureCreate(char *procedureName,
|
||||||
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
|
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
|
||||||
"\n\tUse DROP FUNCTION first.");
|
"\n\tUse DROP FUNCTION first.");
|
||||||
|
|
||||||
|
/* do not change existing permissions */
|
||||||
|
replaces[Anum_pg_proc_proacl-1] = ' ';
|
||||||
|
|
||||||
/* Okay, do it... */
|
/* Okay, do it... */
|
||||||
tup = heap_modifytuple(oldtup, rel, values, nulls, replaces);
|
tup = heap_modifytuple(oldtup, rel, values, nulls, replaces);
|
||||||
simple_heap_update(rel, &tup->t_self, tup);
|
simple_heap_update(rel, &tup->t_self, tup);
|
||||||
|
@ -329,6 +325,10 @@ ProcedureCreate(char *procedureName,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Creating a new procedure */
|
/* Creating a new procedure */
|
||||||
|
|
||||||
|
/* start out with empty permissions */
|
||||||
|
nulls[Anum_pg_proc_proacl-1] = 'n';
|
||||||
|
|
||||||
tup = heap_formtuple(tupDesc, values, nulls);
|
tup = heap_formtuple(tupDesc, values, nulls);
|
||||||
heap_insert(rel, tup);
|
heap_insert(rel, tup);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.64 2001/10/28 06:25:42 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.65 2002/02/18 23:11:10 petere Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
|
@ -50,6 +50,7 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "optimizer/cost.h"
|
#include "optimizer/cost.h"
|
||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
@ -60,22 +61,18 @@ static int defGetTypeLength(DefElem *def);
|
||||||
#define DEFAULT_TYPDELIM ','
|
#define DEFAULT_TYPDELIM ','
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate the input language name to lower case.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
case_translate_language_name(const char *input, char *output)
|
case_translate_language_name(const char *input, char *output)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Translate the input language name to lower case, except if it's "C",
|
|
||||||
* translate to upper case.
|
|
||||||
*/
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NAMEDATALEN - 1 && input[i]; ++i)
|
for (i = 0; i < NAMEDATALEN - 1 && input[i]; ++i)
|
||||||
output[i] = tolower((unsigned char) input[i]);
|
output[i] = tolower((unsigned char) input[i]);
|
||||||
|
|
||||||
output[i] = '\0';
|
output[i] = '\0';
|
||||||
|
|
||||||
if (strcmp(output, "c") == 0)
|
|
||||||
output[0] = 'C';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,12 +172,12 @@ compute_full_attributes(List *parameters,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
interpret_AS_clause(const char *languageName, const List *as,
|
interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
|
||||||
char **prosrc_str_p, char **probin_str_p)
|
char **prosrc_str_p, char **probin_str_p)
|
||||||
{
|
{
|
||||||
Assert(as != NIL);
|
Assert(as != NIL);
|
||||||
|
|
||||||
if (strcmp(languageName, "C") == 0)
|
if (languageOid == ClanguageId)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For "C" language, store the file name in probin and, when
|
* For "C" language, store the file name in probin and, when
|
||||||
|
@ -213,29 +210,16 @@ interpret_AS_clause(const char *languageName, const List *as,
|
||||||
void
|
void
|
||||||
CreateFunction(ProcedureStmt *stmt)
|
CreateFunction(ProcedureStmt *stmt)
|
||||||
{
|
{
|
||||||
char *probin_str;
|
|
||||||
|
|
||||||
/* pathname of executable file that executes this function, if any */
|
/* pathname of executable file that executes this function, if any */
|
||||||
|
char *probin_str;
|
||||||
char *prosrc_str;
|
|
||||||
|
|
||||||
/* SQL that executes this function, if any */
|
/* SQL that executes this function, if any */
|
||||||
|
char *prosrc_str;
|
||||||
char *prorettype;
|
|
||||||
|
|
||||||
/* Type of return value (or member of set of values) from function */
|
/* Type of return value (or member of set of values) from function */
|
||||||
|
char *prorettype;
|
||||||
|
/* name of language of function, with case adjusted */
|
||||||
char languageName[NAMEDATALEN];
|
char languageName[NAMEDATALEN];
|
||||||
|
|
||||||
/*
|
|
||||||
* name of language of function, with case adjusted: "C", "internal",
|
|
||||||
* "sql", etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool returnsSet;
|
|
||||||
|
|
||||||
/* The function returns a set of values, as opposed to a singleton. */
|
/* The function returns a set of values, as opposed to a singleton. */
|
||||||
|
bool returnsSet;
|
||||||
/*
|
/*
|
||||||
* The following are optional user-supplied attributes of the
|
* The following are optional user-supplied attributes of the
|
||||||
* function.
|
* function.
|
||||||
|
@ -247,62 +231,28 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
bool canCache,
|
bool canCache,
|
||||||
isStrict;
|
isStrict;
|
||||||
|
|
||||||
|
HeapTuple languageTuple;
|
||||||
|
Form_pg_language languageStruct;
|
||||||
|
Oid languageOid;
|
||||||
|
|
||||||
/* Convert language name to canonical case */
|
/* Convert language name to canonical case */
|
||||||
case_translate_language_name(stmt->language, languageName);
|
case_translate_language_name(stmt->language, languageName);
|
||||||
|
|
||||||
/*
|
languageTuple = SearchSysCache(LANGNAME,
|
||||||
* Apply appropriate security checks depending on language.
|
PointerGetDatum(languageName),
|
||||||
*/
|
0, 0, 0);
|
||||||
if (strcmp(languageName, "C") == 0 ||
|
if (!HeapTupleIsValid(languageTuple))
|
||||||
strcmp(languageName, "internal") == 0)
|
elog(ERROR, "language \"%s\" does not exist", languageName);
|
||||||
{
|
|
||||||
if (!superuser())
|
|
||||||
elog(ERROR,
|
|
||||||
"Only users with Postgres superuser privilege are "
|
|
||||||
"permitted to create a function in the '%s' language.\n\t"
|
|
||||||
"Others may use the 'sql' language "
|
|
||||||
"or the created procedural languages.",
|
|
||||||
languageName);
|
|
||||||
}
|
|
||||||
else if (strcmp(languageName, "sql") == 0)
|
|
||||||
{
|
|
||||||
/* No security check needed for SQL functions */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HeapTuple languageTuple;
|
|
||||||
Form_pg_language languageStruct;
|
|
||||||
|
|
||||||
/* Lookup the language in the system cache */
|
languageOid = languageTuple->t_data->t_oid;
|
||||||
languageTuple = SearchSysCache(LANGNAME,
|
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
|
||||||
PointerGetDatum(languageName),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!HeapTupleIsValid(languageTuple))
|
|
||||||
elog(ERROR,
|
|
||||||
"Unrecognized language specified in a CREATE FUNCTION: "
|
|
||||||
"'%s'.\n\tPre-installed languages are SQL, C, and "
|
|
||||||
"internal.\n\tAdditional languages may be installed "
|
|
||||||
"using 'createlang'.",
|
|
||||||
languageName);
|
|
||||||
|
|
||||||
/* Check that this language is a PL */
|
if (!((languageStruct->lanpltrusted
|
||||||
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
|
&& pg_language_aclcheck(languageOid, GetUserId()) == ACLCHECK_OK)
|
||||||
if (!languageStruct->lanispl)
|
|| superuser()))
|
||||||
elog(ERROR,
|
elog(ERROR, "permission denied");
|
||||||
"Language '%s' isn't defined as PL", languageName);
|
|
||||||
|
|
||||||
/*
|
ReleaseSysCache(languageTuple);
|
||||||
* Functions in untrusted procedural languages are restricted to
|
|
||||||
* be defined by postgres superusers only
|
|
||||||
*/
|
|
||||||
if (!languageStruct->lanpltrusted && !superuser())
|
|
||||||
elog(ERROR, "Only users with Postgres superuser privilege "
|
|
||||||
"are permitted to create a function in the '%s' "
|
|
||||||
"language.",
|
|
||||||
languageName);
|
|
||||||
|
|
||||||
ReleaseSysCache(languageTuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert remaining parameters of CREATE to form wanted by
|
* Convert remaining parameters of CREATE to form wanted by
|
||||||
|
@ -316,7 +266,7 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||||
&outin_ratio, &canCache, &isStrict);
|
&outin_ratio, &canCache, &isStrict);
|
||||||
|
|
||||||
interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
|
interpret_AS_clause(languageOid, languageName, stmt->as, &prosrc_str, &probin_str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* And now that we have all the parameters, and know we're permitted
|
* And now that we have all the parameters, and know we're permitted
|
||||||
|
@ -326,7 +276,7 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
stmt->replace,
|
stmt->replace,
|
||||||
returnsSet,
|
returnsSet,
|
||||||
prorettype,
|
prorettype,
|
||||||
languageName,
|
languageOid,
|
||||||
prosrc_str, /* converted to text later */
|
prosrc_str, /* converted to text later */
|
||||||
probin_str, /* converted to text later */
|
probin_str, /* converted to text later */
|
||||||
true, /* (obsolete "trusted") */
|
true, /* (obsolete "trusted") */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.28 2001/06/13 21:44:40 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.29 2002/02/18 23:11:11 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -27,22 +27,18 @@
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate the input language name to lower case.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
case_translate_language_name(const char *input, char *output)
|
case_translate_language_name(const char *input, char *output)
|
||||||
{
|
{
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
Translate the input language name to lower case, except if it's C,
|
|
||||||
translate to upper case.
|
|
||||||
--------------------------------------------------------------------------*/
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NAMEDATALEN && input[i]; ++i)
|
for (i = 0; i < NAMEDATALEN && input[i]; ++i)
|
||||||
output[i] = tolower((unsigned char) input[i]);
|
output[i] = tolower((unsigned char) input[i]);
|
||||||
|
|
||||||
output[i] = '\0';
|
output[i] = '\0';
|
||||||
|
|
||||||
if (strcmp(output, "c") == 0)
|
|
||||||
output[0] = 'C';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,6 +112,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||||
values[i++] = ObjectIdGetDatum(procTup->t_data->t_oid);
|
values[i++] = ObjectIdGetDatum(procTup->t_data->t_oid);
|
||||||
values[i++] = DirectFunctionCall1(textin,
|
values[i++] = DirectFunctionCall1(textin,
|
||||||
CStringGetDatum(stmt->plcompiler));
|
CStringGetDatum(stmt->plcompiler));
|
||||||
|
nulls[i] = 'n'; /* lanacl */
|
||||||
|
|
||||||
ReleaseSysCache(procTup);
|
ReleaseSysCache(procTup);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.89 2001/10/25 05:49:27 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.90 2002/02/18 23:11:13 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -658,6 +658,9 @@ ExecMakeFunctionResult(FunctionCachePtr fcache,
|
||||||
bool hasSetArg;
|
bool hasSetArg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!fcache->permission_ok)
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* arguments is a list of expressions to evaluate before passing to
|
* arguments is a list of expressions to evaluate before passing to
|
||||||
* the function manager. We skip the evaluation if it was already
|
* the function manager. We skip the evaluation if it was already
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.160 2001/11/05 05:00:14 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.161 2002/02/18 23:11:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1893,9 +1893,9 @@ _copyGrantStmt(GrantStmt *from)
|
||||||
GrantStmt *newnode = makeNode(GrantStmt);
|
GrantStmt *newnode = makeNode(GrantStmt);
|
||||||
|
|
||||||
newnode->is_grant = from->is_grant;
|
newnode->is_grant = from->is_grant;
|
||||||
Node_Copy(from, newnode, relnames);
|
newnode->objtype = from->objtype;
|
||||||
if (from->privileges)
|
Node_Copy(from, newnode, objects);
|
||||||
newnode->privileges = pstrdup(from->privileges);
|
Node_Copy(from, newnode, privileges);
|
||||||
Node_Copy(from, newnode, grantees);
|
Node_Copy(from, newnode, grantees);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
|
@ -1914,6 +1914,20 @@ _copyPrivGrantee(PrivGrantee *from)
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FuncWithArgs *
|
||||||
|
_copyFuncWithArgs(FuncWithArgs *from)
|
||||||
|
{
|
||||||
|
FuncWithArgs *newnode = makeNode(FuncWithArgs);
|
||||||
|
|
||||||
|
if (from->funcname)
|
||||||
|
newnode->funcname = pstrdup(from->funcname);
|
||||||
|
else
|
||||||
|
newnode->funcname = NULL;
|
||||||
|
Node_Copy(from, newnode, funcargs);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
static ClosePortalStmt *
|
static ClosePortalStmt *
|
||||||
_copyClosePortalStmt(ClosePortalStmt *from)
|
_copyClosePortalStmt(ClosePortalStmt *from)
|
||||||
{
|
{
|
||||||
|
@ -2971,6 +2985,9 @@ copyObject(void *from)
|
||||||
case T_PrivGrantee:
|
case T_PrivGrantee:
|
||||||
retval = _copyPrivGrantee(from);
|
retval = _copyPrivGrantee(from);
|
||||||
break;
|
break;
|
||||||
|
case T_FuncWithArgs:
|
||||||
|
retval = _copyFuncWithArgs(from);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.108 2001/11/05 05:00:14 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.109 2002/02/18 23:11:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -758,9 +758,11 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
|
||||||
{
|
{
|
||||||
if (a->is_grant != b->is_grant)
|
if (a->is_grant != b->is_grant)
|
||||||
return false;
|
return false;
|
||||||
if (!equal(a->relnames, b->relnames))
|
if (a->objtype != b->objtype)
|
||||||
return false;
|
return false;
|
||||||
if (!equalstr(a->privileges, b->privileges))
|
if (!equal(a->objects, b->objects))
|
||||||
|
return false;
|
||||||
|
if (!equal(a->privileges, b->privileges))
|
||||||
return false;
|
return false;
|
||||||
if (!equal(a->grantees, b->grantees))
|
if (!equal(a->grantees, b->grantees))
|
||||||
return false;
|
return false;
|
||||||
|
@ -775,6 +777,13 @@ _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
|
||||||
&& equalstr(a->groupname, b->groupname);
|
&& equalstr(a->groupname, b->groupname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
|
||||||
|
{
|
||||||
|
return equalstr(a->funcname, b->funcname)
|
||||||
|
&& equal(a->funcargs, b->funcargs);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
|
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
|
||||||
{
|
{
|
||||||
|
@ -2122,6 +2131,9 @@ equal(void *a, void *b)
|
||||||
case T_PrivGrantee:
|
case T_PrivGrantee:
|
||||||
retval = _equalPrivGrantee(a, b);
|
retval = _equalPrivGrantee(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_FuncWithArgs:
|
||||||
|
retval = _equalFuncWithArgs(a, b);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
|
elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.277 2002/02/18 06:49:20 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.278 2002/02/18 23:11:17 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
|
@ -56,7 +56,6 @@
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "parser/gramparse.h"
|
#include "parser/gramparse.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "utils/acl.h"
|
|
||||||
#include "utils/numeric.h"
|
#include "utils/numeric.h"
|
||||||
#include "utils/datetime.h"
|
#include "utils/datetime.h"
|
||||||
|
|
||||||
|
@ -122,6 +121,7 @@ static void doNegateFloat(Value *v);
|
||||||
A_Indices *aind;
|
A_Indices *aind;
|
||||||
ResTarget *target;
|
ResTarget *target;
|
||||||
ParamNo *paramno;
|
ParamNo *paramno;
|
||||||
|
PrivTarget *privtarget;
|
||||||
|
|
||||||
VersionStmt *vstmt;
|
VersionStmt *vstmt;
|
||||||
DefineStmt *dstmt;
|
DefineStmt *dstmt;
|
||||||
|
@ -182,10 +182,14 @@ static void doNegateFloat(Value *v);
|
||||||
OptUseOp, opt_class, SpecialRuleRelation
|
OptUseOp, opt_class, SpecialRuleRelation
|
||||||
|
|
||||||
%type <str> opt_level, opt_encoding
|
%type <str> opt_level, opt_encoding
|
||||||
%type <str> privileges, operation_commalist
|
|
||||||
%type <node> grantee
|
%type <node> grantee
|
||||||
%type <list> grantee_list
|
%type <list> grantee_list
|
||||||
%type <chr> operation, TriggerOneEvent
|
%type <ival> privilege
|
||||||
|
%type <list> privileges, privilege_list
|
||||||
|
%type <privtarget> privilege_target
|
||||||
|
%type <node> function_with_argtypes
|
||||||
|
%type <list> function_with_argtypes_list
|
||||||
|
%type <chr> TriggerOneEvent
|
||||||
|
|
||||||
%type <list> stmtblock, stmtmulti,
|
%type <list> stmtblock, stmtmulti,
|
||||||
into_clause, OptTempTableName, relation_name_list,
|
into_clause, OptTempTableName, relation_name_list,
|
||||||
|
@ -323,7 +327,7 @@ static void doNegateFloat(Value *v);
|
||||||
SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
|
SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
|
||||||
TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
|
TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
|
||||||
TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
|
TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
|
||||||
UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING,
|
UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USAGE, USER, USING,
|
||||||
VALUES, VARCHAR, VARYING, VIEW,
|
VALUES, VARCHAR, VARYING, VIEW,
|
||||||
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
|
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
|
||||||
|
|
||||||
|
@ -2327,73 +2331,94 @@ from_in: IN
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* GRANT privileges ON [TABLE] relation_name_list TO [GROUP] grantee, ...
|
* GRANT and REVOKE statements
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
GrantStmt: GRANT privileges ON opt_table relation_name_list TO grantee_list opt_with_grant
|
GrantStmt: GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
|
||||||
{
|
{
|
||||||
GrantStmt *n = makeNode(GrantStmt);
|
GrantStmt *n = makeNode(GrantStmt);
|
||||||
n->is_grant = true;
|
n->is_grant = true;
|
||||||
n->relnames = $5;
|
|
||||||
n->privileges = $2;
|
n->privileges = $2;
|
||||||
n->grantees = $7;
|
n->objtype = ($4)->objtype;
|
||||||
|
n->objects = ($4)->objs;
|
||||||
|
n->grantees = $6;
|
||||||
$$ = (Node*)n;
|
$$ = (Node*)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
privileges: ALL PRIVILEGES
|
RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target FROM grantee_list
|
||||||
{
|
{
|
||||||
$$ = aclmakepriv(ACL_MODE_STR,0);
|
GrantStmt *n = makeNode(GrantStmt);
|
||||||
}
|
n->is_grant = false;
|
||||||
| ALL
|
n->privileges = $3;
|
||||||
{
|
n->objtype = ($5)->objtype;
|
||||||
$$ = aclmakepriv(ACL_MODE_STR,0);
|
n->objects = ($5)->objs;
|
||||||
}
|
n->grantees = $7;
|
||||||
| operation_commalist
|
$$ = (Node *)n;
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
operation_commalist: operation
|
|
||||||
|
/* either ALL [PRIVILEGES] or a list of individual privileges */
|
||||||
|
privileges: privilege_list { $$ = $1; }
|
||||||
|
| ALL { $$ = makeListi1(ALL); }
|
||||||
|
| ALL PRIVILEGES { $$ = makeListi1(ALL); }
|
||||||
|
;
|
||||||
|
|
||||||
|
privilege_list: privilege { $$ = makeListi1($1); }
|
||||||
|
| privilege_list ',' privilege { $$ = lappendi($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Not all of these privilege types apply to all objects, but that
|
||||||
|
gets sorted out later. */
|
||||||
|
privilege: SELECT { $$ = SELECT; }
|
||||||
|
| INSERT { $$ = INSERT; }
|
||||||
|
| UPDATE { $$ = UPDATE; }
|
||||||
|
| DELETE { $$ = DELETE; }
|
||||||
|
| RULE { $$ = RULE; }
|
||||||
|
| REFERENCES { $$ = REFERENCES; }
|
||||||
|
| TRIGGER { $$ = TRIGGER; }
|
||||||
|
| EXECUTE { $$ = EXECUTE; }
|
||||||
|
| USAGE { $$ = USAGE; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/* Don't bother trying to fold the first two rules into one using
|
||||||
|
opt_table. You're going to get conflicts. */
|
||||||
|
privilege_target: relation_name_list
|
||||||
{
|
{
|
||||||
$$ = aclmakepriv("",$1);
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
n->objtype = TABLE;
|
||||||
|
n->objs = $1;
|
||||||
|
$$ = n;
|
||||||
}
|
}
|
||||||
| operation_commalist ',' operation
|
| TABLE relation_name_list
|
||||||
{
|
{
|
||||||
$$ = aclmakepriv($1,$3);
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
n->objtype = TABLE;
|
||||||
|
n->objs = $2;
|
||||||
|
$$ = n;
|
||||||
|
}
|
||||||
|
| FUNCTION function_with_argtypes_list
|
||||||
|
{
|
||||||
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
n->objtype = FUNCTION;
|
||||||
|
n->objs = $2;
|
||||||
|
$$ = n;
|
||||||
|
}
|
||||||
|
| LANGUAGE name_list
|
||||||
|
{
|
||||||
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
n->objtype = LANGUAGE;
|
||||||
|
n->objs = $2;
|
||||||
|
$$ = n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
operation: SELECT
|
|
||||||
{
|
grantee_list: grantee { $$ = makeList1($1); }
|
||||||
$$ = ACL_MODE_SELECT_CHR;
|
| grantee_list ',' grantee { $$ = lappend($1, $3); }
|
||||||
}
|
|
||||||
| INSERT
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_INSERT_CHR;
|
|
||||||
}
|
|
||||||
| UPDATE
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_UPDATE_CHR;
|
|
||||||
}
|
|
||||||
| DELETE
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_DELETE_CHR;
|
|
||||||
}
|
|
||||||
| RULE
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_RULE_CHR;
|
|
||||||
}
|
|
||||||
| REFERENCES
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_REFERENCES_CHR;
|
|
||||||
}
|
|
||||||
| TRIGGER
|
|
||||||
{
|
|
||||||
$$ = ACL_MODE_TRIGGER_CHR;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
grantee: PUBLIC
|
grantee: PUBLIC
|
||||||
|
@ -2419,31 +2444,33 @@ grantee: PUBLIC
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
grantee_list: grantee { $$ = makeList1($1); }
|
|
||||||
| grantee_list ',' grantee { $$ = lappend($1, $3); }
|
|
||||||
|
|
||||||
|
opt_grant_grant_option: WITH GRANT OPTION
|
||||||
opt_with_grant: WITH GRANT OPTION
|
|
||||||
{
|
{
|
||||||
elog(ERROR,"WITH GRANT OPTION is not supported. Only relation owners can set privileges");
|
elog(ERROR, "grant options are not implemented");
|
||||||
}
|
}
|
||||||
|
| /*EMPTY*/
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_revoke_grant_option: GRANT OPTION FOR
|
||||||
|
{
|
||||||
|
elog(ERROR, "grant options are not implemented");
|
||||||
|
}
|
||||||
| /*EMPTY*/
|
| /*EMPTY*/
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
function_with_argtypes_list: function_with_argtypes
|
||||||
*
|
{ $$ = makeList1($1); }
|
||||||
* REVOKE privileges ON [TABLE] relation_name_list FROM user, ...
|
| function_with_argtypes_list ',' function_with_argtypes
|
||||||
*
|
{ $$ = lappend($1, $3); }
|
||||||
*****************************************************************************/
|
;
|
||||||
|
|
||||||
RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
|
function_with_argtypes: func_name func_args
|
||||||
{
|
{
|
||||||
GrantStmt *n = makeNode(GrantStmt);
|
FuncWithArgs *n = makeNode(FuncWithArgs);
|
||||||
n->is_grant = false;
|
n->funcname = $1;
|
||||||
n->relnames = $5;
|
n->funcargs = $2;
|
||||||
n->privileges = $2;
|
|
||||||
n->grantees = $7;
|
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -5876,6 +5903,7 @@ unreserved_keyword:
|
||||||
| UNLISTEN { $$ = "unlisten"; }
|
| UNLISTEN { $$ = "unlisten"; }
|
||||||
| UNTIL { $$ = "until"; }
|
| UNTIL { $$ = "until"; }
|
||||||
| UPDATE { $$ = "update"; }
|
| UPDATE { $$ = "update"; }
|
||||||
|
| USAGE { $$ = "usage"; }
|
||||||
| VACUUM { $$ = "vacuum"; }
|
| VACUUM { $$ = "vacuum"; }
|
||||||
| VALID { $$ = "valid"; }
|
| VALID { $$ = "valid"; }
|
||||||
| VALUES { $$ = "values"; }
|
| VALUES { $$ = "values"; }
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.99 2001/10/10 00:02:42 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.100 2002/02/18 23:11:18 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -269,6 +269,7 @@ static ScanKeyword ScanKeywords[] = {
|
||||||
{"unlisten", UNLISTEN},
|
{"unlisten", UNLISTEN},
|
||||||
{"until", UNTIL},
|
{"until", UNTIL},
|
||||||
{"update", UPDATE},
|
{"update", UPDATE},
|
||||||
|
{"usage", USAGE},
|
||||||
{"user", USER},
|
{"user", USER},
|
||||||
{"using", USING},
|
{"using", USING},
|
||||||
{"vacuum", VACUUM},
|
{"vacuum", VACUUM},
|
||||||
|
@ -354,3 +355,36 @@ ScanKeywordLookup(char *text)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This does the reverse mapping from token number to string.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
TokenString(int token)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
static char buf[NAMEDATALEN];
|
||||||
|
|
||||||
|
while (i < sizeof(ScanKeywords))
|
||||||
|
{
|
||||||
|
if (ScanKeywords[i].value == token)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
|
||||||
|
/* uppercase */
|
||||||
|
for (k = 0; k < NAMEDATALEN; k++)
|
||||||
|
if (ScanKeywords[i].name[k] >= 'a'
|
||||||
|
&& ScanKeywords[i].name[k] <= 'z')
|
||||||
|
buf[k] = ScanKeywords[i].name[k] + ('A' - 'a');
|
||||||
|
else
|
||||||
|
buf[k] = ScanKeywords[i].name[k];
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.20 2001/05/22 12:06:51 momjian Exp $
|
# $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.21 2002/02/18 23:11:20 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ FuNkYfMgRsTuFf
|
||||||
tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $RAWFILE | \
|
tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $RAWFILE | \
|
||||||
$AWK '
|
$AWK '
|
||||||
BEGIN { OFS = ""; }
|
BEGIN { OFS = ""; }
|
||||||
{ if (seenit[$(NF-1)]++ == 0) print "#define F_", $(NF-1), " ", $1; }' >> "$$-$OIDSFILE"
|
{ if (seenit[$(NF-2)]++ == 0) print "#define F_", $(NF-2), " ", $1; }' >> "$$-$OIDSFILE"
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
cleanup
|
cleanup
|
||||||
|
@ -209,7 +209,7 @@ cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
|
||||||
|
|
||||||
FuNkYfMgRtAbStUfF
|
FuNkYfMgRtAbStUfF
|
||||||
|
|
||||||
$AWK '{ print "extern Datum", $(NF-1), "(PG_FUNCTION_ARGS);"; }' $RAWFILE >> "$$-$TABLEFILE"
|
$AWK '{ print "extern Datum", $(NF-2), "(PG_FUNCTION_ARGS);"; }' $RAWFILE >> "$$-$TABLEFILE"
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
cleanup
|
cleanup
|
||||||
|
@ -232,7 +232,7 @@ $AWK 'BEGIN {
|
||||||
Bool["f"] = "false"
|
Bool["f"] = "false"
|
||||||
}
|
}
|
||||||
{ printf (" { %d, \"%s\", %d, %s, %s, %s },\n"), \
|
{ printf (" { %d, \"%s\", %d, %s, %s, %s },\n"), \
|
||||||
$1, $(NF-1), $9, Bool[$8], Bool[$10], $(NF-1)
|
$1, $(NF-2), $9, Bool[$8], Bool[$10], $(NF-2)
|
||||||
}' $RAWFILE >> "$$-$TABLEFILE"
|
}' $RAWFILE >> "$$-$TABLEFILE"
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.66 2001/11/16 23:30:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.67 2002/02/18 23:11:22 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -373,7 +373,7 @@ aclitemgt(const AclItem *a1, const AclItem *a2)
|
||||||
* newly-created tables (or any table with a NULL acl entry in pg_class)
|
* newly-created tables (or any table with a NULL acl entry in pg_class)
|
||||||
*/
|
*/
|
||||||
Acl *
|
Acl *
|
||||||
acldefault(const char *relname, AclId ownerid)
|
acldefault(AclId ownerid)
|
||||||
{
|
{
|
||||||
Acl *acl;
|
Acl *acl;
|
||||||
AclItem *aip;
|
AclItem *aip;
|
||||||
|
@ -381,16 +381,18 @@ acldefault(const char *relname, AclId ownerid)
|
||||||
#define ACL_WORLD_DEFAULT (ACL_NO)
|
#define ACL_WORLD_DEFAULT (ACL_NO)
|
||||||
#define ACL_OWNER_DEFAULT (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
|
#define ACL_OWNER_DEFAULT (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
|
||||||
|
|
||||||
acl = makeacl(2);
|
acl = makeacl(ownerid ? 2 : 1);
|
||||||
aip = ACL_DAT(acl);
|
aip = ACL_DAT(acl);
|
||||||
aip[0].ai_idtype = ACL_IDTYPE_WORLD;
|
aip[0].ai_idtype = ACL_IDTYPE_WORLD;
|
||||||
aip[0].ai_id = ACL_ID_WORLD;
|
aip[0].ai_id = ACL_ID_WORLD;
|
||||||
aip[0].ai_mode = (IsSystemRelationName(relname) &&
|
aip[0].ai_mode = ACL_WORLD_DEFAULT;
|
||||||
!IsToastRelationName(relname)) ? ACL_SELECT
|
/* FIXME: The owner's default should vary with the object type. */
|
||||||
: ACL_WORLD_DEFAULT;
|
if (ownerid)
|
||||||
aip[1].ai_idtype = ACL_IDTYPE_UID;
|
{
|
||||||
aip[1].ai_id = ownerid;
|
aip[1].ai_idtype = ACL_IDTYPE_UID;
|
||||||
aip[1].ai_mode = ACL_OWNER_DEFAULT;
|
aip[1].ai_id = ownerid;
|
||||||
|
aip[1].ai_mode = ACL_OWNER_DEFAULT;
|
||||||
|
}
|
||||||
return acl;
|
return acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.39 2001/10/02 21:39:35 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.40 2002/02/18 23:11:23 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "utils/fcache.h"
|
#include "utils/fcache.h"
|
||||||
|
@ -54,7 +55,7 @@ SetDefine(char *querystr, char *typename)
|
||||||
false, /* don't replace */
|
false, /* don't replace */
|
||||||
true, /* returnsSet */
|
true, /* returnsSet */
|
||||||
typename, /* returnTypeName */
|
typename, /* returnTypeName */
|
||||||
"sql", /* languageName */
|
SQLlanguageId, /* language */
|
||||||
querystr, /* sourceCode */
|
querystr, /* sourceCode */
|
||||||
fileName, /* fileName */
|
fileName, /* fileName */
|
||||||
true, /* trusted */
|
true, /* trusted */
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.41 2001/10/06 23:21:44 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.42 2002/02/18 23:11:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "miscadmin.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/fcache.h"
|
#include "utils/fcache.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,5 +42,7 @@ init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
|
||||||
/* Initialize additional info */
|
/* Initialize additional info */
|
||||||
retval->setArgsValid = false;
|
retval->setArgsValid = false;
|
||||||
|
|
||||||
|
retval->permission_ok = pg_proc_aclcheck(foid, GetUserId()) == ACLCHECK_OK;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.19 2001/09/08 15:24:00 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.20 2002/02/18 23:11:26 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -30,16 +30,23 @@
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
superuser(void)
|
superuser(void)
|
||||||
|
{
|
||||||
|
return superuser_arg(GetUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
superuser_arg(Oid userid)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
HeapTuple utup;
|
HeapTuple utup;
|
||||||
|
|
||||||
/* Special escape path in case you deleted all your users. */
|
/* Special escape path in case you deleted all your users. */
|
||||||
if (!IsUnderPostmaster && GetUserId() == BOOTSTRAP_USESYSID)
|
if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
utup = SearchSysCache(SHADOWSYSID,
|
utup = SearchSysCache(SHADOWSYSID,
|
||||||
ObjectIdGetDatum(GetUserId()),
|
ObjectIdGetDatum(userid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (HeapTupleIsValid(utup))
|
if (HeapTupleIsValid(utup))
|
||||||
{
|
{
|
||||||
|
@ -49,6 +56,7 @@ superuser(void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Postgres user running this command is the owner of the specified
|
* The Postgres user running this command is the owner of the specified
|
||||||
* database.
|
* database.
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# Portions Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.142 2001/11/25 22:19:30 petere Exp $
|
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.143 2002/02/18 23:11:28 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -833,6 +833,24 @@ EOF
|
||||||
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
|
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
|
||||||
|
# Set most system catalogs and built-in functions as world-accessible.
|
||||||
|
# Some objects may require different permissions by default, so we
|
||||||
|
# make sure we don't overwrite privilege sets that have already been
|
||||||
|
# set (NOT NULL).
|
||||||
|
$ECHO_N "setting privileges on built-in objects... "$ECHO_C
|
||||||
|
(
|
||||||
|
cat <<EOF
|
||||||
|
UPDATE pg_class SET relacl = '{"=r"}' \
|
||||||
|
WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL;
|
||||||
|
UPDATE pg_proc SET proacl = '{"=r"}' \
|
||||||
|
WHERE proacl IS NULL;
|
||||||
|
UPDATE pg_language SET lanacl = '{"=r"}' \
|
||||||
|
WHERE lanpltrusted;
|
||||||
|
EOF
|
||||||
|
) \
|
||||||
|
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
|
||||||
|
echo "ok"
|
||||||
|
|
||||||
$ECHO_N "vacuuming database template1... "$ECHO_C
|
$ECHO_N "vacuuming database template1... "$ECHO_C
|
||||||
|
|
||||||
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
|
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# Portions Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.33 2002/02/18 05:48:44 momjian Exp $
|
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.34 2002/02/18 23:11:30 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -289,4 +289,15 @@ if [ "$?" -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -n "$trusted"; then
|
||||||
|
sqlcmd="GRANT USAGE ON LANGUAGE \"$langname\" TO PUBLIC;"
|
||||||
|
if [ "$showsql" = yes ]; then
|
||||||
|
echo "$sqlcmd"
|
||||||
|
fi
|
||||||
|
$PSQL "$sqlcmd"
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo "$CMDNAME: language installation failed" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: catversion.h,v 1.103 2002/01/12 18:09:04 tgl Exp $
|
* $Id: catversion.h,v 1.104 2002/02/18 23:11:32 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -53,6 +53,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200201121
|
#define CATALOG_VERSION_NO 200202181
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_attribute.h,v 1.79 2001/11/05 17:46:32 momjian Exp $
|
* $Id: pg_attribute.h,v 1.80 2002/02/18 23:11:33 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -310,7 +310,8 @@ DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
|
||||||
{ 1255, {"propercall_cpu"}, 23, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"propercall_cpu"}, 23, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"prooutin_ratio"}, 23, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1255, {"prooutin_ratio"}, 23, 0, 4, 15, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1255, {"prosrc"}, 25, 0, -1, 16, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
{ 1255, {"prosrc"}, 25, 0, -1, 16, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||||
{ 1255, {"probin"}, 17, 0, -1, 17, 0, -1, -1, false, 'x', false, 'i', false, false }
|
{ 1255, {"probin"}, 17, 0, -1, 17, 0, -1, -1, false, 'x', false, 'i', false, false }, \
|
||||||
|
{ 1255, {"proacl"}, 1034, 0, -1, 18, 0, -1, -1, false, 'x', false, 'i', false, false }
|
||||||
|
|
||||||
DATA(insert ( 1255 proname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
DATA(insert ( 1255 proname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert ( 1255 proowner 23 0 4 2 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 proowner 23 0 4 2 0 -1 -1 t p f i f f));
|
||||||
|
@ -329,6 +330,7 @@ DATA(insert ( 1255 propercall_cpu 23 0 4 14 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 prooutin_ratio 23 0 4 15 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 prooutin_ratio 23 0 4 15 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 prosrc 25 0 -1 16 0 -1 -1 f x f i f f));
|
DATA(insert ( 1255 prosrc 25 0 -1 16 0 -1 -1 f x f i f f));
|
||||||
DATA(insert ( 1255 probin 17 0 -1 17 0 -1 -1 f x f i f f));
|
DATA(insert ( 1255 probin 17 0 -1 17 0 -1 -1 f x f i f f));
|
||||||
|
DATA(insert ( 1255 proacl 1034 0 -1 18 0 -1 -1 f x f i f f));
|
||||||
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_class.h,v 1.57 2001/11/05 17:46:32 momjian Exp $
|
* $Id: pg_class.h,v 1.58 2002/02/18 23:11:34 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -136,7 +136,7 @@ DATA(insert OID = 1247 ( pg_type 71 PGUID 0 1247 0 0 0 0 f f r 17 0 0 0 0 0 t
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1249 ( pg_attribute 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
|
DATA(insert OID = 1249 ( pg_attribute 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 1255 0 0 0 0 f f r 17 0 0 0 0 0 t f f f _null_ ));
|
DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 1255 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1259 ( pg_class 83 PGUID 0 1259 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ ));
|
DATA(insert OID = 1259 ( pg_class 83 PGUID 0 1259 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_language.h,v 1.15 2001/11/05 17:46:32 momjian Exp $
|
* $Id: pg_language.h,v 1.16 2002/02/18 23:11:35 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
|
@ -38,6 +38,7 @@ CATALOG(pg_language)
|
||||||
bool lanpltrusted; /* PL is trusted */
|
bool lanpltrusted; /* PL is trusted */
|
||||||
Oid lanplcallfoid; /* Call handler for PL */
|
Oid lanplcallfoid; /* Call handler for PL */
|
||||||
text lancompiler; /* VARIABLE LENGTH FIELD */
|
text lancompiler; /* VARIABLE LENGTH FIELD */
|
||||||
|
aclitem lanacl[1]; /* Access privileges */
|
||||||
} FormData_pg_language;
|
} FormData_pg_language;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
@ -51,25 +52,26 @@ typedef FormData_pg_language *Form_pg_language;
|
||||||
* compiler constants for pg_language
|
* compiler constants for pg_language
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_language 5
|
#define Natts_pg_language 6
|
||||||
#define Anum_pg_language_lanname 1
|
#define Anum_pg_language_lanname 1
|
||||||
#define Anum_pg_language_lanispl 2
|
#define Anum_pg_language_lanispl 2
|
||||||
#define Anum_pg_language_lanpltrusted 3
|
#define Anum_pg_language_lanpltrusted 3
|
||||||
#define Anum_pg_language_lanplcallfoid 4
|
#define Anum_pg_language_lanplcallfoid 4
|
||||||
#define Anum_pg_language_lancompiler 5
|
#define Anum_pg_language_lancompiler 5
|
||||||
|
#define Anum_pg_language_lanacl 6
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_language
|
* initial contents of pg_language
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert OID = 12 ( internal f f 0 "n/a" ));
|
DATA(insert OID = 12 ( "internal" f f 0 "n/a" _null_ ));
|
||||||
DESCR("Built-in functions");
|
DESCR("Built-in functions");
|
||||||
#define INTERNALlanguageId 12
|
#define INTERNALlanguageId 12
|
||||||
DATA(insert OID = 13 ( "C" f f 0 "/bin/cc" ));
|
DATA(insert OID = 13 ( "c" f f 0 "/bin/cc" _null_ ));
|
||||||
DESCR("Dynamically-loaded C functions");
|
DESCR("Dynamically-loaded C functions");
|
||||||
#define ClanguageId 13
|
#define ClanguageId 13
|
||||||
DATA(insert OID = 14 ( "sql" f f 0 "postgres"));
|
DATA(insert OID = 14 ( "sql" f t 0 "postgres" _null_ ));
|
||||||
DESCR("SQL-language functions");
|
DESCR("SQL-language functions");
|
||||||
#define SQLlanguageId 14
|
#define SQLlanguageId 14
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,7 +12,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: miscadmin.h,v 1.98 2002/01/01 23:16:22 tgl Exp $
|
* $Id: miscadmin.h,v 1.99 2002/02/18 23:11:31 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* some of the information in this file should be moved to
|
* some of the information in this file should be moved to
|
||||||
|
@ -227,6 +227,7 @@ extern char *convertstr(unsigned char *buff, int len, int dest);
|
||||||
|
|
||||||
/* in utils/misc/superuser.c */
|
/* in utils/misc/superuser.c */
|
||||||
extern bool superuser(void); /* current user is superuser */
|
extern bool superuser(void); /* current user is superuser */
|
||||||
|
extern bool superuser_arg(Oid userid); /* given user is superuser */
|
||||||
extern bool is_dbadmin(Oid dbid); /* current user is owner of
|
extern bool is_dbadmin(Oid dbid); /* current user is owner of
|
||||||
* database */
|
* database */
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: nodes.h,v 1.96 2001/11/05 17:46:34 momjian Exp $
|
* $Id: nodes.h,v 1.97 2002/02/18 23:11:41 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -222,6 +222,8 @@ typedef enum NodeTag
|
||||||
T_CaseWhen,
|
T_CaseWhen,
|
||||||
T_FkConstraint,
|
T_FkConstraint,
|
||||||
T_PrivGrantee,
|
T_PrivGrantee,
|
||||||
|
T_FuncWithArgs,
|
||||||
|
T_PrivTarget,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
|
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: parsenodes.h,v 1.151 2001/11/05 17:46:34 momjian Exp $
|
* $Id: parsenodes.h,v 1.152 2002/02/18 23:11:41 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -145,8 +145,9 @@ typedef struct GrantStmt
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
bool is_grant; /* not revoke */
|
bool is_grant; /* not revoke */
|
||||||
List *relnames;
|
int objtype;
|
||||||
char *privileges;
|
List *objects;
|
||||||
|
List *privileges;
|
||||||
List *grantees;
|
List *grantees;
|
||||||
} GrantStmt;
|
} GrantStmt;
|
||||||
|
|
||||||
|
@ -159,6 +160,23 @@ typedef struct PrivGrantee
|
||||||
} PrivGrantee;
|
} PrivGrantee;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct FuncWithArgs
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
char *funcname;
|
||||||
|
List *funcargs;
|
||||||
|
} FuncWithArgs;
|
||||||
|
|
||||||
|
|
||||||
|
/* This is only used internally in gram.y. */
|
||||||
|
typedef struct PrivTarget
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
int objtype;
|
||||||
|
List *objs;
|
||||||
|
} PrivTarget;
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
* Close Portal Statement
|
* Close Portal Statement
|
||||||
* ----------------------
|
* ----------------------
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: keywords.h,v 1.12 2001/11/05 17:46:34 momjian Exp $
|
* $Id: keywords.h,v 1.13 2002/02/18 23:11:45 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -21,5 +21,6 @@ typedef struct ScanKeyword
|
||||||
} ScanKeyword;
|
} ScanKeyword;
|
||||||
|
|
||||||
extern ScanKeyword *ScanKeywordLookup(char *text);
|
extern ScanKeyword *ScanKeywordLookup(char *text);
|
||||||
|
extern const char *TokenString(int token);
|
||||||
|
|
||||||
#endif /* KEYWORDS_H */
|
#endif /* KEYWORDS_H */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: acl.h,v 1.39 2001/11/05 17:46:36 momjian Exp $
|
* $Id: acl.h,v 1.40 2002/02/18 23:11:45 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* For backward-compatibility purposes we have to allow there
|
* For backward-compatibility purposes we have to allow there
|
||||||
|
@ -171,7 +171,7 @@ extern char *aclcheck_error_strings[];
|
||||||
/*
|
/*
|
||||||
* routines used internally
|
* routines used internally
|
||||||
*/
|
*/
|
||||||
extern Acl *acldefault(const char *relname, AclId ownerid);
|
extern Acl *acldefault(AclId ownerid);
|
||||||
extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg);
|
extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -208,4 +208,7 @@ extern bool pg_func_ownercheck(Oid userid, char *funcname,
|
||||||
extern bool pg_aggr_ownercheck(Oid userid, char *aggname,
|
extern bool pg_aggr_ownercheck(Oid userid, char *aggname,
|
||||||
Oid basetypeID);
|
Oid basetypeID);
|
||||||
|
|
||||||
|
extern int32 pg_proc_aclcheck(Oid proc_oid, Oid userid);
|
||||||
|
extern int32 pg_language_aclcheck(Oid lang_oid, Oid userid);
|
||||||
|
|
||||||
#endif /* ACL_H */
|
#endif /* ACL_H */
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: fcache.h,v 1.20 2001/11/05 17:46:36 momjian Exp $
|
* $Id: fcache.h,v 1.21 2002/02/18 23:11:46 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,8 @@ typedef struct FunctionCache
|
||||||
*/
|
*/
|
||||||
FmgrInfo func;
|
FmgrInfo func;
|
||||||
|
|
||||||
|
bool permission_ok;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setArgsValid is true when we are evaluating a set-valued function
|
* setArgsValid is true when we are evaluating a set-valued function
|
||||||
* and we are in the middle of a call series; we want to pass the same
|
* and we are in the middle of a call series; we want to pass the same
|
||||||
|
|
|
@ -188,6 +188,49 @@ SELECT * FROM atestv3; -- ok
|
||||||
-----+-----+-------
|
-----+-----+-------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
-- privileges on functions, languages
|
||||||
|
-- switch to superuser
|
||||||
|
\c -
|
||||||
|
REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC;
|
||||||
|
GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok
|
||||||
|
GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
|
||||||
|
ERROR: language "c" is not trusted
|
||||||
|
SET SESSION AUTHORIZATION regressuser1;
|
||||||
|
GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
|
||||||
|
ERROR: permission denied
|
||||||
|
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
|
||||||
|
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
|
||||||
|
GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
|
||||||
|
GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
|
||||||
|
ERROR: invalid privilege type USAGE for function object
|
||||||
|
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
|
||||||
|
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
|
||||||
|
ERROR: Function 'testfunc_nosuch(int4)' does not exist
|
||||||
|
SET SESSION AUTHORIZATION regressuser2;
|
||||||
|
SELECT testfunc1(5), testfunc2(5); -- ok
|
||||||
|
testfunc1 | testfunc2
|
||||||
|
-----------+-----------
|
||||||
|
10 | 15
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
|
||||||
|
ERROR: permission denied
|
||||||
|
SET SESSION AUTHORIZATION regressuser3;
|
||||||
|
SELECT testfunc1(5); -- fail
|
||||||
|
ERROR: permission denied
|
||||||
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
|
SELECT testfunc1(5); -- ok
|
||||||
|
testfunc1
|
||||||
|
-----------
|
||||||
|
10
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP FUNCTION testfunc1(int); -- fail
|
||||||
|
ERROR: RemoveFunction: function 'testfunc1': permission denied
|
||||||
|
\c -
|
||||||
|
DROP FUNCTION testfunc1(int); -- ok
|
||||||
|
-- restore to sanity
|
||||||
|
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
||||||
-- has_table_privilege function
|
-- has_table_privilege function
|
||||||
-- bad-input checks
|
-- bad-input checks
|
||||||
select has_table_privilege(NULL,'pg_shadow','select');
|
select has_table_privilege(NULL,'pg_shadow','select');
|
||||||
|
@ -207,7 +250,7 @@ ERROR: pg_aclcheck: invalid user id 4293967297
|
||||||
select has_table_privilege(1,'rule');
|
select has_table_privilege(1,'rule');
|
||||||
ERROR: has_table_privilege: invalid relation oid 1
|
ERROR: has_table_privilege: invalid relation oid 1
|
||||||
-- superuser
|
-- superuser
|
||||||
\c regression
|
\c -
|
||||||
select has_table_privilege(current_user,'pg_shadow','select');
|
select has_table_privilege(current_user,'pg_shadow','select');
|
||||||
has_table_privilege
|
has_table_privilege
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
@ -126,6 +126,42 @@ SELECT * FROM atestv1; -- ok
|
||||||
SELECT * FROM atestv3; -- ok
|
SELECT * FROM atestv3; -- ok
|
||||||
|
|
||||||
|
|
||||||
|
-- privileges on functions, languages
|
||||||
|
|
||||||
|
-- switch to superuser
|
||||||
|
\c -
|
||||||
|
REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC;
|
||||||
|
GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok
|
||||||
|
GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION regressuser1;
|
||||||
|
GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
|
||||||
|
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
|
||||||
|
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
|
||||||
|
GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
|
||||||
|
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
|
||||||
|
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION regressuser2;
|
||||||
|
SELECT testfunc1(5), testfunc2(5); -- ok
|
||||||
|
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION regressuser3;
|
||||||
|
SELECT testfunc1(5); -- fail
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
|
SELECT testfunc1(5); -- ok
|
||||||
|
|
||||||
|
DROP FUNCTION testfunc1(int); -- fail
|
||||||
|
|
||||||
|
\c -
|
||||||
|
DROP FUNCTION testfunc1(int); -- ok
|
||||||
|
-- restore to sanity
|
||||||
|
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
|
||||||
|
|
||||||
|
|
||||||
-- has_table_privilege function
|
-- has_table_privilege function
|
||||||
|
|
||||||
-- bad-input checks
|
-- bad-input checks
|
||||||
|
@ -137,7 +173,7 @@ select has_table_privilege(-999999,'pg_shadow','update');
|
||||||
select has_table_privilege(1,'rule');
|
select has_table_privilege(1,'rule');
|
||||||
|
|
||||||
-- superuser
|
-- superuser
|
||||||
\c regression
|
\c -
|
||||||
select has_table_privilege(current_user,'pg_shadow','select');
|
select has_table_privilege(current_user,'pg_shadow','select');
|
||||||
select has_table_privilege(current_user,'pg_shadow','insert');
|
select has_table_privilege(current_user,'pg_shadow','insert');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue