aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/analyze.c21
-rw-r--r--src/backend/commands/schemacmds.c13
-rw-r--r--src/backend/commands/vacuum.c15
-rw-r--r--src/backend/commands/variable.c37
4 files changed, 74 insertions, 12 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index e5cf86621de..d694600dc7b 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.89.2.1 2005/11/22 18:23:06 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.89.2.2 2008/01/03 21:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -112,6 +112,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
double totalrows,
totaldeadrows;
HeapTuple *rows;
+ Oid save_userid;
+ bool save_secdefcxt;
if (vacstmt->verbose)
elevel = INFO;
@@ -200,6 +202,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
RelationGetRelationName(onerel))));
/*
+ * Switch to the table owner's userid, so that any index functions are
+ * run as that user.
+ */
+ GetUserIdAndContext(&save_userid, &save_secdefcxt);
+ SetUserIdAndContext(onerel->rd_rel->relowner, true);
+
+ /*
* Determine which columns to analyze
*
* Note that system attributes are never analyzed.
@@ -318,9 +327,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
onerel->rd_rel->relisshared,
0, 0);
- vac_close_indexes(nindexes, Irel, AccessShareLock);
- relation_close(onerel, AccessShareLock);
- return;
+ goto cleanup;
}
/*
@@ -439,6 +446,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
totalrows, totaldeadrows);
}
+ /* We skip to here if there were no analyzable columns */
+cleanup:
+
/* Done with indexes */
vac_close_indexes(nindexes, Irel, NoLock);
@@ -448,6 +458,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
* we made in pg_statistic.)
*/
relation_close(onerel, NoLock);
+
+ /* Restore userid */
+ SetUserIdAndContext(save_userid, save_secdefcxt);
}
/*
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 56a3359a532..957d50d7fa7 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.35 2005/10/15 02:49:15 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.35.2.1 2008/01/03 21:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,9 +44,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
ListCell *parsetree_item;
Oid owner_uid;
Oid saved_uid;
+ bool saved_secdefcxt;
AclResult aclresult;
- saved_uid = GetUserId();
+ GetUserIdAndContext(&saved_uid, &saved_secdefcxt);
/*
* Who is supposed to own the new schema?
@@ -82,11 +83,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
* temporarily set the current user so that the object(s) will be created
* with the correct ownership.
*
- * (The setting will revert to session user on error or at the end of this
- * routine.)
+ * (The setting will be restored at the end of this routine, or in case
+ * of error, transaction abort will clean things up.)
*/
if (saved_uid != owner_uid)
- SetUserId(owner_uid);
+ SetUserIdAndContext(owner_uid, true);
/* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_uid);
@@ -138,7 +139,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
PopSpecialNamespace(namespaceId);
/* Reset current user */
- SetUserId(saved_uid);
+ SetUserIdAndContext(saved_uid, saved_secdefcxt);
}
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 80c1e31121b..39d769aaa8a 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.317.2.5 2007/06/14 13:54:40 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.317.2.6 2008/01/03 21:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -961,6 +961,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
LockRelId onerelid;
Oid toast_relid;
bool result;
+ Oid save_userid;
+ bool save_secdefcxt;
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
@@ -1072,6 +1074,14 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
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
*/
if (vacstmt->full)
@@ -1081,6 +1091,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
result = true; /* did the vacuum */
+ /* Restore userid */
+ SetUserIdAndContext(save_userid, save_secdefcxt);
+
/* all done with this class, but hold lock until commit */
relation_close(onerel, NoLock);
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index ca47fbef639..458b0a3a169 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.114.2.2 2006/02/12 22:32:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.114.2.3 2008/01/03 21:24:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -623,6 +623,22 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
/* not a saved ID, so look it up */
HeapTuple roleTup;
+ 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 (source >= PGC_S_INTERACTIVE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot set session authorization within security-definer function")));
+ return NULL;
+ }
+
if (!IsTransactionState())
{
/*
@@ -730,6 +746,25 @@ assign_role(const char *value, bool doit, GucSource source)
}
}
+ if (roleid == InvalidOid && InSecurityDefinerContext())
+ {
+ /*
+ * Disallow SET ROLE 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 arranged so
+ * that restoring a previously saved setting isn't prevented.
+ *
+ * XXX it would be nice to allow this case in future, with the
+ * behavior being that the SET ROLE's effects end when the security
+ * definer context is exited.
+ */
+ if (source >= PGC_S_INTERACTIVE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot set role within security-definer function")));
+ return NULL;
+ }
+
if (roleid == InvalidOid &&
strcmp(actual_rolename, "none") != 0)
{