diff options
author | Stephen Frost <sfrost@snowman.net> | 2015-10-04 21:05:08 -0400 |
---|---|---|
committer | Stephen Frost <sfrost@snowman.net> | 2015-10-04 21:05:08 -0400 |
commit | 088c83363a11200f2225f279d4a5c6cc6f9db3d2 (patch) | |
tree | f5568ba1294ab5695d5f67b9f79f96130e60c44a /src/backend/commands/tablecmds.c | |
parent | 16a70e3059885739f59ccdaa20f2e4a3b2a0a700 (diff) | |
download | postgresql-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.c | 40 |
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 |