Allow functions to be executed with the privileges of the function owner.

I took the opportunity to remove the pg_proc.proistrusted field.
This commit is contained in:
Peter Eisentraut 2002-05-18 13:48:01 +00:00
parent 51fd22abdd
commit e8ac187c68
16 changed files with 1491 additions and 1376 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.97 2002/05/13 19:22:06 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.98 2002/05/18 13:47:59 petere Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -4260,14 +4260,14 @@ SELECT NULLIF(value, '(none)') ...
</indexterm> </indexterm>
<para> <para>
The <function>session_user</> is the user that initiated a database The <function>session_user</> is the user that initiated a
connection; it is fixed for the duration of that connection. The database connection; it is fixed for the duration of that
<function>current_user</> is the user identifier that is applicable connection. The <function>current_user</> is the user identifier
for permission checking. Currently it is always equal to the session that is applicable for permission checking. Normally, it is equal
user, but in the future there might be <quote>setuid</> functions and to the session user, but it changes during the execution of
other facilities to allow the current user to change temporarily. functions with the attribute <literal>SECURITY DEFINER</literal>.
In Unix parlance, the session user is the <quote>real user</> In Unix parlance, the session user is the <quote>real user</> and
and the current user is the <quote>effective user</>. the current user is the <quote>effective user</>.
</para> </para>
<note> <note>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.38 2002/05/17 18:32:52 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.39 2002/05/18 13:47:59 petere Exp $
--> -->
<refentry id="SQL-CREATEFUNCTION"> <refentry id="SQL-CREATEFUNCTION">
@ -21,6 +21,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
| IMMUTABLE | STABLE | VOLATILE | IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| IMPLICIT CAST | IMPLICIT CAST
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
| AS '<replaceable class="parameter">definition</replaceable>' | AS '<replaceable class="parameter">definition</replaceable>'
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>' | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
} ... } ...
@ -199,6 +200,27 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><optional>EXTERNAL</optional> SECURITY INVOKER</term>
<term><optional>EXTERNAL</optional> SECURITY DEFINER</term>
<listitem>
<para>
<literal>SECURITY INVOKER</literal> indicates that the function
is to be executed with the privileges of the user that calls it.
That is the default. <literal>SECURITY DEFINER</literal>
specifies that the function is to be executed with the
privileges of the user that created it.
</para>
<para>
The key word <literal>EXTERNAL</literal> is present for SQL
compatibility but is optional since, unlike in SQL, this feature
does not only apply to external functions.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">definition</replaceable></term> <term><replaceable class="parameter">definition</replaceable></term>
@ -372,7 +394,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para> </para>
</refsect1> </refsect1>
<refsect1 id="sql-createfunction-cast-function"> <refsect1 id="sql-createfunction-cast-functions">
<title id="sql-createfunction-cast-functions-title"> <title id="sql-createfunction-cast-functions-title">
Type Cast Functions Type Cast Functions
</title> </title>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.136 2002/05/17 18:32:52 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.137 2002/05/18 13:47:59 petere Exp $
--> -->
<appendix id="release"> <appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
Functions can be executed with the privileges of the owner
Syntax of CREATE FUNCTION has been extended to resemble SQL99 Syntax of CREATE FUNCTION has been extended to resemble SQL99
Effects of SET within a transaction block now roll back if transaction aborts Effects of SET within a transaction block now roll back if transaction aborts
New SET LOCAL syntax sets a parameter for the life of the current transaction New SET LOCAL syntax sets a parameter for the life of the current transaction

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.45 2002/05/17 22:35:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.46 2002/05/18 13:47:59 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -139,7 +139,7 @@ AggregateCreate(const char *aggName,
"aggregate_dummy", /* placeholder proc */ "aggregate_dummy", /* placeholder proc */
"-", /* probin */ "-", /* probin */
true, /* isAgg */ true, /* isAgg */
true, /* (obsolete "trusted") */ false, /* security invoker (currently not definable for agg) */
false, /* isImplicit */ false, /* isImplicit */
false, /* isStrict (not needed for agg) */ false, /* isStrict (not needed for agg) */
PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */ PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.71 2002/05/17 22:35:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.72 2002/05/18 13:47:59 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -48,7 +48,7 @@ ProcedureCreate(const char *procedureName,
const char *prosrc, const char *prosrc,
const char *probin, const char *probin,
bool isAgg, bool isAgg,
bool trusted, bool security_definer,
bool isImplicit, bool isImplicit,
bool isStrict, bool isStrict,
char volatility, char volatility,
@ -220,7 +220,7 @@ ProcedureCreate(const char *procedureName,
values[i++] = Int32GetDatum(GetUserId()); /* proowner */ values[i++] = Int32GetDatum(GetUserId()); /* proowner */
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */ values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
values[i++] = BoolGetDatum(isAgg); /* proisagg */ values[i++] = BoolGetDatum(isAgg); /* proisagg */
values[i++] = BoolGetDatum(trusted); /* proistrusted */ values[i++] = BoolGetDatum(security_definer); /* prosecdef */
values[i++] = BoolGetDatum(isImplicit); /* proimplicit */ values[i++] = BoolGetDatum(isImplicit); /* proimplicit */
values[i++] = BoolGetDatum(isStrict); /* proisstrict */ values[i++] = BoolGetDatum(isStrict); /* proisstrict */
values[i++] = BoolGetDatum(returnsSet); /* proretset */ values[i++] = BoolGetDatum(returnsSet); /* proretset */

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.4 2002/05/17 18:32:52 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.5 2002/05/18 13:47:59 petere Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
@ -421,6 +421,7 @@ CreateFunction(CreateFunctionStmt *stmt)
outin_ratio = OUTIN_RATIO; outin_ratio = OUTIN_RATIO;
isImplicit = false; isImplicit = false;
isStrict = false; isStrict = false;
security = false;
volatility = PROVOLATILE_VOLATILE; volatility = PROVOLATILE_VOLATILE;
/* override attributes from explicit list */ /* override attributes from explicit list */
@ -489,7 +490,7 @@ CreateFunction(CreateFunctionStmt *stmt)
prosrc_str, /* converted to text later */ prosrc_str, /* converted to text later */
probin_str, /* converted to text later */ probin_str, /* converted to text later */
false, /* not an aggregate */ false, /* not an aggregate */
true, /* (obsolete "trusted") */ security,
isImplicit, isImplicit,
isStrict, isStrict,
volatility, volatility,

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.43 2002/04/11 20:00:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.44 2002/05/18 13:47:59 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -61,7 +61,7 @@ SetDefine(char *querystr, Oid elemType)
querystr, /* prosrc */ querystr, /* prosrc */
fileName, /* probin */ fileName, /* probin */
false, /* not aggregate */ false, /* not aggregate */
true, /* trusted */ false, /* security invoker */
false, /* not implicit coercion */ false, /* not implicit coercion */
false, /* isStrict (irrelevant, no args) */ false, /* isStrict (irrelevant, no args) */
PROVOLATILE_VOLATILE, /* assume unsafe */ PROVOLATILE_VOLATILE, /* assume unsafe */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.58 2002/03/05 05:33:20 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.59 2002/05/18 13:47:59 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -19,6 +19,7 @@
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "executor/functions.h" #include "executor/functions.h"
#include "miscadmin.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgrtab.h" #include "utils/fmgrtab.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
@ -56,10 +57,12 @@ typedef struct
} Oldstyle_fnextra; } Oldstyle_fnextra;
static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
bool ignore_security);
static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple); static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple); static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS); static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
static Datum fmgr_untrusted(PG_FUNCTION_ARGS); static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
/* /*
@ -135,6 +138,18 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
*/ */
void void
fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt) fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
{
fmgr_info_cxt_security(functionId, finfo, mcxt, false);
}
/*
* This one does the actual work. ignore_security is ordinarily false
* but is set to true by fmgr_security_definer to avoid infinite
* recursive lookups.
*/
static void
fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
bool ignore_security)
{ {
const FmgrBuiltin *fbp; const FmgrBuiltin *fbp;
HeapTuple procedureTuple; HeapTuple procedureTuple;
@ -177,10 +192,9 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
finfo->fn_strict = procedureStruct->proisstrict; finfo->fn_strict = procedureStruct->proisstrict;
finfo->fn_retset = procedureStruct->proretset; finfo->fn_retset = procedureStruct->proretset;
if (!procedureStruct->proistrusted) if (procedureStruct->prosecdef && !ignore_security)
{ {
/* This isn't really supported anymore... */ finfo->fn_addr = fmgr_security_definer;
finfo->fn_addr = fmgr_untrusted;
finfo->fn_oid = functionId; finfo->fn_oid = functionId;
ReleaseSysCache(procedureTuple); ReleaseSysCache(procedureTuple);
return; return;
@ -620,17 +634,63 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
/* /*
* Handler for all functions marked "untrusted" * Support for security definer functions
*/
struct fmgr_security_definer_cache
{
FmgrInfo flinfo;
Oid userid;
};
/*
* Function handler for security definer functions. We extract the
* OID of the actual function and do a fmgr lookup again. Then we
* look up the owner of the function and cache both the fmgr info and
* the owner ID. During the call we temporarily replace the flinfo
* with the cached/looked-up one, while keeping the outer fcinfo
* (which contains all the actual arguments, etc.) intact.
*/ */
static Datum static Datum
fmgr_untrusted(PG_FUNCTION_ARGS) fmgr_security_definer(PG_FUNCTION_ARGS)
{ {
/* Datum result;
* Currently these are unsupported. Someday we might do something FmgrInfo *save_flinfo;
* like forking a subprocess to execute 'em. struct fmgr_security_definer_cache *fcache;
*/ Oid save_userid;
elog(ERROR, "Untrusted functions not supported"); HeapTuple tuple;
return 0; /* keep compiler happy */
if (!fcinfo->flinfo->fn_extra)
{
fcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*fcache));
memset(fcache, 0, sizeof(*fcache));
fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
fcinfo->flinfo->fn_mcxt, true);
tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(fcinfo->flinfo->fn_oid), 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "fmgr_security_definer: function %u: cache lookup failed",
fcinfo->flinfo->fn_oid);
fcache->userid = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
ReleaseSysCache(tuple);
fcinfo->flinfo->fn_extra = fcache;
}
else
fcache = fcinfo->flinfo->fn_extra;
save_flinfo = fcinfo->flinfo;
fcinfo->flinfo = &fcache->flinfo;
save_userid = GetUserId();
SetUserId(fcache->userid);
result = FunctionCallInvoke(fcinfo);
SetUserId(save_userid);
fcinfo->flinfo = save_flinfo;
return result;
} }

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.261 2002/05/17 18:32:52 petere Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.262 2002/05/18 13:48:00 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -3216,6 +3216,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
char *provolatile; char *provolatile;
char *proimplicit; char *proimplicit;
char *proisstrict; char *proisstrict;
char *prosecdef;
char *lanname; char *lanname;
char *rettypename; char *rettypename;
@ -3232,7 +3233,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, " "SELECT proretset, prosrc, probin, "
"provolatile, proimplicit, proisstrict, " "provolatile, proimplicit, proisstrict, prosecdef, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname " "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc " "FROM pg_proc "
"WHERE oid = '%s'::oid", "WHERE oid = '%s'::oid",
@ -3245,6 +3246,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
"case when proiscachable then 'i' else 'v' end as provolatile, " "case when proiscachable then 'i' else 'v' end as provolatile, "
"'f'::boolean as proimplicit, " "'f'::boolean as proimplicit, "
"proisstrict, " "proisstrict, "
"'f'::boolean as prosecdef, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname " "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc " "FROM pg_proc "
"WHERE oid = '%s'::oid", "WHERE oid = '%s'::oid",
@ -3257,6 +3259,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
"case when proiscachable then 'i' else 'v' end as provolatile, " "case when proiscachable then 'i' else 'v' end as provolatile, "
"'f'::boolean as proimplicit, " "'f'::boolean as proimplicit, "
"'f'::boolean as proisstrict, " "'f'::boolean as proisstrict, "
"'f'::boolean as prosecdef, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname " "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc " "FROM pg_proc "
"WHERE oid = '%s'::oid", "WHERE oid = '%s'::oid",
@ -3287,6 +3290,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile")); provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
proimplicit = PQgetvalue(res, 0, PQfnumber(res, "proimplicit")); proimplicit = PQgetvalue(res, 0, PQfnumber(res, "proimplicit"));
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict")); proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname")); lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
/* /*
@ -3358,6 +3362,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
if (proisstrict[0] == 't') if (proisstrict[0] == 't')
appendPQExpBuffer(q, " STRICT"); appendPQExpBuffer(q, " STRICT");
if (prosecdef[0] == 't')
appendPQExpBuffer(q, " SECURITY DEFINER");
appendPQExpBuffer(q, ";\n"); appendPQExpBuffer(q, ";\n");
ArchiveEntry(fout, finfo->oid, fn->data, finfo->pronamespace->nspname, ArchiveEntry(fout, finfo->oid, fn->data, finfo->pronamespace->nspname,

View File

@ -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.131 2002/05/12 23:43:03 tgl Exp $ * $Id: catversion.h,v 1.132 2002/05/18 13:48:00 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200205122 #define CATALOG_VERSION_NO 200205181
#endif #endif

View File

@ -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.91 2002/04/21 00:26:43 tgl Exp $ * $Id: pg_attribute.h,v 1.92 2002/05/18 13:48:00 petere Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -300,7 +300,7 @@ DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
{ 1255, {"proowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \ { 1255, {"proowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"prolang"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \ { 1255, {"prolang"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"proisagg"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1255, {"proisagg"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proistrusted"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1255, {"prosecdef"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proimplicit"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1255, {"proimplicit"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proisstrict"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1255, {"proisstrict"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proretset"}, 16, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \ { 1255, {"proretset"}, 16, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \
@ -321,7 +321,7 @@ DATA(insert ( 1255 pronamespace 26 0 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proowner 23 0 4 3 0 -1 -1 t p f i f f)); DATA(insert ( 1255 proowner 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1255 prolang 26 0 4 4 0 -1 -1 t p f i f f)); DATA(insert ( 1255 prolang 26 0 4 4 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proisagg 16 0 1 5 0 -1 -1 t p f c f f)); DATA(insert ( 1255 proisagg 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proistrusted 16 0 1 6 0 -1 -1 t p f c f f)); DATA(insert ( 1255 prosecdef 16 0 1 6 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proimplicit 16 0 1 7 0 -1 -1 t p f c f f)); DATA(insert ( 1255 proimplicit 16 0 1 7 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proisstrict 16 0 1 8 0 -1 -1 t p f c f f)); DATA(insert ( 1255 proisstrict 16 0 1 8 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proretset 16 0 1 9 0 -1 -1 t p f c f f)); DATA(insert ( 1255 proretset 16 0 1 9 0 -1 -1 t p f c f f));

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ WHERE p1.oid != p2.oid AND
p1.prolang = 12 AND p2.prolang = 12 AND p1.prolang = 12 AND p2.prolang = 12 AND
(p1.prolang != p2.prolang OR (p1.prolang != p2.prolang OR
p1.proisagg != p2.proisagg OR p1.proisagg != p2.proisagg OR
p1.proistrusted != p2.proistrusted OR p1.prosecdef != p2.prosecdef OR
p1.proisstrict != p2.proisstrict OR p1.proisstrict != p2.proisstrict OR
p1.proretset != p2.proretset OR p1.proretset != p2.proretset OR
p1.provolatile != p2.provolatile OR p1.provolatile != p2.provolatile OR

View File

@ -206,6 +206,10 @@ ERROR: invalid privilege type USAGE for function object
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4; GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4; GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
ERROR: GRANT: function testfunc_nosuch(integer) does not exist ERROR: GRANT: function testfunc_nosuch(integer) does not exist
CREATE FUNCTION testfunc4(boolean) RETURNS text
AS 'select col1 from atest2 where col2 = $1;'
LANGUAGE sql SECURITY DEFINER;
GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regressuser3;
SET SESSION AUTHORIZATION regressuser2; SET SESSION AUTHORIZATION regressuser2;
SELECT testfunc1(5), testfunc2(5); -- ok SELECT testfunc1(5), testfunc2(5); -- ok
testfunc1 | testfunc2 testfunc1 | testfunc2
@ -218,6 +222,14 @@ ERROR: sql: permission denied
SET SESSION AUTHORIZATION regressuser3; SET SESSION AUTHORIZATION regressuser3;
SELECT testfunc1(5); -- fail SELECT testfunc1(5); -- fail
ERROR: testfunc1: permission denied ERROR: testfunc1: permission denied
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
ERROR: atest2: permission denied
SELECT testfunc4(true); -- ok
testfunc4
-----------
bar
(1 row)
SET SESSION AUTHORIZATION regressuser4; SET SESSION AUTHORIZATION regressuser4;
SELECT testfunc1(5); -- ok SELECT testfunc1(5); -- ok
testfunc1 testfunc1
@ -501,6 +513,8 @@ from (select oid from pg_class where relname = 'atest1') as t1;
-- clean up -- clean up
\c regression \c regression
DROP FUNCTION testfunc2(int);
DROP FUNCTION testfunc4(boolean);
DROP TABLE atest1; DROP TABLE atest1;
DROP TABLE atest2; DROP TABLE atest2;
DROP TABLE atest3; DROP TABLE atest3;

View File

@ -54,7 +54,7 @@ WHERE p1.oid != p2.oid AND
p1.prolang = 12 AND p2.prolang = 12 AND p1.prolang = 12 AND p2.prolang = 12 AND
(p1.prolang != p2.prolang OR (p1.prolang != p2.prolang OR
p1.proisagg != p2.proisagg OR p1.proisagg != p2.proisagg OR
p1.proistrusted != p2.proistrusted OR p1.prosecdef != p2.prosecdef OR
p1.proisstrict != p2.proisstrict OR p1.proisstrict != p2.proisstrict OR
p1.proretset != p2.proretset OR p1.proretset != p2.proretset OR
p1.provolatile != p2.provolatile OR p1.provolatile != p2.provolatile OR

View File

@ -144,12 +144,19 @@ GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4; GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4; GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regressuser4;
CREATE FUNCTION testfunc4(boolean) RETURNS text
AS 'select col1 from atest2 where col2 = $1;'
LANGUAGE sql SECURITY DEFINER;
GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regressuser3;
SET SESSION AUTHORIZATION regressuser2; SET SESSION AUTHORIZATION regressuser2;
SELECT testfunc1(5), testfunc2(5); -- ok SELECT testfunc1(5), testfunc2(5); -- ok
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
SET SESSION AUTHORIZATION regressuser3; SET SESSION AUTHORIZATION regressuser3;
SELECT testfunc1(5); -- fail SELECT testfunc1(5); -- fail
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
SELECT testfunc4(true); -- ok
SET SESSION AUTHORIZATION regressuser4; SET SESSION AUTHORIZATION regressuser4;
SELECT testfunc1(5); -- ok SELECT testfunc1(5); -- ok
@ -265,6 +272,9 @@ from (select oid from pg_class where relname = 'atest1') as t1;
-- clean up -- clean up
\c regression \c regression
DROP FUNCTION testfunc2(int);
DROP FUNCTION testfunc4(boolean);
DROP TABLE atest1; DROP TABLE atest1;
DROP TABLE atest2; DROP TABLE atest2;
DROP TABLE atest3; DROP TABLE atest3;