mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
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:
parent
51fd22abdd
commit
e8ac187c68
@ -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
|
||||
-->
|
||||
|
||||
@ -4260,14 +4260,14 @@ SELECT NULLIF(value, '(none)') ...
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The <function>session_user</> is the user that initiated a database
|
||||
connection; it is fixed for the duration of that connection. The
|
||||
<function>current_user</> is the user identifier that is applicable
|
||||
for permission checking. Currently it is always equal to the session
|
||||
user, but in the future there might be <quote>setuid</> functions and
|
||||
other facilities to allow the current user to change temporarily.
|
||||
In Unix parlance, the session user is the <quote>real user</>
|
||||
and the current user is the <quote>effective user</>.
|
||||
The <function>session_user</> is the user that initiated a
|
||||
database connection; it is fixed for the duration of that
|
||||
connection. The <function>current_user</> is the user identifier
|
||||
that is applicable for permission checking. Normally, it is equal
|
||||
to the session user, but it changes during the execution of
|
||||
functions with the attribute <literal>SECURITY DEFINER</literal>.
|
||||
In Unix parlance, the session user is the <quote>real user</> and
|
||||
the current user is the <quote>effective user</>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
|
@ -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">
|
||||
@ -21,6 +21,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
||||
| IMMUTABLE | STABLE | VOLATILE
|
||||
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
||||
| IMPLICIT CAST
|
||||
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
|
||||
| AS '<replaceable class="parameter">definition</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>
|
||||
</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>
|
||||
<term><replaceable class="parameter">definition</replaceable></term>
|
||||
|
||||
@ -372,7 +394,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="sql-createfunction-cast-function">
|
||||
<refsect1 id="sql-createfunction-cast-functions">
|
||||
<title id="sql-createfunction-cast-functions-title">
|
||||
Type Cast Functions
|
||||
</title>
|
||||
|
@ -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">
|
||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
||||
worries about funny characters.
|
||||
-->
|
||||
<literallayout><![CDATA[
|
||||
Functions can be executed with the privileges of the owner
|
||||
Syntax of CREATE FUNCTION has been extended to resemble SQL99
|
||||
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
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 */
|
||||
"-", /* probin */
|
||||
true, /* isAgg */
|
||||
true, /* (obsolete "trusted") */
|
||||
false, /* security invoker (currently not definable for agg) */
|
||||
false, /* isImplicit */
|
||||
false, /* isStrict (not needed for agg) */
|
||||
PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 *probin,
|
||||
bool isAgg,
|
||||
bool trusted,
|
||||
bool security_definer,
|
||||
bool isImplicit,
|
||||
bool isStrict,
|
||||
char volatility,
|
||||
@ -220,7 +220,7 @@ ProcedureCreate(const char *procedureName,
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
|
||||
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
||||
values[i++] = BoolGetDatum(isAgg); /* proisagg */
|
||||
values[i++] = BoolGetDatum(trusted); /* proistrusted */
|
||||
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
|
||||
values[i++] = BoolGetDatum(isImplicit); /* proimplicit */
|
||||
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
||||
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* These routines take the parse tree and pick out the
|
||||
@ -421,6 +421,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
||||
outin_ratio = OUTIN_RATIO;
|
||||
isImplicit = false;
|
||||
isStrict = false;
|
||||
security = false;
|
||||
volatility = PROVOLATILE_VOLATILE;
|
||||
|
||||
/* override attributes from explicit list */
|
||||
@ -489,7 +490,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
||||
prosrc_str, /* converted to text later */
|
||||
probin_str, /* converted to text later */
|
||||
false, /* not an aggregate */
|
||||
true, /* (obsolete "trusted") */
|
||||
security,
|
||||
isImplicit,
|
||||
isStrict,
|
||||
volatility,
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* 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 */
|
||||
fileName, /* probin */
|
||||
false, /* not aggregate */
|
||||
true, /* trusted */
|
||||
false, /* security invoker */
|
||||
false, /* not implicit coercion */
|
||||
false, /* isStrict (irrelevant, no args) */
|
||||
PROVOLATILE_VOLATILE, /* assume unsafe */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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_proc.h"
|
||||
#include "executor/functions.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgrtab.h"
|
||||
#include "utils/lsyscache.h"
|
||||
@ -56,10 +57,12 @@ typedef struct
|
||||
} 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_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
|
||||
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
|
||||
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;
|
||||
HeapTuple procedureTuple;
|
||||
@ -177,10 +192,9 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
|
||||
finfo->fn_strict = procedureStruct->proisstrict;
|
||||
finfo->fn_retset = procedureStruct->proretset;
|
||||
|
||||
if (!procedureStruct->proistrusted)
|
||||
if (procedureStruct->prosecdef && !ignore_security)
|
||||
{
|
||||
/* This isn't really supported anymore... */
|
||||
finfo->fn_addr = fmgr_untrusted;
|
||||
finfo->fn_addr = fmgr_security_definer;
|
||||
finfo->fn_oid = functionId;
|
||||
ReleaseSysCache(procedureTuple);
|
||||
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
|
||||
fmgr_untrusted(PG_FUNCTION_ARGS)
|
||||
fmgr_security_definer(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* Currently these are unsupported. Someday we might do something
|
||||
* like forking a subprocess to execute 'em.
|
||||
*/
|
||||
elog(ERROR, "Untrusted functions not supported");
|
||||
return 0; /* keep compiler happy */
|
||||
Datum result;
|
||||
FmgrInfo *save_flinfo;
|
||||
struct fmgr_security_definer_cache *fcache;
|
||||
Oid save_userid;
|
||||
HeapTuple tuple;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* 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 *proimplicit;
|
||||
char *proisstrict;
|
||||
char *prosecdef;
|
||||
char *lanname;
|
||||
char *rettypename;
|
||||
|
||||
@ -3232,7 +3233,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
{
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT proretset, prosrc, probin, "
|
||||
"provolatile, proimplicit, proisstrict, "
|
||||
"provolatile, proimplicit, proisstrict, prosecdef, "
|
||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||
"FROM pg_proc "
|
||||
"WHERE oid = '%s'::oid",
|
||||
@ -3245,6 +3246,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||
"'f'::boolean as proimplicit, "
|
||||
"proisstrict, "
|
||||
"'f'::boolean as prosecdef, "
|
||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||
"FROM pg_proc "
|
||||
"WHERE oid = '%s'::oid",
|
||||
@ -3257,6 +3259,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||
"'f'::boolean as proimplicit, "
|
||||
"'f'::boolean as proisstrict, "
|
||||
"'f'::boolean as prosecdef, "
|
||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||
"FROM pg_proc "
|
||||
"WHERE oid = '%s'::oid",
|
||||
@ -3287,6 +3290,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
|
||||
proimplicit = PQgetvalue(res, 0, PQfnumber(res, "proimplicit"));
|
||||
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
|
||||
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
|
||||
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
|
||||
|
||||
/*
|
||||
@ -3358,6 +3362,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
if (proisstrict[0] == 't')
|
||||
appendPQExpBuffer(q, " STRICT");
|
||||
|
||||
if (prosecdef[0] == 't')
|
||||
appendPQExpBuffer(q, " SECURITY DEFINER");
|
||||
|
||||
appendPQExpBuffer(q, ";\n");
|
||||
|
||||
ArchiveEntry(fout, finfo->oid, fn->data, finfo->pronamespace->nspname,
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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 */
|
||||
#define CATALOG_VERSION_NO 200205122
|
||||
#define CATALOG_VERSION_NO 200205181
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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
|
||||
* 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, {"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, {"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, {"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 }, \
|
||||
@ -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 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 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 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));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -55,7 +55,7 @@ WHERE p1.oid != p2.oid AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
(p1.prolang != p2.prolang OR
|
||||
p1.proisagg != p2.proisagg OR
|
||||
p1.proistrusted != p2.proistrusted OR
|
||||
p1.prosecdef != p2.prosecdef OR
|
||||
p1.proisstrict != p2.proisstrict OR
|
||||
p1.proretset != p2.proretset OR
|
||||
p1.provolatile != p2.provolatile OR
|
||||
|
@ -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 testfunc_nosuch(int) TO regressuser4;
|
||||
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;
|
||||
SELECT testfunc1(5), testfunc2(5); -- ok
|
||||
testfunc1 | testfunc2
|
||||
@ -218,6 +222,14 @@ ERROR: sql: permission denied
|
||||
SET SESSION AUTHORIZATION regressuser3;
|
||||
SELECT testfunc1(5); -- fail
|
||||
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;
|
||||
SELECT testfunc1(5); -- ok
|
||||
testfunc1
|
||||
@ -501,6 +513,8 @@ from (select oid from pg_class where relname = 'atest1') as t1;
|
||||
|
||||
-- clean up
|
||||
\c regression
|
||||
DROP FUNCTION testfunc2(int);
|
||||
DROP FUNCTION testfunc4(boolean);
|
||||
DROP TABLE atest1;
|
||||
DROP TABLE atest2;
|
||||
DROP TABLE atest3;
|
||||
|
@ -54,7 +54,7 @@ WHERE p1.oid != p2.oid AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
(p1.prolang != p2.prolang OR
|
||||
p1.proisagg != p2.proisagg OR
|
||||
p1.proistrusted != p2.proistrusted OR
|
||||
p1.prosecdef != p2.prosecdef OR
|
||||
p1.proisstrict != p2.proisstrict OR
|
||||
p1.proretset != p2.proretset OR
|
||||
p1.provolatile != p2.provolatile OR
|
||||
|
@ -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 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;
|
||||
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
|
||||
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
|
||||
SELECT testfunc4(true); -- ok
|
||||
|
||||
SET SESSION AUTHORIZATION regressuser4;
|
||||
SELECT testfunc1(5); -- ok
|
||||
@ -265,6 +272,9 @@ from (select oid from pg_class where relname = 'atest1') as t1;
|
||||
-- clean up
|
||||
|
||||
\c regression
|
||||
DROP FUNCTION testfunc2(int);
|
||||
DROP FUNCTION testfunc4(boolean);
|
||||
|
||||
DROP TABLE atest1;
|
||||
DROP TABLE atest2;
|
||||
DROP TABLE atest3;
|
||||
|
Loading…
Reference in New Issue
Block a user