Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 22eaf35

Browse files
committed
RLS refactoring
This refactors rewrite/rowsecurity.c to simplify the handling of the default deny case (reducing the number of places where we check for and add the default deny policy from three to one) by splitting up the retrival of the policies from the application of them. This also allowed us to do away with the policy_id field. A policy_name field was added for WithCheckOption policies and is used in error reporting, when available. Patch by Dean Rasheed, with various mostly cosmetic changes by me. Back-patch to 9.5 where RLS was introduced to avoid unnecessary differences, since we're still in alpha, per discussion with Robert.
1 parent 000a213 commit 22eaf35

File tree

13 files changed

+447
-457
lines changed

13 files changed

+447
-457
lines changed

src/backend/commands/policy.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,6 @@ policy_role_list_to_array(List *roles, int *num_roles)
186186
/*
187187
* Load row security policy from the catalog, and store it in
188188
* the relation's relcache entry.
189-
*
190-
* We will always set up some kind of policy here. If no explicit policies
191-
* are found then an implicit default-deny policy is created.
192189
*/
193190
void
194191
RelationBuildRowSecurity(Relation relation)
@@ -246,7 +243,6 @@ RelationBuildRowSecurity(Relation relation)
246243
char *with_check_value;
247244
Expr *with_check_qual;
248245
char *policy_name_value;
249-
Oid policy_id;
250246
bool isnull;
251247
RowSecurityPolicy *policy;
252248

@@ -298,14 +294,11 @@ RelationBuildRowSecurity(Relation relation)
298294
else
299295
with_check_qual = NULL;
300296

301-
policy_id = HeapTupleGetOid(tuple);
302-
303297
/* Now copy everything into the cache context */
304298
MemoryContextSwitchTo(rscxt);
305299

306300
policy = palloc0(sizeof(RowSecurityPolicy));
307301
policy->policy_name = pstrdup(policy_name_value);
308-
policy->policy_id = policy_id;
309302
policy->polcmd = cmd_value;
310303
policy->roles = DatumGetArrayTypePCopy(roles_datum);
311304
policy->qual = copyObject(qual_expr);
@@ -326,40 +319,6 @@ RelationBuildRowSecurity(Relation relation)
326319

327320
systable_endscan(sscan);
328321
heap_close(catalog, AccessShareLock);
329-
330-
/*
331-
* Check if no policies were added
332-
*
333-
* If no policies exist in pg_policy for this relation, then we need
334-
* to create a single default-deny policy. We use InvalidOid for the
335-
* Oid to indicate that this is the default-deny policy (we may decide
336-
* to ignore the default policy if an extension adds policies).
337-
*/
338-
if (rsdesc->policies == NIL)
339-
{
340-
RowSecurityPolicy *policy;
341-
Datum role;
342-
343-
MemoryContextSwitchTo(rscxt);
344-
345-
role = ObjectIdGetDatum(ACL_ID_PUBLIC);
346-
347-
policy = palloc0(sizeof(RowSecurityPolicy));
348-
policy->policy_name = pstrdup("default-deny policy");
349-
policy->policy_id = InvalidOid;
350-
policy->polcmd = '*';
351-
policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true,
352-
'i');
353-
policy->qual = (Expr *) makeConst(BOOLOID, -1, InvalidOid,
354-
sizeof(bool), BoolGetDatum(false),
355-
false, true);
356-
policy->with_check_qual = copyObject(policy->qual);
357-
policy->hassublinks = false;
358-
359-
rsdesc->policies = lcons(policy, rsdesc->policies);
360-
361-
MemoryContextSwitchTo(oldcxt);
362-
}
363322
}
364323
PG_CATCH();
365324
{

src/backend/executor/execMain.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,14 +1815,26 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
18151815
break;
18161816
case WCO_RLS_INSERT_CHECK:
18171817
case WCO_RLS_UPDATE_CHECK:
1818-
ereport(ERROR,
1819-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1818+
if (wco->polname != NULL)
1819+
ereport(ERROR,
1820+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1821+
errmsg("new row violates row level security policy \"%s\" for \"%s\"",
1822+
wco->polname, wco->relname)));
1823+
else
1824+
ereport(ERROR,
1825+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
18201826
errmsg("new row violates row level security policy for \"%s\"",
18211827
wco->relname)));
18221828
break;
18231829
case WCO_RLS_CONFLICT_CHECK:
1824-
ereport(ERROR,
1825-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1830+
if (wco->polname != NULL)
1831+
ereport(ERROR,
1832+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1833+
errmsg("new row violates row level security policy \"%s\" (USING expression) for \"%s\"",
1834+
wco->polname, wco->relname)));
1835+
else
1836+
ereport(ERROR,
1837+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
18261838
errmsg("new row violates row level security policy (USING expression) for \"%s\"",
18271839
wco->relname)));
18281840
break;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,7 @@ _copyWithCheckOption(const WithCheckOption *from)
21682168

21692169
COPY_SCALAR_FIELD(kind);
21702170
COPY_STRING_FIELD(relname);
2171+
COPY_STRING_FIELD(polname);
21712172
COPY_NODE_FIELD(qual);
21722173
COPY_SCALAR_FIELD(cascaded);
21732174

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,7 @@ _equalWithCheckOption(const WithCheckOption *a, const WithCheckOption *b)
24552455
{
24562456
COMPARE_SCALAR_FIELD(kind);
24572457
COMPARE_STRING_FIELD(relname);
2458+
COMPARE_STRING_FIELD(polname);
24582459
COMPARE_NODE_FIELD(qual);
24592460
COMPARE_SCALAR_FIELD(cascaded);
24602461

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,7 @@ _outWithCheckOption(StringInfo str, const WithCheckOption *node)
24032403

24042404
WRITE_ENUM_FIELD(kind, WCOKind);
24052405
WRITE_STRING_FIELD(relname);
2406+
WRITE_STRING_FIELD(polname);
24062407
WRITE_NODE_FIELD(qual);
24072408
WRITE_BOOL_FIELD(cascaded);
24082409
}

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ _readWithCheckOption(void)
270270

271271
READ_ENUM_FIELD(kind, WCOKind);
272272
READ_STRING_FIELD(relname);
273+
READ_STRING_FIELD(polname);
273274
READ_NODE_FIELD(qual);
274275
READ_BOOL_FIELD(cascaded);
275276

src/backend/rewrite/rewriteHandler.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,8 +1786,8 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown)
17861786
/*
17871787
* Fetch any new security quals that must be applied to this RTE.
17881788
*/
1789-
get_row_security_policies(parsetree, parsetree->commandType, rte,
1790-
rt_index, &securityQuals, &withCheckOptions,
1789+
get_row_security_policies(parsetree, rte, rt_index,
1790+
&securityQuals, &withCheckOptions,
17911791
&hasRowSecurity, &hasSubLinks);
17921792

17931793
if (securityQuals != NIL || withCheckOptions != NIL)
@@ -3026,6 +3026,7 @@ rewriteTargetView(Query *parsetree, Relation view)
30263026
wco = makeNode(WithCheckOption);
30273027
wco->kind = WCO_VIEW_CHECK;
30283028
wco->relname = pstrdup(RelationGetRelationName(view));
3029+
wco->polname = NULL;
30293030
wco->qual = NULL;
30303031
wco->cascaded = cascaded;
30313032

0 commit comments

Comments
 (0)