PostgreSQL Source Code  git master
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

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 };
Definition: rls.h:43

Function Documentation

◆ check_enable_rls()

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

Definition at line 52 of file rls.c.

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

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

53 {
54  Oid user_id = checkAsUser ? checkAsUser : GetUserId();
55  HeapTuple tuple;
56  Form_pg_class classform;
57  bool relrowsecurity;
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 = pg_class_ownercheck(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 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Oid GetUserId(void)
Definition: miscinit.c:379
int errcode(int sqlerrcode)
Definition: elog.c:575
bool InNoForceRLSOperation(void)
Definition: miscinit.c:520
unsigned int Oid
Definition: postgres_ext.h:31
#define FirstNormalObjectId
Definition: transam.h:94
bool has_bypassrls_privilege(Oid roleid)
Definition: aclchk.c:5395
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
bool relforcerowsecurity
Definition: pg_class.h:65
bool relrowsecurity
Definition: pg_class.h:64
#define ereport(elevel, rest)
Definition: elog.h:122
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
bool row_security
Definition: guc.c:448
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4751
FormData_pg_class * Form_pg_class
Definition: pg_class.h:93
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: rls.h:43
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730

Variable Documentation

◆ row_security

bool row_security

Definition at line 448 of file guc.c.

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