PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rls.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  CheckEnableRlsResult { RLS_NONE , RLS_NONE_ENV , RLS_ENABLED }
 

Functions

int check_enable_rls (Oid relid, Oid checkAsUser, bool noError)
 

Variables

PGDLLIMPORT bool row_security
 

Enumeration Type Documentation

◆ CheckEnableRlsResult

Enumerator
RLS_NONE 
RLS_NONE_ENV 
RLS_ENABLED 

Definition at line 41 of file rls.h.

42 {
43  RLS_NONE,
46 };
@ RLS_NONE
Definition: rls.h:43
@ RLS_NONE_ENV
Definition: rls.h:44
@ RLS_ENABLED
Definition: rls.h:45

Function Documentation

◆ check_enable_rls()

int check_enable_rls ( Oid  relid,
Oid  checkAsUser,
bool  noError 
)

Definition at line 52 of file rls.c.

53 {
54  Oid user_id = OidIsValid(checkAsUser) ? checkAsUser : GetUserId();
55  HeapTuple tuple;
56  Form_pg_class classform;
57  bool relrowsecurity;
58  bool relforcerowsecurity;
59  bool amowner;
60 
61  /* Nothing to do for built-in relations */
62  if (relid < (Oid) FirstNormalObjectId)
63  return RLS_NONE;
64 
65  /* Fetch relation's relrowsecurity and relforcerowsecurity flags */
66  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
67  if (!HeapTupleIsValid(tuple))
68  return RLS_NONE;
69  classform = (Form_pg_class) GETSTRUCT(tuple);
70 
71  relrowsecurity = classform->relrowsecurity;
72  relforcerowsecurity = classform->relforcerowsecurity;
73 
74  ReleaseSysCache(tuple);
75 
76  /* Nothing to do if the relation does not have RLS */
77  if (!relrowsecurity)
78  return RLS_NONE;
79 
80  /*
81  * BYPASSRLS users always bypass RLS. Note that superusers are always
82  * considered to have BYPASSRLS.
83  *
84  * Return RLS_NONE_ENV to indicate that this decision depends on the
85  * environment (in this case, the user_id).
86  */
87  if (has_bypassrls_privilege(user_id))
88  return RLS_NONE_ENV;
89 
90  /*
91  * Table owners generally bypass RLS, except if the table has been set (by
92  * an owner) to FORCE ROW SECURITY, and this is not a referential
93  * integrity check.
94  *
95  * Return RLS_NONE_ENV to indicate that this decision depends on the
96  * environment (in this case, the user_id).
97  */
98  amowner = object_ownercheck(RelationRelationId, relid, user_id);
99  if (amowner)
100  {
101  /*
102  * If FORCE ROW LEVEL SECURITY has been set on the relation then we
103  * should return RLS_ENABLED to indicate that RLS should be applied.
104  * If not, or if we are in an InNoForceRLSOperation context, we return
105  * RLS_NONE_ENV.
106  *
107  * InNoForceRLSOperation indicates that we should not apply RLS even
108  * if the table has FORCE RLS set - IF the current user is the owner.
109  * This is specifically to ensure that referential integrity checks
110  * are able to still run correctly.
111  *
112  * This is intentionally only done after we have checked that the user
113  * is the table owner, which should always be the case for referential
114  * integrity checks.
115  */
116  if (!relforcerowsecurity || InNoForceRLSOperation())
117  return RLS_NONE_ENV;
118  }
119 
120  /*
121  * We should apply RLS. However, the user may turn off the row_security
122  * GUC to get a forced error instead.
123  */
124  if (!row_security && !noError)
125  ereport(ERROR,
126  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
127  errmsg("query would be affected by row-level security policy for table \"%s\"",
128  get_rel_name(relid)),
129  amowner ? errhint("To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY.") : 0));
130 
131  /* RLS should be fully enabled for this relation. */
132  return RLS_ENABLED;
133 }
bool has_bypassrls_privilege(Oid roleid)
Definition: aclchk.c:4164
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4064
#define OidIsValid(objectId)
Definition: c.h:780
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool row_security
Definition: guc_tables.c:510
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1928
Oid GetUserId(void)
Definition: miscinit.c:524
bool InNoForceRLSOperation(void)
Definition: miscinit.c:703
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
unsigned int Oid
Definition: postgres_ext.h:31
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
#define FirstNormalObjectId
Definition: transam.h:197

References ereport, errcode(), errhint(), errmsg(), ERROR, FirstNormalObjectId, get_rel_name(), GETSTRUCT, GetUserId(), has_bypassrls_privilege(), HeapTupleIsValid, InNoForceRLSOperation(), object_ownercheck(), ObjectIdGetDatum(), OidIsValid, ReleaseSysCache(), RLS_ENABLED, RLS_NONE, RLS_NONE_ENV, row_security, and SearchSysCache1().

Referenced by BuildIndexValueDescription(), DoCopy(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), get_row_security_policies(), intorel_startup(), LogicalRepSyncTableStart(), ri_ReportViolation(), row_security_active(), row_security_active_name(), and TargetPrivilegesCheck().

Variable Documentation

◆ row_security

PGDLLIMPORT bool row_security
extern

Definition at line 510 of file guc_tables.c.

Referenced by check_enable_rls(), CompleteCachedPlan(), and RevalidateCachedQuery().