forked from pgEdge/spock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspock_common.c
152 lines (131 loc) · 4 KB
/
spock_common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*-------------------------------------------------------------------------
*
* spock_common.c
* Common code for Spock.
*
* Copyright (c) 2022-2024, pgEdge, Inc.
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, The Regents of the University of California
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "miscadmin.h"
#include "utils/guc.h"
#include "spock_common.h"
#include "spock_compat.h"
/*
* Temporarily switch to a new user ID.
*
* SECURITY_RESTRICTED_OPERATION is imposed and a new GUC nest level is
* created so that any settings changes can be rolled back.
*/
void
SPKSwitchToUntrustedUser(Oid userid, UserContext *context)
{
int sec_context;
/* Get the current user ID and security context. */
GetUserIdAndSecContext(&context->save_userid,
&context->save_sec_context);
sec_context = context->save_sec_context;
/*
* This user can SET ROLE to the target user, but not the other way
* around, so protect ourselves against the target user by setting
* SECURITY_RESTRICTED_OPERATION to prevent certain changes to the
* session state. Also set up a new GUC nest level, so that we can
* roll back any GUC changes that may be made by code running as the
* target user, inasmuch as they could be malicious.
*/
sec_context |= SECURITY_RESTRICTED_OPERATION;
SetUserIdAndSecContext(userid, sec_context);
context->save_nestlevel = NewGUCNestLevel();
}
/*
* Switch back to the original user ID.
*
* If we created a new GUC nest level, also roll back any changes that were
* made within it.
*/
void
SPKRestoreUserContext(UserContext *context)
{
if (context->save_nestlevel != -1)
AtEOXact_GUC(false, context->save_nestlevel);
SetUserIdAndSecContext(context->save_userid, context->save_sec_context);
}
bool
SPKExecBRDeleteTriggers(EState *estate,
EPQState *epqstate,
ResultRelInfo *relinfo,
ItemPointer tupleid,
HeapTuple fdw_trigtuple)
{
UserContext ucxt;
bool ret;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ret = ExecBRDeleteTriggers(estate, epqstate, relinfo, tupleid, fdw_trigtuple);
RestoreUserContext(&ucxt);
return ret;
}
void
SPKExecARDeleteTriggers(EState *estate,
ResultRelInfo *relinfo,
ItemPointer tupleid,
HeapTuple fdw_trigtuple)
{
UserContext ucxt;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ExecARDeleteTriggers(estate, relinfo, tupleid, fdw_trigtuple);
RestoreUserContext(&ucxt);
}
bool
SPKExecBRUpdateTriggers(EState *estate,
EPQState *epqstate,
ResultRelInfo *relinfo,
ItemPointer tupleid,
HeapTuple fdw_trigtuple,
TupleTableSlot *slot)
{
UserContext ucxt;
bool ret;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ret = ExecBRUpdateTriggers(estate, epqstate, relinfo, tupleid, fdw_trigtuple, slot);
RestoreUserContext(&ucxt);
return ret;
}
void
SPKExecARUpdateTriggers(EState *estate,
ResultRelInfo *relinfo,
ItemPointer tupleid,
HeapTuple fdw_trigtuple,
TupleTableSlot *slot,
List *recheckIndexes)
{
UserContext ucxt;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ExecARUpdateTriggers(estate, relinfo, tupleid, fdw_trigtuple, slot, recheckIndexes);
RestoreUserContext(&ucxt);
}
bool
SPKExecBRInsertTriggers(EState *estate,
ResultRelInfo *relinfo,
TupleTableSlot *slot)
{
UserContext ucxt;
bool ret;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ret = ExecBRInsertTriggers(estate, relinfo, slot);
RestoreUserContext(&ucxt);
return ret;
}
void
SPKExecARInsertTriggers(EState *estate,
ResultRelInfo *relinfo,
TupleTableSlot *slot,
List *recheckIndexes)
{
UserContext ucxt;
SwitchToUntrustedUser(relinfo->ri_RelationDesc->rd_rel->relowner, &ucxt);
ExecARInsertTriggers(estate, relinfo, slot, recheckIndexes);
RestoreUserContext(&ucxt);
}