PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
test_rls_hooks.c
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------
2  *
3  * test_rls_hooks.c
4  * Code for testing RLS hooks.
5  *
6  * Copyright (c) 2015-2017, 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 "fmgr.h"
17 #include "miscadmin.h"
18 
19 #include "test_rls_hooks.h"
20 
21 #include <catalog/pg_type.h>
22 #include <nodes/makefuncs.h>
23 #include <nodes/makefuncs.h>
24 #include <parser/parse_clause.h>
25 #include <parser/parse_node.h>
26 #include <parser/parse_relation.h>
27 #include <rewrite/rowsecurity.h>
28 #include <utils/acl.h>
29 #include <utils/rel.h>
30 #include <utils/relcache.h>
31 
33 
34 /* Saved hook values in case of unload */
37 
38 void _PG_init(void);
39 void _PG_fini(void);
40 
41 /* Install hooks */
42 void
43 _PG_init(void)
44 {
45  /* Save values for unload */
48 
49  /* Set our hooks */
52 }
53 
54 /* Uninstall hooks */
55 void
56 _PG_fini(void)
57 {
60 }
61 
62 /*
63  * Return permissive policies to be added
64  */
65 List *
67 {
68  List *policies = NIL;
69  RowSecurityPolicy *policy = palloc0(sizeof(RowSecurityPolicy));
70  Datum role;
71  FuncCall *n;
72  Node *e;
73  ColumnRef *c;
74  ParseState *qual_pstate;
75  RangeTblEntry *rte;
76 
77  if (strcmp(RelationGetRelationName(relation), "rls_test_permissive")
78  && strcmp(RelationGetRelationName(relation), "rls_test_both"))
79  return NIL;
80 
81  qual_pstate = make_parsestate(NULL);
82 
83  rte = addRangeTableEntryForRelation(qual_pstate, relation, NULL, false,
84  false);
85  addRTEtoQuery(qual_pstate, rte, false, true, true);
86 
88 
89  policy->policy_name = pstrdup("extension policy");
90  policy->polcmd = '*';
91  policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true, 'i');
92 
93  /*
94  * policy->qual = (Expr *) makeConst(BOOLOID, -1, InvalidOid,
95  * sizeof(bool), BoolGetDatum(true), false, true);
96  */
97 
98  n = makeFuncCall(list_make2(makeString("pg_catalog"),
99  makeString("current_user")), NIL, 0);
100 
101  c = makeNode(ColumnRef);
102  c->fields = list_make1(makeString("username"));
103  c->location = 0;
104 
105  e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
106 
107  policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
109  "POLICY");
110 
111  policy->with_check_qual = copyObject(policy->qual);
112  policy->hassublinks = false;
113 
114  policies = list_make1(policy);
115 
116  return policies;
117 }
118 
119 /*
120  * Return restrictive policies to be added
121  *
122  * Note that a permissive policy must exist or the default-deny policy
123  * will be included and nothing will be visible. If no filtering should
124  * be done except for the restrictive policy, then a single "USING (true)"
125  * permissive policy can be used; see the regression tests.
126  */
127 List *
129 {
130  List *policies = NIL;
131  RowSecurityPolicy *policy = palloc0(sizeof(RowSecurityPolicy));
132  Datum role;
133  FuncCall *n;
134  Node *e;
135  ColumnRef *c;
136  ParseState *qual_pstate;
137  RangeTblEntry *rte;
138 
139 
140  if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive")
141  && strcmp(RelationGetRelationName(relation), "rls_test_both"))
142  return NIL;
143 
144  qual_pstate = make_parsestate(NULL);
145 
146  rte = addRangeTableEntryForRelation(qual_pstate, relation, NULL, false,
147  false);
148  addRTEtoQuery(qual_pstate, rte, false, true, true);
149 
151 
152  policy->policy_name = pstrdup("extension policy");
153  policy->polcmd = '*';
154  policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true, 'i');
155 
156  n = makeFuncCall(list_make2(makeString("pg_catalog"),
157  makeString("current_user")), NIL, 0);
158 
159  c = makeNode(ColumnRef);
160  c->fields = list_make1(makeString("supervisor"));
161  c->location = 0;
162 
163  e = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (Node *) n, (Node *) c, 0);
164 
165  policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e),
167  "POLICY");
168 
169  policy->with_check_qual = copyObject(policy->qual);
170  policy->hassublinks = false;
171 
172  policies = list_make1(policy);
173 
174  return policies;
175 }
#define list_make2(x1, x2)
Definition: pg_list.h:134
void _PG_fini(void)
Value * makeString(char *str)
Definition: value.c:53
static row_security_policy_hook_type prev_row_security_policy_hook_permissive
#define NIL
Definition: pg_list.h:69
void _PG_init(void)
PG_MODULE_MAGIC
#define OIDOID
Definition: pg_type.h:328
char * pstrdup(const char *in)
Definition: mcxt.c:1077
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3306
List *(* row_security_policy_hook_type)(CmdType cmdtype, Relation relation)
Definition: rowsecurity.h:37
Definition: nodes.h:504
row_security_policy_hook_type row_security_policy_hook_permissive
Definition: rowsecurity.c:94
List * test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
unsigned int Oid
Definition: postgres_ext.h:31
A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:49
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
int location
Definition: parsenodes.h:227
void * copyObject(const void *from)
Definition: copyfuncs.c:4619
static row_security_policy_hook_type prev_row_security_policy_hook_restrictive
#define list_make1(x1)
Definition: pg_list.h:133
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
char * c
Expr * with_check_qual
Definition: rowsecurity.h:27
row_security_policy_hook_type row_security_policy_hook_restrictive
Definition: rowsecurity.c:95
#define RelationGetRelationName(relation)
Definition: rel.h:437
ArrayType * roles
Definition: rowsecurity.h:24
void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
FuncCall * makeFuncCall(List *name, List *args, int location)
Definition: makefuncs.c:582
void * palloc0(Size size)
Definition: mcxt.c:878
uintptr_t Datum
Definition: postgres.h:372
#define makeNode(_type_)
Definition: nodes.h:552
#define NULL
Definition: c.h:229
List * test_rls_hooks_restrictive(CmdType cmdtype, Relation relation)
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, Alias *alias, bool inh, bool inFromCl)
e
Definition: preproc-init.c:82
#define ACL_ID_PUBLIC
Definition: acl.h:39
Definition: pg_list.h:45
CmdType
Definition: nodes.h:637
List * fields
Definition: parsenodes.h:226