Skip to content

Commit e8ac187

Browse files
committed
Allow functions to be executed with the privileges of the function owner.
I took the opportunity to remove the pg_proc.proistrusted field.
1 parent 51fd22a commit e8ac187

File tree

16 files changed

+1508
-1393
lines changed

16 files changed

+1508
-1393
lines changed

doc/src/sgml/func.sgml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.97 2002/05/13 19:22:06 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.98 2002/05/18 13:47:59 petere Exp $
33
PostgreSQL documentation
44
-->
55

@@ -4260,14 +4260,14 @@ SELECT NULLIF(value, '(none)') ...
42604260
</indexterm>
42614261

42624262
<para>
4263-
The <function>session_user</> is the user that initiated a database
4264-
connection; it is fixed for the duration of that connection. The
4265-
<function>current_user</> is the user identifier that is applicable
4266-
for permission checking. Currently it is always equal to the session
4267-
user, but in the future there might be <quote>setuid</> functions and
4268-
other facilities to allow the current user to change temporarily.
4269-
In Unix parlance, the session user is the <quote>real user</>
4270-
and the current user is the <quote>effective user</>.
4263+
The <function>session_user</> is the user that initiated a
4264+
database connection; it is fixed for the duration of that
4265+
connection. The <function>current_user</> is the user identifier
4266+
that is applicable for permission checking. Normally, it is equal
4267+
to the session user, but it changes during the execution of
4268+
functions with the attribute <literal>SECURITY DEFINER</literal>.
4269+
In Unix parlance, the session user is the <quote>real user</> and
4270+
the current user is the <quote>effective user</>.
42714271
</para>
42724272

42734273
<note>

doc/src/sgml/ref/create_function.sgml

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.38 2002/05/17 18:32:52 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.39 2002/05/18 13:47:59 petere Exp $
33
-->
44

55
<refentry id="SQL-CREATEFUNCTION">
@@ -21,6 +21,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
2121
| IMMUTABLE | STABLE | VOLATILE
2222
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
2323
| IMPLICIT CAST
24+
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
2425
| AS '<replaceable class="parameter">definition</replaceable>'
2526
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
2627
} ...
@@ -199,6 +200,27 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
199200
</listitem>
200201
</varlistentry>
201202

203+
<varlistentry>
204+
<term><optional>EXTERNAL</optional> SECURITY INVOKER</term>
205+
<term><optional>EXTERNAL</optional> SECURITY DEFINER</term>
206+
207+
<listitem>
208+
<para>
209+
<literal>SECURITY INVOKER</literal> indicates that the function
210+
is to be executed with the privileges of the user that calls it.
211+
That is the default. <literal>SECURITY DEFINER</literal>
212+
specifies that the function is to be executed with the
213+
privileges of the user that created it.
214+
</para>
215+
216+
<para>
217+
The key word <literal>EXTERNAL</literal> is present for SQL
218+
compatibility but is optional since, unlike in SQL, this feature
219+
does not only apply to external functions.
220+
</para>
221+
</listitem>
222+
</varlistentry>
223+
202224
<varlistentry>
203225
<term><replaceable class="parameter">definition</replaceable></term>
204226

@@ -372,7 +394,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
372394
</para>
373395
</refsect1>
374396

375-
<refsect1 id="sql-createfunction-cast-function">
397+
<refsect1 id="sql-createfunction-cast-functions">
376398
<title id="sql-createfunction-cast-functions-title">
377399
Type Cast Functions
378400
</title>

doc/src/sgml/release.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.136 2002/05/17 18:32:52 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.137 2002/05/18 13:47:59 petere Exp $
33
-->
44

