aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/matview.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2013-07-12 18:21:22 -0400
committerNoah Misch <noah@leadboat.com>2013-07-12 18:21:22 -0400
commitf3ab5d46960023cf8a9df3751ab9748ce01a46a0 (patch)
tree484f5381fe26bd82dd20889a4c5bc1d8b974e948 /src/backend/commands/matview.c
parent448fee2e238ae4797e68d7d15b49f2fc52691547 (diff)
downloadpostgresql-f3ab5d46960023cf8a9df3751ab9748ce01a46a0.tar.gz
postgresql-f3ab5d46960023cf8a9df3751ab9748ce01a46a0.zip
Switch user ID to the object owner when populating a materialized view.
This makes superuser-issued REFRESH MATERIALIZED VIEW safe regardless of the object's provenance. REINDEX is an earlier example of this pattern. As a downside, functions called from materialized views must tolerate running in a security-restricted operation. CREATE MATERIALIZED VIEW need not change user ID. Nonetheless, avoid creation of materialized views that will invariably fail REFRESH by making it, too, start a security-restricted operation. Back-patch to 9.3 so materialized views have this from the beginning. Reviewed by Kevin Grittner.
Diffstat (limited to 'src/backend/commands/matview.c')
-rw-r--r--src/backend/commands/matview.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 2ffdca31f6b..1c383baf687 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -122,6 +122,9 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
RewriteRule *rule;
List *actions;
Query *dataQuery;
+ Oid save_userid;
+ int save_sec_context;
+ int save_nestlevel;
Oid tableSpace;
Oid OIDNewHeap;
DestReceiver *dest;
@@ -192,6 +195,16 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW");
/*
+ * Switch to the owner's userid, so that any functions are run as that
+ * user. Also lock down security-restricted operations and arrange to
+ * make GUC variable changes local to this command.
+ */
+ GetUserIdAndSecContext(&save_userid, &save_sec_context);
+ SetUserIdAndSecContext(matviewRel->rd_rel->relowner,
+ save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ save_nestlevel = NewGUCNestLevel();
+
+ /*
* Tentatively mark the matview as populated or not (this will roll back
* if we fail later).
*/
@@ -217,6 +230,12 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
RecentXmin, ReadNextMultiXactId());
RelationCacheInvalidateEntry(matviewOid);
+
+ /* Roll back any GUC changes */
+ AtEOXact_GUC(false, save_nestlevel);
+
+ /* Restore userid and security context */
+ SetUserIdAndSecContext(save_userid, save_sec_context);
}
/*