diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/analyze.c | 21 | ||||
-rw-r--r-- | src/backend/commands/schemacmds.c | 13 | ||||
-rw-r--r-- | src/backend/commands/vacuum.c | 15 | ||||
-rw-r--r-- | src/backend/commands/variable.c | 37 |
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) { |