aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/lockcmds.c
diff options
context:
space:
mode:
authorDean Rasheed <dean.a.rasheed@gmail.com>2022-03-22 10:28:10 +0000
committerDean Rasheed <dean.a.rasheed@gmail.com>2022-03-22 10:28:10 +0000
commit7faa5fc84bf46ea6c543993cffb8be64dff60d25 (patch)
tree5e2f4c3b96cd77946916cd64369f3d71d8e86dc8 /src/backend/commands/lockcmds.c
parentf5576a21b0778f275d7418f6f7a44d9400ee90aa (diff)
downloadpostgresql-7faa5fc84bf46ea6c543993cffb8be64dff60d25.tar.gz
postgresql-7faa5fc84bf46ea6c543993cffb8be64dff60d25.zip
Add support for security invoker views.
A security invoker view checks permissions for accessing its underlying base relations using the privileges of the user of the view, rather than the privileges of the view owner. Additionally, if any of the base relations are tables with RLS enabled, the policies of the user of the view are applied, rather than those of the view owner. This allows views to be defined without giving away additional privileges on the underlying base relations, and matches a similar feature available in other database systems. It also allows views to operate more naturally with RLS, without affecting the assignments of policies to users. Christoph Heiss, with some additional hacking by me. Reviewed by Laurenz Albe and Wolfgang Walther. Discussion: https://postgr.es/m/b66dd6d6-ad3e-c6f2-8b90-47be773da240%40cybertec.at
Diffstat (limited to 'src/backend/commands/lockcmds.c')
-rw-r--r--src/backend/commands/lockcmds.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index 4b3f79704f8..b97b8b0435c 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -169,7 +169,7 @@ typedef struct
{
LOCKMODE lockmode; /* lock mode to use */
bool nowait; /* no wait mode */
- Oid viewowner; /* view owner for checking the privilege */
+ Oid check_as_user; /* user for checking the privilege */
Oid viewoid; /* OID of the view to be locked */
List *ancestor_views; /* OIDs of ancestor views */
} LockViewRecurse_context;
@@ -215,8 +215,12 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context)
if (list_member_oid(context->ancestor_views, relid))
continue;
- /* Check permissions with the view owner's privilege. */
- aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner);
+ /*
+ * Check permissions as the specified user. This will either be
+ * the view owner or the current user.
+ */
+ aclresult = LockTableAclCheck(relid, context->lockmode,
+ context->check_as_user);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_relkind_objtype(relkind), relname);
@@ -259,9 +263,16 @@ LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait,
view = table_open(reloid, NoLock);
viewquery = get_view_query(view);
+ /*
+ * If the view has the security_invoker property set, check permissions as
+ * the current user. Otherwise, check permissions as the view owner.
+ */
context.lockmode = lockmode;
context.nowait = nowait;
- context.viewowner = view->rd_rel->relowner;
+ if (RelationHasSecurityInvoker(view))
+ context.check_as_user = GetUserId();
+ else
+ context.check_as_user = view->rd_rel->relowner;
context.viewoid = reloid;
context.ancestor_views = lappend_oid(ancestor_views, reloid);