aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2015-10-04 21:05:08 -0400
committerStephen Frost <sfrost@snowman.net>2015-10-04 21:05:08 -0400
commit088c83363a11200f2225f279d4a5c6cc6f9db3d2 (patch)
treef5568ba1294ab5695d5f67b9f79f96130e60c44a /src/backend/commands/tablecmds.c
parent16a70e3059885739f59ccdaa20f2e4a3b2a0a700 (diff)
downloadpostgresql-088c83363a11200f2225f279d4a5c6cc6f9db3d2.tar.gz
postgresql-088c83363a11200f2225f279d4a5c6cc6f9db3d2.zip
ALTER TABLE .. FORCE ROW LEVEL SECURITY
To allow users to force RLS to always be applied, even for table owners, add ALTER TABLE .. FORCE ROW LEVEL SECURITY. row_security=off overrides FORCE ROW LEVEL SECURITY, to ensure pg_dump output is complete (by default). Also add SECURITY_NOFORCE_RLS context to avoid data corruption when ALTER TABLE .. FORCE ROW SECURITY is being used. The SECURITY_NOFORCE_RLS security context is used only during referential integrity checks and is only considered in check_enable_rls() after we have already checked that the current user is the owner of the relation (which should always be the case during referential integrity checks). Back-patch to 9.5 where RLS was added.
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 126b11923f0..7668c9d771f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -419,6 +419,7 @@ static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKM
static void ATExecGenericOptions(Relation rel, List *options);
static void ATExecEnableRowSecurity(Relation rel);
static void ATExecDisableRowSecurity(Relation rel);
+static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls);
static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
ForkNumber forkNum, char relpersistence);
@@ -2930,6 +2931,8 @@ AlterTableGetLockLevel(List *cmds)
case AT_SetNotNull:
case AT_EnableRowSecurity:
case AT_DisableRowSecurity:
+ case AT_ForceRowSecurity:
+ case AT_NoForceRowSecurity:
cmd_lockmode = AccessExclusiveLock;
break;
@@ -3351,6 +3354,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
case AT_DropOf: /* NOT OF */
case AT_EnableRowSecurity:
case AT_DisableRowSecurity:
+ case AT_ForceRowSecurity:
+ case AT_NoForceRowSecurity:
ATSimplePermissions(rel, ATT_TABLE);
/* These commands never recurse */
/* No command-specific prep needed */
@@ -3667,6 +3672,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
case AT_DisableRowSecurity:
ATExecDisableRowSecurity(rel);
break;
+ case AT_ForceRowSecurity:
+ ATExecForceNoForceRowSecurity(rel, true);
+ break;
+ case AT_NoForceRowSecurity:
+ ATExecForceNoForceRowSecurity(rel, false);
+ break;
case AT_GenericOptions:
ATExecGenericOptions(rel, (List *) cmd->def);
break;
@@ -11067,6 +11078,35 @@ ATExecDisableRowSecurity(Relation rel)
}
/*
+ * ALTER TABLE FORCE/NO FORCE ROW LEVEL SECURITY
+ */
+static void
+ATExecForceNoForceRowSecurity(Relation rel, bool force_rls)
+{
+ Relation pg_class;
+ Oid relid;
+ HeapTuple tuple;
+
+ relid = RelationGetRelid(rel);
+
+ pg_class = heap_open(RelationRelationId, RowExclusiveLock);
+
+ tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
+
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for relation %u", relid);
+
+ ((Form_pg_class) GETSTRUCT(tuple))->relforcerowsecurity = force_rls;
+ simple_heap_update(pg_class, &tuple->t_self, tuple);
+
+ /* keep catalog indexes current */
+ CatalogUpdateIndexes(pg_class, tuple);
+
+ heap_close(pg_class, RowExclusiveLock);
+ heap_freetuple(tuple);
+}
+
+/*
* ALTER FOREIGN TABLE <name> OPTIONS (...)
*/
static void