55
<appendix id="release">
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
2424
worries about funny characters.
2525
-->
2626
<literallayout><![CDATA[
27+
Functions can be executed with the privileges of the owner
2728
Syntax of CREATE FUNCTION has been extended to resemble SQL99
2829
Effects of SET within a transaction block now roll back if transaction aborts
2930
New SET LOCAL syntax sets a parameter for the life of the current transaction

src/backend/catalog/pg_aggregate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.45 2002/05/17 22:35:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.46 2002/05/18 13:47:59 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -139,7 +139,7 @@ AggregateCreate(const char *aggName,
139139
"aggregate_dummy", /* placeholder proc */
140140
"-", /* probin */
141141
true, /* isAgg */
142-
true, /* (obsolete "trusted") */
142+
false, /* security invoker (currently not definable for agg) */
143143
false, /* isImplicit */
144144
false, /* isStrict (not needed for agg) */
145145
PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */

src/backend/catalog/pg_proc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.71 2002/05/17 22:35:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.72 2002/05/18 13:47:59 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -48,7 +48,7 @@ ProcedureCreate(const char *procedureName,
4848
const char *prosrc,
4949
const char *probin,
5050
bool isAgg,
51-
bool trusted,
51+
bool security_definer,
5252
bool isImplicit,
5353
bool isStrict,
5454
char volatility,
@@ -220,7 +220,7 @@ ProcedureCreate(const char *procedureName,
220220
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
221221
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
222222
values[i++] = BoolGetDatum(isAgg); /* proisagg */
223-
values[i++] = BoolGetDatum(trusted); /* proistrusted */
223+
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
224224
values[i++] = BoolGetDatum(isImplicit); /* proimplicit */
225225
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
226226
values[i++] = BoolGetDatum(returnsSet); /* proretset */

src/backend/commands/functioncmds.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.4 2002/05/17 18:32:52 petere Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.5 2002/05/18 13:47:59 petere Exp $
1313
*
1414
* DESCRIPTION
1515
* These routines take the parse tree and pick out the
@@ -421,6 +421,7 @@ CreateFunction(CreateFunctionStmt *stmt)
421421
outin_ratio = OUTIN_RATIO;
422422
isImplicit = false;
423423
isStrict = false;
424+
security = false;
424425
volatility = PROVOLATILE_VOLATILE;
425426

426427
/* override attributes from explicit list */
@@ -489,7 +490,7 @@ CreateFunction(CreateFunctionStmt *stmt)
489490
prosrc_str, /* converted to text later */
490491
probin_str, /* converted to text later */
491492
false, /* not an aggregate */
492-
true, /* (obsolete "trusted") */
493+
security,
493494
isImplicit,
494495
isStrict,
495496
volatility,

src/backend/utils/adt/sets.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.43 2002/04/11 20:00:05 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.44 2002/05/18 13:47:59 petere Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -61,7 +61,7 @@ SetDefine(char *querystr, Oid elemType)
6161
querystr, /* prosrc */
6262
fileName, /* probin */
6363
false, /* not aggregate */
64-
true, /* trusted */
64+
false, /* security invoker */
6565
false, /* not implicit coercion */
6666
false, /* isStrict (irrelevant, no args) */
6767
PROVOLATILE_VOLATILE, /* assume unsafe */

src/backend/utils/fmgr/fmgr.c

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.58 2002/03/05 05:33:20 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.59 2002/05/18 13:47:59 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -19,6 +19,7 @@
1919
#include "catalog/pg_language.h"
2020
#include "catalog/pg_proc.h"
2121
#include "executor/functions.h"
22+
#include "miscadmin.h"
2223
#include "utils/builtins.h"
2324
#include "utils/fmgrtab.h"
2425
#include "utils/lsyscache.h"
@@ -56,10 +57,12 @@ typedef struct
5657
} Oldstyle_fnextra;
5758

5859

60+
static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
61+
bool ignore_security);
5962
static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
6063
static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
6164
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
62-
static Datum fmgr_untrusted(PG_FUNCTION_ARGS);
65+
static Datum fmgr_security_definer(PG_FUNCTION_ARGS);
6366

6467

6568
/*
@@ -135,6 +138,18 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
135138
*/
136139
void
137140
fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
141+
{
142+
fmgr_info_cxt_security(functionId, finfo, mcxt, false);
143+
}
144+
145+
/*
146+
* This one does the actual work. ignore_security is ordinarily false
147+
* but is set to true by fmgr_security_definer to avoid infinite
148+
* recursive lookups.
149+
*/
150+
static void
151+
fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
152+
bool ignore_security)
138153
{
139154
const FmgrBuiltin *fbp;
140155
HeapTuple procedureTuple;
@@ -177,10 +192,9 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
177192
finfo->fn_strict = procedureStruct->proisstrict;
178193
finfo->fn_retset = procedureStruct->proretset;
179194

180-
if (!procedureStruct->proistrusted)
195+
if (procedureStruct->prosecdef && !ignore_security)
181196
{
182-
/* This isn't really supported anymore... */
183-
finfo->fn_addr = fmgr_untrusted;
197+
finfo->fn_addr = fmgr_security_definer;
184198
finfo->fn_oid = functionId;
185199
ReleaseSysCache(procedureTuple);
186200
return;
@@ -620,17 +634,63 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
620634

621635

622636
/*
623-
* Handler for all functions marked "untrusted"
637+
* Support for security definer functions
638+
*/
639+
640+
struct fmgr_security_definer_cache
641+
{
642+
FmgrInfo flinfo;
643+
Oid userid;
644+
};
645+
646+
/*
647+
* Function handler for security definer functions. We extract the
648+
* OID of the actual function and do a fmgr lookup again. Then we
649+
* look up the owner of the function and cache both the fmgr info and
650+
* the owner ID. During the call we temporarily replace the flinfo
651+
* with the cached/looked-up one, while keeping the outer fcinfo
652+
* (which contains all the actual arguments, etc.) intact.
624653
*/
625654
static Datum
626-
fmgr_untrusted(PG_FUNCTION_ARGS)
655+
fmgr_security_definer(PG_FUNCTION_ARGS)
627656
{
628-
/*
629-
* Currently these are unsupported. Someday we might do something
630-
* like forking a subprocess to execute 'em.
631-
*/
632-
elog(ERROR, "Untrusted functions not supported");
633-
return 0; /* keep compiler happy */
657+
Datum result;
658+
FmgrInfo *save_flinfo;
659+
struct fmgr_security_definer_cache *fcache;
660+
Oid save_userid;
661+
HeapTuple tuple;
662+
663+
if (!fcinfo->flinfo->fn_extra)
664+
{
665+
fcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*fcache));
666+
memset(fcache, 0, sizeof(*fcache));
667+
668+
fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
669+
fcinfo->flinfo->fn_mcxt, true);
670+
671+
tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(fcinfo->flinfo->fn_oid), 0, 0, 0);
672+
if (!HeapTupleIsValid(tuple))
673+
elog(ERROR, "fmgr_security_definer: function %u: cache lookup failed",
674+
fcinfo->flinfo->fn_oid);
675+
fcache->userid = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
676+
ReleaseSysCache(tuple);
677+
678+
fcinfo->flinfo->fn_extra = fcache;
679+
}
680+
else
681+
fcache = fcinfo->flinfo->fn_extra;
682+
683+
save_flinfo = fcinfo->flinfo;
684+
fcinfo->flinfo = &fcache->flinfo;
685+
686+
save_userid = GetUserId();
687+
SetUserId(fcache->userid);
688+
result = FunctionCallInvoke(fcinfo);
689+
SetUserId(save_userid);
690+
691+
fcinfo->flinfo = save_flinfo;
692+
693+
return result;
634694
}
635695

