diff options
Diffstat (limited to 'src/backend/rewrite/rowsecurity.c')
-rw-r--r-- | src/backend/rewrite/rowsecurity.c | 81 |
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 */ |