summaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rowsecurity.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rowsecurity.c')
-rw-r--r--src/backend/rewrite/rowsecurity.c81
1 files changed, 2 insertions, 79 deletions
diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c
index 8f8e291fb88..7669130e2b6 100644
--- a/src/backend/rewrite/rowsecurity.c
+++ b/src/backend/rewrite/rowsecurity.c
@@ -52,6 +52,7 @@
#include "utils/acl.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
+#include "utils/rls.h"
#include "utils/syscache.h"
#include "tcop/utility.h"
@@ -115,7 +116,7 @@ prepend_row_security_policies(Query* root, RangeTblEntry* rte, int rt_index)
return false;
/* Determine the state of RLS for this, pass checkAsUser explicitly */
- rls_status = check_enable_rls(rte->relid, rte->checkAsUser);
+ rls_status = check_enable_rls(rte->relid, rte->checkAsUser, false);
/* If there is no RLS on this table at all, nothing to do */
if (rls_status == RLS_NONE)
@@ -456,84 +457,6 @@ process_policies(List *policies, int rt_index, Expr **qual_eval,
}
/*
- * check_enable_rls
- *
- * Determine, based on the relation, row_security setting, and current role,
- * if RLS is applicable to this query. RLS_NONE_ENV indicates that, while
- * RLS is not to be added for this query, a change in the environment may change
- * that. RLS_NONE means that RLS is not on the relation at all and therefore
- * we don't need to worry about it. RLS_ENABLED means RLS should be implemented
- * for the table and the plan cache needs to be invalidated if the environment
- * changes.
- *
- * Handle checking as another role via checkAsUser (for views, etc).
- */
-int
-check_enable_rls(Oid relid, Oid checkAsUser)
-{
- HeapTuple tuple;
- Form_pg_class classform;
- bool relrowsecurity;
- Oid user_id = checkAsUser ? checkAsUser : GetUserId();
-
- tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
- if (!HeapTupleIsValid(tuple))
- return RLS_NONE;
-
- classform = (Form_pg_class) GETSTRUCT(tuple);
-
- relrowsecurity = classform->relrowsecurity;
-
- ReleaseSysCache(tuple);
-
- /* Nothing to do if the relation does not have RLS */
- if (!relrowsecurity)
- return RLS_NONE;
-
- /*
- * Check permissions
- *
- * If the relation has row level security enabled and the row_security GUC
- * is off, then check if the user has rights to bypass RLS for this
- * relation. Table owners can always bypass, as can any role with the
- * BYPASSRLS capability.
- *
- * If the role is the table owner, then we bypass RLS unless row_security
- * is set to 'force'. Note that superuser is always considered an owner.
- *
- * Return RLS_NONE_ENV to indicate that this decision depends on the
- * environment (in this case, what the current values of user_id and
- * row_security are).
- */
- if (row_security != ROW_SECURITY_FORCE
- && (pg_class_ownercheck(relid, user_id)))
- return RLS_NONE_ENV;
-
- /*
- * If the row_security GUC is 'off' then check if the user has permission
- * to bypass it. Note that we have already handled the case where the user
- * is the table owner above.
- *
- * Note that row_security is always considered 'on' when querying
- * through a view or other cases where checkAsUser is true, so skip this
- * if checkAsUser is in use.
- */
- if (!checkAsUser && row_security == ROW_SECURITY_OFF)
- {
- if (has_bypassrls_privilege(user_id))
- /* OK to bypass */
- return RLS_NONE_ENV;
- else
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("insufficient privilege to bypass row security.")));
- }
-
- /* RLS should be fully enabled for this relation. */
- return RLS_ENABLED;
-}
-
-/*
* check_role_for_policy -
* determines if the policy should be applied for the current role
*/