636696

src/bin/pg_dump/pg_dump.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.261 2002/05/17 18:32:52 petere Exp $
25+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.262 2002/05/18 13:48:00 petere Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -3216,6 +3216,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
32163216
char *provolatile;
32173217
char *proimplicit;
32183218
char *proisstrict;
3219+
char *prosecdef;
32193220
char *lanname;
32203221
char *rettypename;
32213222

@@ -3232,7 +3233,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
32323233
{
32333234
appendPQExpBuffer(query,
32343235
"SELECT proretset, prosrc, probin, "
3235-
"provolatile, proimplicit, proisstrict, "
3236+
"provolatile, proimplicit, proisstrict, prosecdef, "
32363237
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
32373238
"FROM pg_proc "
32383239
"WHERE oid = '%s'::oid",
@@ -3245,6 +3246,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
32453246
"case when proiscachable then 'i' else 'v' end as provolatile, "
32463247
"'f'::boolean as proimplicit, "
32473248
"proisstrict, "
3249+
"'f'::boolean as prosecdef, "
32483250
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
32493251
"FROM pg_proc "
32503252
"WHERE oid = '%s'::oid",
@@ -3257,6 +3259,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
32573259
"case when proiscachable then 'i' else 'v' end as provolatile, "
32583260
"'f'::boolean as proimplicit, "
32593261
"'f'::boolean as proisstrict, "
3262+
"'f'::boolean as prosecdef, "
32603263
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
32613264
"FROM pg_proc "
32623265
"WHERE oid = '%s'::oid",
@@ -3287,6 +3290,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
32873290
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
32883291
proimplicit = PQgetvalue(res, 0, PQfnumber(res, "proimplicit"));
32893292
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
3293+
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
32903294
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
32913295

32923296
/*
@@ -3358,6 +3362,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
33583362
if (proisstrict[0] == 't')
33593363
appendPQExpBuffer(q, " STRICT");
33603364

3365+
if (prosecdef[0] == 't')
3366+
appendPQExpBuffer(q, " SECURITY DEFINER");
3367+
33613368
appendPQExpBuffer(q, ";\n");
33623369

33633370
ArchiveEntry(fout, finfo->oid, fn->data, finfo->pronamespace->nspname,

src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $Id: catversion.h,v 1.131 2002/05/12 23:43:03 tgl Exp $
40+
* $Id: catversion.h,v 1.132 2002/05/18 13:48:00 petere Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200205122
56+
#define CATALOG_VERSION_NO 200205181
5757

5858
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy