diff options
author | Noah Misch <noah@leadboat.com> | 2013-07-12 18:21:22 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2013-07-12 18:21:22 -0400 |
commit | f3ab5d46960023cf8a9df3751ab9748ce01a46a0 (patch) | |
tree | 484f5381fe26bd82dd20889a4c5bc1d8b974e948 /src/backend/commands/matview.c | |
parent | 448fee2e238ae4797e68d7d15b49f2fc52691547 (diff) | |
download | postgresql-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.c | 19 |
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); } /* |