Age Owner TLA Line data Source code
1 : /*--------------------------------------------------------------------------
2 : *
3 : * test_rls_hooks.c
4 : * Code for testing RLS hooks.
5 : *
6 : * Copyright (c) 2015-2023, PostgreSQL Global Development Group
7 : *
8 : * IDENTIFICATION
9 : * src/test/modules/test_rls_hooks/test_rls_hooks.c
10 : *
11 : * -------------------------------------------------------------------------
12 : */
13 :
14 : #include "postgres.h"
15 :
16 : #include "catalog/pg_type.h"
17 : #include "fmgr.h"
18 : #include "miscadmin.h"
19 : #include "nodes/makefuncs.h"
20 : #include "parser/parse_clause.h"
21 : #include "parser/parse_collate.h"
22 : #include "parser/parse_node.h"
23 : #include "parser/parse_relation.h"
24 : #include "rewrite/rowsecurity.h"
25 : #include "test_rls_hooks.h"
26 : #include "utils/acl.h"
27 : #include "utils/rel.h"
28 : #include "utils/relcache.h"
29 :
2909 sfrost 30 CBC 1 : PG_MODULE_MAGIC;
31 :
2909 sfrost 32 ECB : /* Install hooks */
33 : void
2878 bruce 34 GIC 1 : _PG_init(void)
2909 sfrost 35 ECB : {
36 : /* Set our hooks */
2909 sfrost 37 CBC 1 : row_security_policy_hook_permissive = test_rls_hooks_permissive;
2909 sfrost 38 GIC 1 : row_security_policy_hook_restrictive = test_rls_hooks_restrictive;
39 1 : }
40 :
41 : /*
42 : * Return permissive policies to be added
2909 sfrost 43 ECB : */
44 : List *
2909 sfrost 45 CBC 30 : test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
2909 sfrost 46 ECB : {
2878 bruce 47 GIC 30 : List *policies = NIL;
48 30 : RowSecurityPolicy *policy = palloc0(sizeof(RowSecurityPolicy));
49 : Datum role;
50 : FuncCall *n;
51 : Node *e;
52 : ColumnRef *c;
53 : ParseState *qual_pstate;
1193 tgl 54 ECB : ParseNamespaceItem *nsitem;
2878 bruce 55 :
1458 michael 56 CBC 30 : if (strcmp(RelationGetRelationName(relation), "rls_test_permissive") != 0 &&
1458 michael 57 GIC 21 : strcmp(RelationGetRelationName(relation), "rls_test_both") != 0)
2909 sfrost 58 CBC 10 : return NIL;
59 :
60 20 : qual_pstate = make_parsestate(NULL);
61 :
1193 tgl 62 GIC 20 : nsitem = addRangeTableEntryForRelation(qual_pstate,
1193 tgl 63 ECB : relation, AccessShareLock,
64 : NULL, false, false);
1193 tgl 65 CBC 20 : addNSItemToQuery(qual_pstate, nsitem, false, true, true);
66 :
2909 sfrost 67 20 : role = ObjectIdGetDatum(ACL_ID_PUBLIC);
2909 sfrost 68 ECB :
2909 sfrost 69 CBC 20 : policy->policy_name = pstrdup("extension policy");
2909 sfrost 70 GIC 20 : policy->polcmd = '*';
282 peter 71 GNC 20 : policy->roles = construct_array_builtin(&role, 1, OIDOID);
72 :
73 : /*
74 : * policy->qual = (Expr *) makeConst(BOOLOID, -1, InvalidOid,
75 : * sizeof(bool), BoolGetDatum(true), false, true);
2878 bruce 76 ECB : */
77 :
2909 sfrost 78 GIC 20 : n = makeFuncCall(list_make2(makeString("pg_catalog"),
79 : makeString("current_user")),
80 : NIL,
81 : COERCE_EXPLICIT_CALL,
886 tgl 82 ECB : -1);
2909 sfrost 83 :
2909 sfrost 84 CBC 20 : c = makeNode(ColumnRef);
2909 sfrost 85 GIC 20 : c->fields = list_make1(makeString("username"));
2909 sfrost 86 CBC 20 : c->location = 0;
87 :
2878 bruce 88 20 : e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
89 :
2878 bruce 90 GIC 20 : policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
91 : EXPR_KIND_POLICY,
2878 bruce 92 ECB : "POLICY");
93 : /* Fix up collation information */
1580 tgl 94 CBC 20 : assign_expr_collations(qual_pstate, (Node *) policy->qual);
2909 sfrost 95 ECB :
2909 sfrost 96 GIC 20 : policy->with_check_qual = copyObject(policy->qual);
2909 sfrost 97 CBC 20 : policy->hassublinks = false;
98 :
99 20 : policies = list_make1(policy);
100 :
2909 sfrost 101 GIC 20 : return policies;
102 : }
103 :
104 : /*
105 : * Return restrictive policies to be added
106 : *
107 : * Note that a permissive policy must exist or the default-deny policy
108 : * will be included and nothing will be visible. If no filtering should
109 : * be done except for the restrictive policy, then a single "USING (true)"
110 : * permissive policy can be used; see the regression tests.
2909 sfrost 111 ECB : */
112 : List *
2909 sfrost 113 CBC 30 : test_rls_hooks_restrictive(CmdType cmdtype, Relation relation)
2909 sfrost 114 ECB : {
2878 bruce 115 GIC 30 : List *policies = NIL;
116 30 : RowSecurityPolicy *policy = palloc0(sizeof(RowSecurityPolicy));
117 : Datum role;
118 : FuncCall *n;
119 : Node *e;
120 : ColumnRef *c;
121 : ParseState *qual_pstate;
1193 tgl 122 ECB : ParseNamespaceItem *nsitem;
2878 bruce 123 :
1458 michael 124 CBC 30 : if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive") != 0 &&
1458 michael 125 GIC 20 : strcmp(RelationGetRelationName(relation), "rls_test_both") != 0)
2909 sfrost 126 CBC 9 : return NIL;
127 :
128 21 : qual_pstate = make_parsestate(NULL);
129 :
1193 tgl 130 GIC 21 : nsitem = addRangeTableEntryForRelation(qual_pstate,
1193 tgl 131 ECB : relation, AccessShareLock,
132 : NULL, false, false);
1193 tgl 133 CBC 21 : addNSItemToQuery(qual_pstate, nsitem, false, true, true);
134 :
2909 sfrost 135 21 : role = ObjectIdGetDatum(ACL_ID_PUBLIC);
2909 sfrost 136 ECB :
2909 sfrost 137 CBC 21 : policy->policy_name = pstrdup("extension policy");
2909 sfrost 138 GIC 21 : policy->polcmd = '*';
282 peter 139 GNC 21 : policy->roles = construct_array_builtin(&role, 1, OIDOID);
140 :
2909 sfrost 141 GIC 21 : n = makeFuncCall(list_make2(makeString("pg_catalog"),
142 : makeString("current_user")),
143 : NIL,
144 : COERCE_EXPLICIT_CALL,
886 tgl 145 ECB : -1);
2909 sfrost 146 :
2909 sfrost 147 CBC 21 : c = makeNode(ColumnRef);
2909 sfrost 148 GIC 21 : c->fields = list_make1(makeString("supervisor"));
2909 sfrost 149 CBC 21 : c->location = 0;
150 :
2878 bruce 151 21 : e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
152 :
2878 bruce 153 GIC 21 : policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
154 : EXPR_KIND_POLICY,
2878 bruce 155 ECB : "POLICY");
156 : /* Fix up collation information */
1580 tgl 157 CBC 21 : assign_expr_collations(qual_pstate, (Node *) policy->qual);
2909 sfrost 158 ECB :
2909 sfrost 159 GIC 21 : policy->with_check_qual = copyObject(policy->qual);
2909 sfrost 160 CBC 21 : policy->hassublinks = false;
161 :
162 21 : policies = list_make1(policy);
163 :
2909 sfrost 164 GIC 21 : return policies;
165 : }
|