mirror of
https://github.com/postgres/postgres.git
synced 2025-06-08 22:02:03 +03:00
Make standard maintenance operations (including VACUUM, ANALYZE, REINDEX,
and CLUSTER) execute as the table owner rather than the calling user, using the same privilege-switching mechanism already used for SECURITY DEFINER functions. The purpose of this change is to ensure that user-defined functions used in index definitions cannot acquire the privileges of a superuser account that is performing routine maintenance. While a function used in an index is supposed to be IMMUTABLE and thus not able to do anything very interesting, there are several easy ways around that restriction; and even if we could plug them all, there would remain a risk of reading sensitive information and broadcasting it through a covert channel such as CPU usage. To prevent bypassing this security measure, execution of SET SESSION AUTHORIZATION and SET ROLE is now forbidden within a SECURITY DEFINER context. Thanks to Itagaki Takahiro for reporting this vulnerability. Security: CVE-2007-6600
This commit is contained in:
parent
7146fab2a8
commit
218cf59b60
@ -1,4 +1,4 @@
|
|||||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_session_auth.sgml,v 1.7 2002/09/21 18:32:54 petere Exp $ -->
|
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_session_auth.sgml,v 1.7.2.1 2008/01/03 21:25:58 tgl Exp $ -->
|
||||||
<refentry id="SQL-SET-SESSION-AUTHORIZATION">
|
<refentry id="SQL-SET-SESSION-AUTHORIZATION">
|
||||||
<docinfo>
|
<docinfo>
|
||||||
<date>2001-04-21</date>
|
<date>2001-04-21</date>
|
||||||
@ -27,7 +27,7 @@ RESET SESSION AUTHORIZATION
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
This command sets the session user identifier and the current user
|
This command sets the session user identifier and the current user
|
||||||
identifier of the current SQL-session context to be
|
identifier of the current SQL session to be
|
||||||
<parameter>username</parameter>. The user name may be written as
|
<parameter>username</parameter>. The user name may be written as
|
||||||
either an identifier or a string literal.
|
either an identifier or a string literal.
|
||||||
The session user identifier is valid for the duration of a
|
The session user identifier is valid for the duration of a
|
||||||
@ -39,7 +39,7 @@ RESET SESSION AUTHORIZATION
|
|||||||
The session user identifier is initially set to be the (possibly
|
The session user identifier is initially set to be the (possibly
|
||||||
authenticated) user name provided by the client. The current user
|
authenticated) user name provided by the client. The current user
|
||||||
identifier is normally equal to the session user identifier, but
|
identifier is normally equal to the session user identifier, but
|
||||||
may change temporarily in the context of <quote>setuid</quote>
|
might change temporarily in the context of <literal>SECURITY DEFINER</>
|
||||||
functions and similar mechanisms. The current user identifier is
|
functions and similar mechanisms. The current user identifier is
|
||||||
relevant for permission checking.
|
relevant for permission checking.
|
||||||
</para>
|
</para>
|
||||||
@ -65,6 +65,15 @@ RESET SESSION AUTHORIZATION
|
|||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>SET SESSION AUTHORIZATION</> cannot be used within a
|
||||||
|
<literal>SECURITY DEFINER</> function.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.135.2.4 2007/04/26 23:25:48 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.135.2.5 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Transaction aborts can now occur two ways:
|
* Transaction aborts can now occur two ways:
|
||||||
@ -215,6 +215,8 @@ static TransactionStateData CurrentTransactionStateData = {
|
|||||||
|
|
||||||
TransactionState CurrentTransactionState = &CurrentTransactionStateData;
|
TransactionState CurrentTransactionState = &CurrentTransactionStateData;
|
||||||
|
|
||||||
|
static Oid prevUser; /* CurrentUserId at transaction start */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User-tweakable parameters
|
* User-tweakable parameters
|
||||||
*/
|
*/
|
||||||
@ -960,6 +962,7 @@ static void
|
|||||||
CommitTransaction(void)
|
CommitTransaction(void)
|
||||||
{
|
{
|
||||||
TransactionState s = CurrentTransactionState;
|
TransactionState s = CurrentTransactionState;
|
||||||
|
bool prevSecDefCxt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the current transaction state
|
* check the current transaction state
|
||||||
@ -983,6 +986,10 @@ CommitTransaction(void)
|
|||||||
*/
|
*/
|
||||||
s->state = TRANS_COMMIT;
|
s->state = TRANS_COMMIT;
|
||||||
|
|
||||||
|
GetUserIdAndContext(&prevUser, &prevSecDefCxt);
|
||||||
|
/* SecurityDefinerContext should never be set outside a transaction */
|
||||||
|
Assert(!prevSecDefCxt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do pre-commit processing (most of this stuff requires database
|
* Do pre-commit processing (most of this stuff requires database
|
||||||
* access, and in fact could still cause an error...)
|
* access, and in fact could still cause an error...)
|
||||||
@ -1118,9 +1125,16 @@ AbortTransaction(void)
|
|||||||
AtAbort_Memory();
|
AtAbort_Memory();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset user id which might have been changed transiently
|
* Reset user ID which might have been changed transiently. We need this
|
||||||
|
* to clean up in case control escaped out of a SECURITY DEFINER function
|
||||||
|
* or other local change of CurrentUserId; therefore, the prior value
|
||||||
|
* of SecurityDefinerContext also needs to be restored.
|
||||||
|
*
|
||||||
|
* (Note: it is not necessary to restore session authorization
|
||||||
|
* setting here because that can only be changed via GUC, and GUC will
|
||||||
|
* take care of rolling it back if need be.)
|
||||||
*/
|
*/
|
||||||
SetUserId(GetSessionUserId());
|
SetUserIdAndContext(prevUser, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do abort processing
|
* do abort processing
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.202.2.1 2005/06/25 16:54:30 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.202.2.2 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -1439,6 +1439,8 @@ index_build(Relation heapRelation,
|
|||||||
IndexInfo *indexInfo)
|
IndexInfo *indexInfo)
|
||||||
{
|
{
|
||||||
RegProcedure procedure;
|
RegProcedure procedure;
|
||||||
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sanity checks
|
* sanity checks
|
||||||
@ -1449,6 +1451,13 @@ index_build(Relation heapRelation,
|
|||||||
procedure = indexRelation->rd_am->ambuild;
|
procedure = indexRelation->rd_am->ambuild;
|
||||||
Assert(RegProcedureIsValid(procedure));
|
Assert(RegProcedureIsValid(procedure));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch to the table owner's userid, so that any index functions are
|
||||||
|
* run as that user.
|
||||||
|
*/
|
||||||
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
SetUserIdAndContext(heapRelation->rd_rel->relowner, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call the access method's build procedure
|
* Call the access method's build procedure
|
||||||
*/
|
*/
|
||||||
@ -1456,6 +1465,9 @@ index_build(Relation heapRelation,
|
|||||||
PointerGetDatum(heapRelation),
|
PointerGetDatum(heapRelation),
|
||||||
PointerGetDatum(indexRelation),
|
PointerGetDatum(indexRelation),
|
||||||
PointerGetDatum(indexInfo));
|
PointerGetDatum(indexInfo));
|
||||||
|
|
||||||
|
/* Restore userid */
|
||||||
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.6 2002/09/04 20:31:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.6.2.1 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -43,9 +43,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
|||||||
const char *owner_name;
|
const char *owner_name;
|
||||||
Oid owner_userid;
|
Oid owner_userid;
|
||||||
Oid saved_userid;
|
Oid saved_userid;
|
||||||
|
bool saved_secdefcxt;
|
||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
saved_userid = GetUserId();
|
GetUserIdAndContext(&saved_userid, &saved_secdefcxt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out user identities.
|
* Figure out user identities.
|
||||||
@ -68,7 +69,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
|||||||
* (This will revert to session user on error or at the end of
|
* (This will revert to session user on error or at the end of
|
||||||
* this routine.)
|
* this routine.)
|
||||||
*/
|
*/
|
||||||
SetUserId(owner_userid);
|
SetUserIdAndContext(owner_userid, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* not superuser */
|
/* not superuser */
|
||||||
@ -143,7 +144,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
|||||||
PopSpecialNamespace(namespaceId);
|
PopSpecialNamespace(namespaceId);
|
||||||
|
|
||||||
/* Reset current user */
|
/* Reset current user */
|
||||||
SetUserId(saved_userid);
|
SetUserIdAndContext(saved_userid, saved_secdefcxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.244.2.2 2007/03/14 18:49:32 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.244.2.3 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -720,6 +720,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
|
|||||||
LockRelId onerelid;
|
LockRelId onerelid;
|
||||||
Oid toast_relid;
|
Oid toast_relid;
|
||||||
bool result;
|
bool result;
|
||||||
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
/* Begin a transaction for vacuuming this relation */
|
/* Begin a transaction for vacuuming this relation */
|
||||||
StartTransactionCommand(true);
|
StartTransactionCommand(true);
|
||||||
@ -820,6 +822,14 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
|
|||||||
*/
|
*/
|
||||||
toast_relid = onerel->rd_rel->reltoastrelid;
|
toast_relid = onerel->rd_rel->reltoastrelid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch to the table owner's userid, so that any index functions are
|
||||||
|
* run as that user. (This is unnecessary, but harmless, for lazy
|
||||||
|
* VACUUM.)
|
||||||
|
*/
|
||||||
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
SetUserIdAndContext(onerel->rd_rel->relowner, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the actual work --- either FULL or "lazy" vacuum
|
* Do the actual work --- either FULL or "lazy" vacuum
|
||||||
*/
|
*/
|
||||||
@ -830,6 +840,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
|
|||||||
|
|
||||||
result = true; /* did the vacuum */
|
result = true; /* did the vacuum */
|
||||||
|
|
||||||
|
/* Restore userid */
|
||||||
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
/* all done with this class, but hold lock until commit */
|
/* all done with this class, but hold lock until commit */
|
||||||
relation_close(onerel, NoLock);
|
relation_close(onerel, NoLock);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.71.2.4 2006/02/12 22:33:46 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.71.2.5 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -561,6 +561,20 @@ assign_session_authorization(const char *value, bool doit, bool interactive)
|
|||||||
/* not a saved ID, so look it up */
|
/* not a saved ID, so look it up */
|
||||||
HeapTuple userTup;
|
HeapTuple userTup;
|
||||||
|
|
||||||
|
if (InSecurityDefinerContext())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Disallow SET SESSION AUTHORIZATION inside a security definer
|
||||||
|
* context. We need to do this because when we exit the context,
|
||||||
|
* GUC won't be notified, leaving things out of sync. Note that
|
||||||
|
* this test is positioned so that restoring a previously saved
|
||||||
|
* setting isn't prevented.
|
||||||
|
*/
|
||||||
|
if (interactive)
|
||||||
|
elog(ERROR, "cannot set session authorization within security-definer function");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (! IsTransactionState())
|
if (! IsTransactionState())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.43.2.5 2004/10/13 22:22:22 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.43.2.6 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
@ -178,9 +178,10 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
int match_type;
|
int match_type;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
|
|
||||||
@ -297,12 +298,12 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Execute the plan
|
* Execute the plan
|
||||||
*/
|
*/
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_check()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_check()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed == 0)
|
if (SPI_processed == 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -486,12 +487,12 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
|||||||
* Now check that foreign key exists in PK table
|
* Now check that foreign key exists in PK table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_check()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_check()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed == 0)
|
if (SPI_processed == 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -558,10 +559,11 @@ ri_Check_Pk_Match(Relation pk_rel, HeapTuple old_row, Oid tgoid, int match_type,
|
|||||||
Datum check_values[RI_MAX_NUMKEYS];
|
Datum check_values[RI_MAX_NUMKEYS];
|
||||||
char check_nulls[RI_MAX_NUMKEYS + 1];
|
char check_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
|
||||||
ri_BuildQueryKeyPkCheck(&qkey, tgoid,
|
ri_BuildQueryKeyPkCheck(&qkey, tgoid,
|
||||||
RI_PLAN_CHECK_LOOKUPPK, pk_rel,
|
RI_PLAN_CHECK_LOOKUPPK, pk_rel,
|
||||||
@ -681,12 +683,12 @@ ri_Check_Pk_Match(Relation pk_rel, HeapTuple old_row, Oid tgoid, int match_type,
|
|||||||
* Now check that foreign key exists in PK table
|
* Now check that foreign key exists in PK table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, check_values, check_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in ri_Check_Pk_Match()");
|
elog(ERROR, "SPI_execp() failed in ri_Check_Pk_Match()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
result = (SPI_processed != 0);
|
result = (SPI_processed != 0);
|
||||||
|
|
||||||
@ -721,9 +723,10 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
int match_type;
|
int match_type;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
|
|
||||||
@ -886,12 +889,12 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now check for existing references
|
* Now check for existing references
|
||||||
*/
|
*/
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, del_values, del_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, del_values, del_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_noaction_del()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_noaction_del()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed > 0)
|
if (SPI_processed > 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -948,9 +951,10 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
int match_type;
|
int match_type;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
|
|
||||||
@ -1124,12 +1128,12 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now check for existing references
|
* Now check for existing references
|
||||||
*/
|
*/
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_noaction_upd()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_noaction_upd()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed > 0)
|
if (SPI_processed > 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -1182,7 +1186,8 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
|
|||||||
char del_nulls[RI_MAX_NUMKEYS + 1];
|
char del_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -1333,13 +1338,13 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now delete constraint
|
* Now delete constraint
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, del_values, del_nulls, 0) != SPI_OK_DELETE)
|
if (SPI_execp(qplan, del_values, del_nulls, 0) != SPI_OK_DELETE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_cascade_del()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_cascade_del()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_cascade_del()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_cascade_del()");
|
||||||
@ -1387,7 +1392,8 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -1569,13 +1575,13 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now update the existing references
|
* Now update the existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_cascade_upd()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_cascade_upd()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_cascade_upd()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_cascade_upd()");
|
||||||
@ -1628,7 +1634,8 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
|
|||||||
char del_nulls[RI_MAX_NUMKEYS + 1];
|
char del_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -1781,13 +1788,13 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now check for existing references
|
* Now check for existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, del_values, del_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, del_values, del_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_restrict_del()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_restrict_del()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed > 0)
|
if (SPI_processed > 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -1848,7 +1855,8 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
|
|||||||
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -2012,15 +2020,13 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now check for existing references
|
* Now check for existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(RelationGetForm(pk_rel)->relowner, true);
|
||||||
|
|
||||||
SetUserId(RelationGetForm(pk_rel)->relowner);
|
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 1) != SPI_OK_SELECT)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 1) != SPI_OK_SELECT)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_restrict_upd()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_restrict_upd()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_processed > 0)
|
if (SPI_processed > 0)
|
||||||
elog(ERROR, "%s referential integrity violation - "
|
elog(ERROR, "%s referential integrity violation - "
|
||||||
@ -2073,7 +2079,8 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
|
|||||||
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -2234,13 +2241,13 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now update the existing references
|
* Now update the existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_setnull_del()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_setnull_del()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_setnull_del()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_setnull_del()");
|
||||||
@ -2289,7 +2296,8 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
|
|||||||
int i;
|
int i;
|
||||||
int match_type;
|
int match_type;
|
||||||
bool use_cached_query;
|
bool use_cached_query;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -2495,13 +2503,13 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now update the existing references
|
* Now update the existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_setnull_upd()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_setnull_upd()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_setnull_upd()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_setnull_upd()");
|
||||||
@ -2547,7 +2555,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
|||||||
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
char upd_nulls[RI_MAX_NUMKEYS + 1];
|
||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -2739,13 +2748,13 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now update the existing references
|
* Now update the existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_setdefault_del()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_setdefault_del()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_setdefault_del()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_setdefault_del()");
|
||||||
@ -2803,7 +2812,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
|||||||
bool isnull;
|
bool isnull;
|
||||||
int i;
|
int i;
|
||||||
int match_type;
|
int match_type;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
Oid fk_owner;
|
Oid fk_owner;
|
||||||
|
|
||||||
ReferentialIntegritySnapshotOverride = true;
|
ReferentialIntegritySnapshotOverride = true;
|
||||||
@ -3018,13 +3028,13 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Now update the existing references
|
* Now update the existing references
|
||||||
*/
|
*/
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(fk_owner);
|
SetUserIdAndContext(fk_owner, true);
|
||||||
|
|
||||||
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
if (SPI_execp(qplan, upd_values, upd_nulls, 0) != SPI_OK_UPDATE)
|
||||||
elog(ERROR, "SPI_execp() failed in RI_FKey_setdefault_upd()");
|
elog(ERROR, "SPI_execp() failed in RI_FKey_setdefault_upd()");
|
||||||
|
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if (SPI_finish() != SPI_OK_FINISH)
|
||||||
elog(WARNING, "SPI_finish() failed in RI_FKey_setdefault_upd()");
|
elog(WARNING, "SPI_finish() failed in RI_FKey_setdefault_upd()");
|
||||||
@ -3171,7 +3181,8 @@ ri_PlanCheck(char *querystr, int nargs, Oid *argtypes,
|
|||||||
{
|
{
|
||||||
void *qplan;
|
void *qplan;
|
||||||
Relation query_rel;
|
Relation query_rel;
|
||||||
Oid save_uid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The query is always run against the FK table except
|
* The query is always run against the FK table except
|
||||||
@ -3185,14 +3196,14 @@ ri_PlanCheck(char *querystr, int nargs, Oid *argtypes,
|
|||||||
query_rel = fk_rel;
|
query_rel = fk_rel;
|
||||||
|
|
||||||
/* Switch to proper UID to perform check as */
|
/* Switch to proper UID to perform check as */
|
||||||
save_uid = GetUserId();
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
SetUserId(RelationGetForm(query_rel)->relowner);
|
SetUserIdAndContext(RelationGetForm(query_rel)->relowner, true);
|
||||||
|
|
||||||
/* Create the plan */
|
/* Create the plan */
|
||||||
qplan = SPI_prepare(querystr, nargs, argtypes);
|
qplan = SPI_prepare(querystr, nargs, argtypes);
|
||||||
|
|
||||||
/* Restore UID */
|
/* Restore UID */
|
||||||
SetUserId(save_uid);
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
/* Save the plan if requested */
|
/* Save the plan if requested */
|
||||||
if (cache_plan)
|
if (cache_plan)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.63 2002/10/04 17:19:55 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.63.2.1 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -651,6 +651,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
|||||||
FmgrInfo *save_flinfo;
|
FmgrInfo *save_flinfo;
|
||||||
struct fmgr_security_definer_cache *fcache;
|
struct fmgr_security_definer_cache *fcache;
|
||||||
Oid save_userid;
|
Oid save_userid;
|
||||||
|
bool save_secdefcxt;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
if (!fcinfo->flinfo->fn_extra)
|
if (!fcinfo->flinfo->fn_extra)
|
||||||
@ -673,16 +674,18 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
|||||||
else
|
else
|
||||||
fcache = fcinfo->flinfo->fn_extra;
|
fcache = fcinfo->flinfo->fn_extra;
|
||||||
|
|
||||||
|
GetUserIdAndContext(&save_userid, &save_secdefcxt);
|
||||||
|
SetUserIdAndContext(fcache->userid, true);
|
||||||
|
|
||||||
save_flinfo = fcinfo->flinfo;
|
save_flinfo = fcinfo->flinfo;
|
||||||
fcinfo->flinfo = &fcache->flinfo;
|
fcinfo->flinfo = &fcache->flinfo;
|
||||||
|
|
||||||
save_userid = GetUserId();
|
|
||||||
SetUserId(fcache->userid);
|
|
||||||
result = FunctionCallInvoke(fcinfo);
|
result = FunctionCallInvoke(fcinfo);
|
||||||
SetUserId(save_userid);
|
|
||||||
|
|
||||||
fcinfo->flinfo = save_flinfo;
|
fcinfo->flinfo = save_flinfo;
|
||||||
|
|
||||||
|
SetUserIdAndContext(save_userid, save_secdefcxt);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.96 2002/09/04 20:31:31 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.96.2.1 2008/01/03 21:25:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -483,6 +483,9 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir)
|
|||||||
* are implemented. Conceptually there is a stack, whose bottom
|
* are implemented. Conceptually there is a stack, whose bottom
|
||||||
* is the session user. You are yourself responsible to save and
|
* is the session user. You are yourself responsible to save and
|
||||||
* restore the current user id if you need to change it.
|
* restore the current user id if you need to change it.
|
||||||
|
*
|
||||||
|
* SecurityDefinerContext is TRUE if we are within a SECURITY DEFINER function
|
||||||
|
* or another context that temporarily changes CurrentUserId.
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
static Oid AuthenticatedUserId = InvalidOid;
|
static Oid AuthenticatedUserId = InvalidOid;
|
||||||
@ -491,8 +494,13 @@ static Oid CurrentUserId = InvalidOid;
|
|||||||
|
|
||||||
static bool AuthenticatedUserIsSuperuser = false;
|
static bool AuthenticatedUserIsSuperuser = false;
|
||||||
|
|
||||||
|
static bool SecurityDefinerContext = false;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is relevant for all privilege checks.
|
* GetUserId - get the current effective user ID.
|
||||||
|
*
|
||||||
|
* Note: there's no SetUserId() anymore; use SetUserIdAndContext().
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
GetUserId(void)
|
GetUserId(void)
|
||||||
@ -502,14 +510,6 @@ GetUserId(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SetUserId(Oid newid)
|
|
||||||
{
|
|
||||||
AssertArg(OidIsValid(newid));
|
|
||||||
CurrentUserId = newid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This value is only relevant for informational purposes.
|
* This value is only relevant for informational purposes.
|
||||||
*/
|
*/
|
||||||
@ -521,17 +521,57 @@ GetSessionUserId(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
SetSessionUserId(Oid newid)
|
SetSessionUserId(Oid newid)
|
||||||
{
|
{
|
||||||
|
AssertState(!SecurityDefinerContext);
|
||||||
AssertArg(OidIsValid(newid));
|
AssertArg(OidIsValid(newid));
|
||||||
SessionUserId = newid;
|
SessionUserId = newid;
|
||||||
/* Current user defaults to session user. */
|
CurrentUserId = newid;
|
||||||
if (!OidIsValid(CurrentUserId))
|
|
||||||
CurrentUserId = newid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetUserIdAndContext/SetUserIdAndContext - get/set the current user ID
|
||||||
|
* and the SecurityDefinerContext flag.
|
||||||
|
*
|
||||||
|
* Unlike GetUserId, GetUserIdAndContext does *not* Assert that the current
|
||||||
|
* value of CurrentUserId is valid; nor does SetUserIdAndContext require
|
||||||
|
* the new value to be valid. In fact, these routines had better not
|
||||||
|
* ever throw any kind of error. This is because they are used by
|
||||||
|
* StartTransaction and AbortTransaction to save/restore the settings,
|
||||||
|
* and during the first transaction within a backend, the value to be saved
|
||||||
|
* and perhaps restored is indeed invalid. We have to be able to get
|
||||||
|
* through AbortTransaction without asserting in case InitPostgres fails.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
GetUserIdAndContext(Oid *userid, bool *sec_def_context)
|
||||||
|
{
|
||||||
|
*userid = CurrentUserId;
|
||||||
|
*sec_def_context = SecurityDefinerContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetUserIdAndContext(Oid userid, bool sec_def_context)
|
||||||
|
{
|
||||||
|
CurrentUserId = userid;
|
||||||
|
SecurityDefinerContext = sec_def_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InSecurityDefinerContext - are we inside a SECURITY DEFINER context?
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
InSecurityDefinerContext(void)
|
||||||
|
{
|
||||||
|
return SecurityDefinerContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize user identity during normal backend startup
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
InitializeSessionUserId(const char *username)
|
InitializeSessionUserId(const char *username)
|
||||||
{
|
{
|
||||||
@ -616,7 +656,6 @@ SetSessionAuthorization(Oid userid)
|
|||||||
elog(ERROR, "permission denied");
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
SetSessionUserId(userid);
|
SetSessionUserId(userid);
|
||||||
SetUserId(userid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, 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.111 2002/10/03 17:07:53 momjian Exp $
|
* $Id: miscadmin.h,v 1.111.2.1 2008/01/03 21:25:58 tgl 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
|
||||||
@ -203,9 +203,10 @@ extern void SetDatabasePath(const char *path);
|
|||||||
extern char *GetUserNameFromId(Oid userid);
|
extern char *GetUserNameFromId(Oid userid);
|
||||||
|
|
||||||
extern Oid GetUserId(void);
|
extern Oid GetUserId(void);
|
||||||
extern void SetUserId(Oid userid);
|
|
||||||
extern Oid GetSessionUserId(void);
|
extern Oid GetSessionUserId(void);
|
||||||
extern void SetSessionUserId(Oid userid);
|
extern void GetUserIdAndContext(Oid *userid, bool *sec_def_context);
|
||||||
|
extern void SetUserIdAndContext(Oid userid, bool sec_def_context);
|
||||||
|
extern bool InSecurityDefinerContext(void);
|
||||||
extern void InitializeSessionUserId(const char *username);
|
extern void InitializeSessionUserId(const char *username);
|
||||||
extern void InitializeSessionUserIdStandalone(void);
|
extern void InitializeSessionUserIdStandalone(void);
|
||||||
extern void SetSessionAuthorization(Oid userid);
|
extern void SetSessionAuthorization(Oid userid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user