Skip to content

Commit 90efa2f

Browse files
committed
Add a test module for Object Access hooks
This includes tests of both the newly added name type object access hooks and the older Oid type hooks, and provides a useful example of how to use the hooks. Mark Dilger, based on some code from Joshua Brindle. Discussion: https://postgr.es/m/47F87A0E-C0E5-43A6-89F6-D403F2B45175@enterprisedb.com
1 parent d11e84e commit 90efa2f

File tree

8 files changed

+1311
-0
lines changed

8 files changed

+1311
-0
lines changed

src/test/modules/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ SUBDIRS = \
2020
test_ginpostinglist \
2121
test_integerset \
2222
test_misc \
23+
test_oat_hooks \
2324
test_parser \
2425
test_pg_dump \
2526
test_predtest \
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Generated subdirectories
2+
/log/
3+
/results/
4+
/tmp_check/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# src/test/modules/test_oat_hooks/Makefile
2+
3+
MODULE_big = test_oat_hooks
4+
OBJS = \
5+
$(WIN32RES) \
6+
test_oat_hooks.o
7+
PGFILEDESC = "test_oat_hooks - example use of object access hooks"
8+
9+
REGRESS = test_oat_hooks
10+
REGRESS_OPTS = --temp-config=$(top_srcdir)/src/test/modules/test_oat_hooks/test_oat_hooks.conf
11+
# Disabled because these tests require "shared_preload_libraries=test_oat_hooks",
12+
# which typical installcheck users do not have (e.g. buildfarm clients).
13+
NO_INSTALLCHECK = 1
14+
15+
ifdef USE_PGXS
16+
PG_CONFIG = pg_config
17+
PGXS := $(shell $(PG_CONFIG) --pgxs)
18+
include $(PGXS)
19+
else
20+
subdir = src/test/modules/test_oat_hooks
21+
top_builddir = ../../../..
22+
include $(top_builddir)/src/Makefile.global
23+
include $(top_srcdir)/contrib/contrib-global.mk
24+
endif
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
OVERVIEW
2+
========
3+
4+
This test module, "test_oat_hooks", is an example of how to use the object
5+
access hooks (OAT) to enforce mandatory access controls (MAC).
6+
7+
The testing strategy is as follows: When this module loads, it registers hooks
8+
of various types. (See below.) GUCs are defined to control each hook,
9+
determining whether the hook allows or denies actions for which it fires. A
10+
single additional GUC controls the verbosity of the hooks. GUCs default to
11+
permissive/quiet, which allows the module to load without generating noise in
12+
the log or denying any activity in the run-up to the regression test beginning.
13+
When the test begins, it uses SET commands to turn on logging and to control
14+
each hook's permissive/restrictive behavior. Various SQL statements are run
15+
under both superuser and ordinary user permissions. The output is compared
16+
against the expected output to verify that the hooks behaved and fired in the
17+
order by expect.
18+
19+
Because users may care about the firing order of other system hooks relative to
20+
OAT hooks, ProcessUtility hooks and ExecutorCheckPerms hooks are also
21+
registered by this module, with their own logging and allow/deny behavior.
22+
23+
24+
SUSET test configuration GUCs
25+
=============================
26+
27+
The following configuration parameters (GUCs) control this test module's Object
28+
Access Type (OAT), Process Utility and Executor Check Permissions hooks. The
29+
general pattern is that each hook has a corresponding GUC which controls
30+
whether the hook will allow or deny operations for which the hook gets called.
31+
A real-world OAT hook should certainly provide more fine-grained conrol than
32+
merely "allow-all" vs. "deny-all", but for testing this is sufficient.
33+
34+
Note that even when these hooks allow an action, the core permissions system
35+
may still refuse the action. The firing order of the hooks relative to the
36+
core permissions system can be inferred from which NOTICE messages get emitted
37+
before an action is refused.
38+
39+
Each hook applies the allow vs. deny setting to all operations performed by
40+
non-superusers.
41+
42+
- test_oat_hooks.deny_set_variable
43+
44+
Controls whether the object_access_hook_str MAC function rejects attempts to
45+
set a configuration parameter.
46+
47+
- test_oat_hooks.deny_alter_system
48+
49+
Controls whether the object_access_hook_str MAC function rejects attempts to
50+
alter system set a configuration parameter.
51+
52+
- test_oat_hooks.deny_object_access
53+
54+
Controls whether the object_access_hook MAC function rejects all operations
55+
for which it is called.
56+
57+
- test_oat_hooks.deny_exec_perms
58+
59+
Controls whether the exec_check_perms MAC function rejects all operations for
60+
which it is called.
61+
62+
- test_oat_hooks.deny_utility_commands
63+
64+
Controls whether the ProcessUtility_hook function rejects all operations for
65+
which it is called.
66+
67+
- test_oat_hooks.audit
68+
69+
Controls whether each hook logs NOTICE messages for each attempt, along with
70+
success or failure status. Note that clearing or setting this GUC may itself
71+
generate NOTICE messages appearing before but not after, or after but not
72+
before, the new setting takes effect.
73+
74+
75+
Functions
76+
=========
77+
78+
The module registers hooks by the following names:
79+
80+
- REGRESS_object_access_hook
81+
82+
- REGRESS_object_access_hook_str
83+
84+
- REGRESS_exec_check_perms
85+
86+
- REGRESS_utility_command
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
-- SET commands fire both the ProcessUtility_hook and the
2+
-- object_access_hook_str. Since the auditing GUC starts out false, we miss the
3+
-- initial "attempting" audit message from the ProcessUtility_hook, but we
4+
-- should thereafter see the audit messages
5+
SET test_oat_hooks.audit = true;
6+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.audit]
7+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.audit]
8+
NOTICE: in process utility: superuser finished set
9+
-- Create objects for use in the test
10+
CREATE USER regress_test_user;
11+
NOTICE: in process utility: superuser attempting CreateRoleStmt
12+
NOTICE: in object access: superuser attempting create (subId=0) [explicit]
13+
NOTICE: in object access: superuser finished create (subId=0) [explicit]
14+
NOTICE: in process utility: superuser finished CreateRoleStmt
15+
CREATE TABLE regress_test_table (t text);
16+
NOTICE: in process utility: superuser attempting CreateStmt
17+
NOTICE: in object access: superuser attempting namespace search (subId=0) [no report on violation, allowed]
18+
LINE 1: CREATE TABLE regress_test_table (t text);
19+
^
20+
NOTICE: in object access: superuser finished namespace search (subId=0) [no report on violation, allowed]
21+
LINE 1: CREATE TABLE regress_test_table (t text);
22+
^
23+
NOTICE: in object access: superuser attempting create (subId=0) [explicit]
24+
NOTICE: in object access: superuser finished create (subId=0) [explicit]
25+
NOTICE: in object access: superuser attempting create (subId=0) [explicit]
26+
NOTICE: in object access: superuser finished create (subId=0) [explicit]
27+
NOTICE: in object access: superuser attempting create (subId=0) [explicit]
28+
NOTICE: in object access: superuser finished create (subId=0) [explicit]
29+
NOTICE: in object access: superuser attempting create (subId=0) [internal]
30+
NOTICE: in object access: superuser finished create (subId=0) [internal]
31+
NOTICE: in object access: superuser attempting create (subId=0) [internal]
32+
NOTICE: in object access: superuser finished create (subId=0) [internal]
33+
NOTICE: in process utility: superuser finished CreateStmt
34+
GRANT SELECT ON Table regress_test_table TO public;
35+
NOTICE: in process utility: superuser attempting GrantStmt
36+
NOTICE: in process utility: superuser finished GrantStmt
37+
CREATE FUNCTION regress_test_func (t text) RETURNS text AS $$
38+
SELECT $1;
39+
$$ LANGUAGE sql;
40+
NOTICE: in process utility: superuser attempting CreateFunctionStmt
41+
NOTICE: in object access: superuser attempting create (subId=0) [explicit]
42+
NOTICE: in object access: superuser finished create (subId=0) [explicit]
43+
NOTICE: in process utility: superuser finished CreateFunctionStmt
44+
GRANT EXECUTE ON FUNCTION regress_test_func (text) TO public;
45+
NOTICE: in process utility: superuser attempting GrantStmt
46+
NOTICE: in process utility: superuser finished GrantStmt
47+
-- Do a few things as superuser
48+
SELECT * FROM regress_test_table;
49+
NOTICE: in executor check perms: superuser attempting execute
50+
NOTICE: in executor check perms: superuser finished execute
51+
t
52+
---
53+
(0 rows)
54+
55+
SELECT regress_test_func('arg');
56+
NOTICE: in executor check perms: superuser attempting execute
57+
NOTICE: in executor check perms: superuser finished execute
58+
regress_test_func
59+
-------------------
60+
arg
61+
(1 row)
62+
63+
SET work_mem = 8192;
64+
NOTICE: in process utility: superuser attempting set
65+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [work_mem]
66+
NOTICE: in object_access_hook_str: superuser finished alter (set) [work_mem]
67+
NOTICE: in process utility: superuser finished set
68+
RESET work_mem;
69+
NOTICE: in process utility: superuser attempting set
70+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [work_mem]
71+
NOTICE: in object_access_hook_str: superuser finished alter (set) [work_mem]
72+
NOTICE: in process utility: superuser finished set
73+
ALTER SYSTEM SET work_mem = 8192;
74+
NOTICE: in process utility: superuser attempting alter system
75+
NOTICE: in object_access_hook_str: superuser attempting alter (alter system set) [work_mem]
76+
NOTICE: in object_access_hook_str: superuser finished alter (alter system set) [work_mem]
77+
NOTICE: in process utility: superuser finished alter system
78+
ALTER SYSTEM RESET work_mem;
79+
NOTICE: in process utility: superuser attempting alter system
80+
NOTICE: in object_access_hook_str: superuser attempting alter (alter system set) [work_mem]
81+
NOTICE: in object_access_hook_str: superuser finished alter (alter system set) [work_mem]
82+
NOTICE: in process utility: superuser finished alter system
83+
-- Do those same things as non-superuser
84+
SET SESSION AUTHORIZATION regress_test_user;
85+
NOTICE: in process utility: superuser attempting set
86+
NOTICE: in object_access_hook_str: non-superuser attempting alter (set) [session_authorization]
87+
NOTICE: in object_access_hook_str: non-superuser finished alter (set) [session_authorization]
88+
NOTICE: in process utility: non-superuser finished set
89+
SELECT * FROM regress_test_table;
90+
NOTICE: in object access: non-superuser attempting namespace search (subId=0) [no report on violation, allowed]
91+
LINE 1: SELECT * FROM regress_test_table;
92+
^
93+
NOTICE: in object access: non-superuser finished namespace search (subId=0) [no report on violation, allowed]
94+
LINE 1: SELECT * FROM regress_test_table;
95+
^
96+
NOTICE: in executor check perms: non-superuser attempting execute
97+
NOTICE: in executor check perms: non-superuser finished execute
98+
t
99+
---
100+
(0 rows)
101+
102+
SELECT regress_test_func('arg');
103+
NOTICE: in executor check perms: non-superuser attempting execute
104+
NOTICE: in executor check perms: non-superuser finished execute
105+
regress_test_func
106+
-------------------
107+
arg
108+
(1 row)
109+
110+
SET work_mem = 8192;
111+
NOTICE: in process utility: non-superuser attempting set
112+
NOTICE: in object_access_hook_str: non-superuser attempting alter (set) [work_mem]
113+
NOTICE: in object_access_hook_str: non-superuser finished alter (set) [work_mem]
114+
NOTICE: in process utility: non-superuser finished set
115+
RESET work_mem;
116+
NOTICE: in process utility: non-superuser attempting set
117+
NOTICE: in object_access_hook_str: non-superuser attempting alter (set) [work_mem]
118+
NOTICE: in object_access_hook_str: non-superuser finished alter (set) [work_mem]
119+
NOTICE: in process utility: non-superuser finished set
120+
ALTER SYSTEM SET work_mem = 8192;
121+
NOTICE: in process utility: non-superuser attempting alter system
122+
ERROR: must be superuser to execute ALTER SYSTEM command
123+
ALTER SYSTEM RESET work_mem;
124+
NOTICE: in process utility: non-superuser attempting alter system
125+
ERROR: must be superuser to execute ALTER SYSTEM command
126+
RESET SESSION AUTHORIZATION;
127+
NOTICE: in process utility: non-superuser attempting set
128+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [session_authorization]
129+
NOTICE: in object_access_hook_str: superuser finished alter (set) [session_authorization]
130+
NOTICE: in process utility: superuser finished set
131+
-- Turn off non-superuser permissions
132+
SET test_oat_hooks.deny_set_variable = true;
133+
NOTICE: in process utility: superuser attempting set
134+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.deny_set_variable]
135+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.deny_set_variable]
136+
NOTICE: in process utility: superuser finished set
137+
SET test_oat_hooks.deny_alter_system = true;
138+
NOTICE: in process utility: superuser attempting set
139+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.deny_alter_system]
140+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.deny_alter_system]
141+
NOTICE: in process utility: superuser finished set
142+
SET test_oat_hooks.deny_object_access = true;
143+
NOTICE: in process utility: superuser attempting set
144+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.deny_object_access]
145+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.deny_object_access]
146+
NOTICE: in process utility: superuser finished set
147+
SET test_oat_hooks.deny_exec_perms = true;
148+
NOTICE: in process utility: superuser attempting set
149+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.deny_exec_perms]
150+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.deny_exec_perms]
151+
NOTICE: in process utility: superuser finished set
152+
SET test_oat_hooks.deny_utility_commands = true;
153+
NOTICE: in process utility: superuser attempting set
154+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [test_oat_hooks.deny_utility_commands]
155+
NOTICE: in object_access_hook_str: superuser finished alter (set) [test_oat_hooks.deny_utility_commands]
156+
NOTICE: in process utility: superuser finished set
157+
-- Try again as non-superuser with permisisons denied
158+
SET SESSION AUTHORIZATION regress_test_user;
159+
NOTICE: in process utility: superuser attempting set
160+
NOTICE: in object_access_hook_str: non-superuser attempting alter (set) [session_authorization]
161+
ERROR: permission denied: set session_authorization
162+
SELECT * FROM regress_test_table;
163+
NOTICE: in object access: superuser attempting namespace search (subId=0) [no report on violation, allowed]
164+
LINE 1: SELECT * FROM regress_test_table;
165+
^
166+
NOTICE: in object access: superuser finished namespace search (subId=0) [no report on violation, allowed]
167+
LINE 1: SELECT * FROM regress_test_table;
168+
^
169+
NOTICE: in executor check perms: superuser attempting execute
170+
NOTICE: in executor check perms: superuser finished execute
171+
t
172+
---
173+
(0 rows)
174+
175+
SELECT regress_test_func('arg');
176+
NOTICE: in executor check perms: superuser attempting execute
177+
NOTICE: in executor check perms: superuser finished execute
178+
regress_test_func
179+
-------------------
180+
arg
181+
(1 row)
182+
183+
SET work_mem = 8192;
184+
NOTICE: in process utility: superuser attempting set
185+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [work_mem]
186+
NOTICE: in object_access_hook_str: superuser finished alter (set) [work_mem]
187+
NOTICE: in process utility: superuser finished set
188+
RESET work_mem;
189+
NOTICE: in process utility: superuser attempting set
190+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [work_mem]
191+
NOTICE: in object_access_hook_str: superuser finished alter (set) [work_mem]
192+
NOTICE: in process utility: superuser finished set
193+
ALTER SYSTEM SET work_mem = 8192;
194+
NOTICE: in process utility: superuser attempting alter system
195+
NOTICE: in object_access_hook_str: superuser attempting alter (alter system set) [work_mem]
196+
NOTICE: in object_access_hook_str: superuser finished alter (alter system set) [work_mem]
197+
NOTICE: in process utility: superuser finished alter system
198+
ALTER SYSTEM RESET work_mem;
199+
NOTICE: in process utility: superuser attempting alter system
200+
NOTICE: in object_access_hook_str: superuser attempting alter (alter system set) [work_mem]
201+
NOTICE: in object_access_hook_str: superuser finished alter (alter system set) [work_mem]
202+
NOTICE: in process utility: superuser finished alter system
203+
RESET SESSION AUTHORIZATION;
204+
NOTICE: in process utility: superuser attempting set
205+
NOTICE: in object_access_hook_str: superuser attempting alter (set) [session_authorization]
206+
NOTICE: in object_access_hook_str: superuser finished alter (set) [session_authorization]
207+
NOTICE: in process utility: superuser finished set
208+
SET test_oat_hooks.audit = false;
209+
NOTICE: in process utility: superuser attempting set
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-- SET commands fire both the ProcessUtility_hook and the
2+
-- object_access_hook_str. Since the auditing GUC starts out false, we miss the
3+
-- initial "attempting" audit message from the ProcessUtility_hook, but we
4+
-- should thereafter see the audit messages
5+
SET test_oat_hooks.audit = true;
6+
7+
-- Create objects for use in the test
8+
CREATE USER regress_test_user;
9+
CREATE TABLE regress_test_table (t text);
10+
GRANT SELECT ON Table regress_test_table TO public;
11+
CREATE FUNCTION regress_test_func (t text) RETURNS text AS $$
12+
SELECT $1;
13+
$$ LANGUAGE sql;
14+
GRANT EXECUTE ON FUNCTION regress_test_func (text) TO public;
15+
16+
-- Do a few things as superuser
17+
SELECT * FROM regress_test_table;
18+
SELECT regress_test_func('arg');
19+
SET work_mem = 8192;
20+
RESET work_mem;
21+
ALTER SYSTEM SET work_mem = 8192;
22+
ALTER SYSTEM RESET work_mem;
23+
24+
-- Do those same things as non-superuser
25+
SET SESSION AUTHORIZATION regress_test_user;
26+
SELECT * FROM regress_test_table;
27+
SELECT regress_test_func('arg');
28+
SET work_mem = 8192;
29+
RESET work_mem;
30+
ALTER SYSTEM SET work_mem = 8192;
31+
ALTER SYSTEM RESET work_mem;
32+
RESET SESSION AUTHORIZATION;
33+
34+
-- Turn off non-superuser permissions
35+
SET test_oat_hooks.deny_set_variable = true;
36+
SET test_oat_hooks.deny_alter_system = true;
37+
SET test_oat_hooks.deny_object_access = true;
38+
SET test_oat_hooks.deny_exec_perms = true;
39+
SET test_oat_hooks.deny_utility_commands = true;
40+
41+
-- Try again as non-superuser with permisisons denied
42+
SET SESSION AUTHORIZATION regress_test_user;
43+
SELECT * FROM regress_test_table;
44+
SELECT regress_test_func('arg');
45+
SET work_mem = 8192;
46+
RESET work_mem;
47+
ALTER SYSTEM SET work_mem = 8192;
48+
ALTER SYSTEM RESET work_mem;
49+
50+
RESET SESSION AUTHORIZATION;
51+
52+
SET test_oat_hooks.audit = false;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy