aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/foreign/foreign.c10
-rw-r--r--src/backend/optimizer/plan/createplan.c13
-rw-r--r--src/backend/optimizer/util/plancat.c12
-rw-r--r--src/backend/rewrite/rewriteHandler.c17
-rw-r--r--src/backend/tcop/postgres.c64
-rw-r--r--src/backend/utils/misc/guc.c12
6 files changed, 128 insertions, 0 deletions
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index e60394c7f90..9875547a31a 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -23,6 +23,7 @@
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
+#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/rel.h"
@@ -322,6 +323,15 @@ GetFdwRoutine(Oid fdwhandler)
Datum datum;
FdwRoutine *routine;
+ /* Check if the access to foreign tables is restricted */
+ if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0))
+ {
+ /* there must not be built-in FDW handler */
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("access to non-system foreign table is restricted")));
+ }
+
datum = OidFunctionCall0(fdwhandler);
routine = (FdwRoutine *) DatumGetPointer(datum);
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 1bc59c94578..f91562cbea3 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -40,6 +40,7 @@
#include "parser/parse_clause.h"
#include "parser/parsetree.h"
#include "partitioning/partprune.h"
+#include "tcop/tcopprot.h"
#include "utils/lsyscache.h"
@@ -7111,7 +7112,19 @@ make_modifytable(PlannerInfo *root, Plan *subplan,
Assert(rte->rtekind == RTE_RELATION);
Assert(operation != CMD_MERGE);
if (rte->relkind == RELKIND_FOREIGN_TABLE)
+ {
+ /* Check if the access to foreign tables is restricted */
+ if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0))
+ {
+ /* there must not be built-in foreign tables */
+ Assert(rte->relid >= FirstNormalObjectId);
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("access to non-system foreign table is restricted")));
+ }
+
fdwroutine = GetFdwRoutineByRelId(rte->relid);
+ }
else
fdwroutine = NULL;
}
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 4b4d3c3e074..7d2f403212f 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -47,6 +47,7 @@
#include "rewrite/rewriteManip.h"
#include "statistics/statistics.h"
#include "storage/bufmgr.h"
+#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/partcache.h"
@@ -465,6 +466,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
/* Grab foreign-table info using the relcache, while we have it */
if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
{
+ /* Check if the access to foreign tables is restricted */
+ if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_FOREIGN_TABLE) != 0))
+ {
+ /* there must not be built-in foreign tables */
+ Assert(RelationGetRelid(relation) >= FirstNormalObjectId);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("access to non-system foreign table is restricted")));
+ }
+
rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
}
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index a7722f96036..7c715258be3 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -41,6 +41,7 @@
#include "rewrite/rewriteManip.h"
#include "rewrite/rewriteSearchCycle.h"
#include "rewrite/rowsecurity.h"
+#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
@@ -1734,6 +1735,14 @@ ApplyRetrieveRule(Query *parsetree,
if (rule->qual != NULL)
elog(ERROR, "cannot handle qualified ON SELECT rule");
+ /* Check if the expansion of non-system views are restricted */
+ if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 &&
+ RelationGetRelid(relation) >= FirstNormalObjectId))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("access to non-system view \"%s\" is restricted",
+ RelationGetRelationName(relation))));
+
if (rt_index == parsetree->resultRelation)
{
/*
@@ -3128,6 +3137,14 @@ rewriteTargetView(Query *parsetree, Relation view)
}
}
+ /* Check if the expansion of non-system views are restricted */
+ if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 &&
+ RelationGetRelid(view) >= FirstNormalObjectId))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("access to non-system view \"%s\" is restricted",
+ RelationGetRelationName(view))));
+
/*
* For INSERT/UPDATE the modified columns must all be updatable.
*/
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 66294ab4c8b..d3aba33043c 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -81,6 +81,7 @@
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
+#include "utils/varlena.h"
/* ----------------
* global variables
@@ -105,6 +106,9 @@ int PostAuthDelay = 0;
/* Time between checks that the client is still connected. */
int client_connection_check_interval = 0;
+/* flags for non-system relation kinds to restrict use */
+int restrict_nonsystem_relation_kind;
+
/* ----------------
* private typedefs etc
* ----------------
@@ -3601,6 +3605,66 @@ assign_max_stack_depth(int newval, void *extra)
max_stack_depth_bytes = newval_bytes;
}
+/*
+ * GUC check_hook for restrict_nonsystem_relation_kind
+ */
+bool
+check_restrict_nonsystem_relation_kind(char **newval, void **extra, GucSource source)
+{
+ char *rawstring;
+ List *elemlist;
+ ListCell *l;
+ int flags = 0;
+
+ /* Need a modifiable copy of string */
+ rawstring = pstrdup(*newval);
+
+ if (!SplitIdentifierString(rawstring, ',', &elemlist))
+ {
+ /* syntax error in list */
+ GUC_check_errdetail("List syntax is invalid.");
+ pfree(rawstring);
+ list_free(elemlist);
+ return false;
+ }
+
+ foreach(l, elemlist)
+ {
+ char *tok = (char *) lfirst(l);
+
+ if (pg_strcasecmp(tok, "view") == 0)
+ flags |= RESTRICT_RELKIND_VIEW;
+ else if (pg_strcasecmp(tok, "foreign-table") == 0)
+ flags |= RESTRICT_RELKIND_FOREIGN_TABLE;
+ else
+ {
+ GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
+ pfree(rawstring);
+ list_free(elemlist);
+ return false;
+ }
+ }
+
+ pfree(rawstring);
+ list_free(elemlist);
+
+ /* Save the flags in *extra, for use by the assign function */
+ *extra = malloc(sizeof(int));
+ *((int *) *extra) = flags;
+
+ return true;
+}
+
+/*
+ * GUC assign_hook for restrict_nonsystem_relation_kind
+ */
+void
+assign_restrict_nonsystem_relation_kind(const char *newval, void *extra)
+{
+ int *flags = (int *) extra;
+
+ restrict_nonsystem_relation_kind = *flags;
+}
/*
* set_debug_options --- apply "-d N" command line option
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 949f985a06f..acbcb8bb81b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -716,6 +716,7 @@ static char *recovery_target_string;
static char *recovery_target_xid_string;
static char *recovery_target_name_string;
static char *recovery_target_lsn_string;
+static char *restrict_nonsystem_relation_kind_string;
/* should be static, but commands/variable.c needs to get at this */
@@ -4711,6 +4712,17 @@ static struct config_string ConfigureNamesString[] =
check_backtrace_functions, assign_backtrace_functions, NULL
},
+ {
+ {"restrict_nonsystem_relation_kind", PGC_USERSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Sets relation kinds of non-system relation to restrict use"),
+ NULL,
+ GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE
+ },
+ &restrict_nonsystem_relation_kind_string,
+ "",
+ check_restrict_nonsystem_relation_kind, assign_restrict_nonsystem_relation_kind, NULL
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL