aboutsummaryrefslogtreecommitdiff
path: root/src/backend/foreign/foreign.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-01-28 14:05:36 -0500
committerRobert Haas <rhaas@postgresql.org>2016-01-28 14:05:36 -0500
commitfbe5a3fb73102c2cfec11aaaa4a67943f4474383 (patch)
tree44b327ff5aaceb5a20346ee4c914914450e51368 /src/backend/foreign/foreign.c
parent2f6b041f76e6de0fa2921131a23bda794ffb83bb (diff)
downloadpostgresql-fbe5a3fb73102c2cfec11aaaa4a67943f4474383.tar.gz
postgresql-fbe5a3fb73102c2cfec11aaaa4a67943f4474383.zip
Only try to push down foreign joins if the user mapping OIDs match.
Previously, the foreign join pushdown infrastructure left the question of security entirely up to individual FDWs, but it would be easy for a foreign data wrapper to inadvertently open up subtle security holes that way. So, make it the core code's job to determine which user mapping OID is relevant, and don't attempt join pushdown unless it's the same for all relevant relations. Per a suggestion from Tom Lane. Shigeru Hanada and Ashutosh Bapat, reviewed by Etsuro Fujita and KaiGai Kohei, with some further changes by me.
Diffstat (limited to 'src/backend/foreign/foreign.c')
-rw-r--r--src/backend/foreign/foreign.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index c24b11b685c..47c00af74f9 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -31,6 +31,7 @@
extern Datum pg_options_to_table(PG_FUNCTION_ARGS);
extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS);
+static HeapTuple find_user_mapping(Oid userid, Oid serverid);
/*
* GetForeignDataWrapper - look up the foreign-data wrapper by OID.
@@ -174,23 +175,7 @@ GetUserMapping(Oid userid, Oid serverid)
bool isnull;
UserMapping *um;
- tp = SearchSysCache2(USERMAPPINGUSERSERVER,
- ObjectIdGetDatum(userid),
- ObjectIdGetDatum(serverid));
-
- if (!HeapTupleIsValid(tp))
- {
- /* Not found for the specific user -- try PUBLIC */
- tp = SearchSysCache2(USERMAPPINGUSERSERVER,
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(serverid));
- }
-
- if (!HeapTupleIsValid(tp))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user mapping not found for \"%s\"",
- MappingUserName(userid))));
+ tp = find_user_mapping(userid, serverid);
um = (UserMapping *) palloc(sizeof(UserMapping));
um->umid = HeapTupleGetOid(tp);
@@ -212,6 +197,61 @@ GetUserMapping(Oid userid, Oid serverid)
return um;
}
+/*
+ * GetUserMappingId - look up the user mapping, and return its OID
+ *
+ * If no mapping is found for the supplied user, we also look for
+ * PUBLIC mappings (userid == InvalidOid).
+ */
+Oid
+GetUserMappingId(Oid userid, Oid serverid)
+{
+ HeapTuple tp;
+ Oid umid;
+
+ tp = find_user_mapping(userid, serverid);
+
+ /* Extract the Oid */
+ umid = HeapTupleGetOid(tp);
+
+ ReleaseSysCache(tp);
+
+ return umid;
+}
+
+
+/*
+ * find_user_mapping - Guts of GetUserMapping family.
+ *
+ * If no mapping is found for the supplied user, we also look for
+ * PUBLIC mappings (userid == InvalidOid).
+ */
+static HeapTuple
+find_user_mapping(Oid userid, Oid serverid)
+{
+ HeapTuple tp;
+
+ tp = SearchSysCache2(USERMAPPINGUSERSERVER,
+ ObjectIdGetDatum(userid),
+ ObjectIdGetDatum(serverid));
+
+ if (HeapTupleIsValid(tp))
+ return tp;
+
+ /* Not found for the specific user -- try PUBLIC */
+ tp = SearchSysCache2(USERMAPPINGUSERSERVER,
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(serverid));
+
+ if (!HeapTupleIsValid(tp))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("user mapping not found for \"%s\"",
+ MappingUserName(userid))));
+
+ return tp;
+}
+
/*
* GetForeignTable - look up the foreign table definition by relation oid.