1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add partitioned table support to sepgsql

The new partitioned table capability added a new relkind, namely
RELKIND_PARTITIONED_TABLE. Update sepgsql to treat this new relkind
exactly the same way it does RELKIND_RELATION.

In addition, add regression test coverage for partitioned tables.

Issue raised by Stephen Frost and initial patch by Mike Palmiotto.
Review by Tom Lane and Robert Haas, and editorializing by me.

Discussion: https://postgr.es/m/flat/623bcaae-112e-ced0-8c22-a84f75ae0c53%40joeconway.com
This commit is contained in:
Joe Conway
2017-04-09 14:01:58 -07:00
parent eef8c0069e
commit 25542d77dd
13 changed files with 1154 additions and 69 deletions

View File

@ -53,6 +53,18 @@ CREATE TABLE var_tbl(x int, y text);
INSERT INTO var_tbl VALUES (2,'xxx'), (3,'yyy'), (4,'zzz'), (5,'xyz');
SECURITY LABEL ON TABLE var_tbl
IS 'system_u:object_r:sepgsql_regtest_var_table_t:s0';
CREATE TABLE foo_ptbl(o int, p text) PARTITION BY RANGE (o);
CREATE TABLE foo_ptbl_ones PARTITION OF foo_ptbl FOR VALUES FROM ('0') TO ('10');
CREATE TABLE foo_ptbl_tens PARTITION OF foo_ptbl FOR VALUES FROM ('10') TO ('100');
INSERT INTO foo_ptbl VALUES (0, 'aaa'), (9,'bbb'), (10,'ccc'), (99,'ddd');
SECURITY LABEL ON TABLE foo_ptbl
IS 'system_u:object_r:sepgsql_regtest_foo_table_t:s0';
CREATE TABLE var_ptbl(q int, r text) PARTITION BY RANGE (q);
CREATE TABLE var_ptbl_ones PARTITION OF var_ptbl FOR VALUES FROM ('0') TO ('10');
CREATE TABLE var_ptbl_tens PARTITION OF var_ptbl FOR VALUES FROM ('10') TO ('100');
INSERT INTO var_ptbl VALUES (0,'xxx'), (9,'yyy'), (10,'zzz'), (99,'xyz');
SECURITY LABEL ON TABLE var_ptbl
IS 'system_u:object_r:sepgsql_regtest_var_table_t:s0';
--
-- Tests for default labeling behavior
--
@ -72,36 +84,90 @@ SELECT sepgsql_getcon(); -- confirm client privilege
CREATE TABLE t4 (m int, n text);
INSERT INTO t4 VALUES (1,'mmm'), (2,'nnn'), (3,'ooo');
SELECT sepgsql_getcon(); -- confirm client privilege
sepgsql_getcon
-----------------------------------------------------
unconfined_u:unconfined_r:sepgsql_regtest_user_t:s0
(1 row)
CREATE TABLE tpart (o int, p text) PARTITION BY RANGE (o);
CREATE TABLE tpart_ones PARTITION OF tpart FOR VALUES FROM ('0') TO ('10');
SELECT sepgsql_getcon(); -- confirm client privilege
sepgsql_getcon
----------------------------------------------------
unconfined_u:unconfined_r:sepgsql_regtest_dba_t:s0
(1 row)
CREATE TABLE tpart_tens PARTITION OF tpart FOR VALUES FROM ('10') TO ('100');
INSERT INTO tpart VALUES (0, 'aaa');
INSERT INTO tpart VALUES (9, 'bbb');
INSERT INTO tpart VALUES (99, 'ccc');
SELECT objtype, objname, label FROM pg_seclabels
WHERE provider = 'selinux' AND objtype = 'table' AND objname in ('t1', 't2', 't3');
objtype | objname | label
---------+---------+-----------------------------------------------
table | t1 | unconfined_u:object_r:sepgsql_table_t:s0
table | t2 | unconfined_u:object_r:sepgsql_table_t:s0
table | t3 | unconfined_u:object_r:user_sepgsql_table_t:s0
(3 rows)
WHERE provider = 'selinux' AND objtype = 'table' AND objname in ('t1', 't2', 't3',
'tpart',
'tpart_ones',
'tpart_tens')
ORDER BY objname ASC;
objtype | objname | label
---------+------------+-----------------------------------------------
table | t1 | unconfined_u:object_r:sepgsql_table_t:s0
table | t2 | unconfined_u:object_r:sepgsql_table_t:s0
table | t3 | unconfined_u:object_r:user_sepgsql_table_t:s0
table | tpart | unconfined_u:object_r:user_sepgsql_table_t:s0
table | tpart_ones | unconfined_u:object_r:user_sepgsql_table_t:s0
table | tpart_tens | unconfined_u:object_r:sepgsql_table_t:s0
(6 rows)
SELECT objtype, objname, label FROM pg_seclabels
WHERE provider = 'selinux' AND objtype = 'column' AND (objname like 't3.%' OR objname like 't4.%');
objtype | objname | label
---------+-------------+-----------------------------------------------
column | t3.t | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.s | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.ctid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.xmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.cmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.xmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.cmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.tableoid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t4.n | unconfined_u:object_r:sepgsql_table_t:s0
column | t4.m | unconfined_u:object_r:sepgsql_table_t:s0
column | t4.ctid | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.xmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.cmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.xmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.cmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.tableoid | unconfined_u:object_r:sepgsql_sysobj_t:s0
(16 rows)
WHERE provider = 'selinux' AND objtype = 'column' AND (objname like 't3.%'
OR objname like 't4.%'
OR objname like 'tpart.%'
OR objname like 'tpart_ones.%'
OR objname like 'tpart_tens.%')
ORDER BY objname ASC;
objtype | objname | label
---------+---------------------+-----------------------------------------------
column | t3.cmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.cmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.ctid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.s | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.t | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.tableoid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.xmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t3.xmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | t4.cmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.cmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.ctid | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.m | unconfined_u:object_r:sepgsql_table_t:s0
column | t4.n | unconfined_u:object_r:sepgsql_table_t:s0
column | t4.tableoid | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.xmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | t4.xmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart.cmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.cmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.ctid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.o | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.cmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.cmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.ctid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.o | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.p | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.tableoid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.xmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_ones.xmin | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.p | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.tableoid | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart_tens.cmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart_tens.cmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart_tens.ctid | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart_tens.o | unconfined_u:object_r:sepgsql_table_t:s0
column | tpart_tens.p | unconfined_u:object_r:sepgsql_table_t:s0
column | tpart_tens.tableoid | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart_tens.xmax | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart_tens.xmin | unconfined_u:object_r:sepgsql_sysobj_t:s0
column | tpart.xmax | unconfined_u:object_r:user_sepgsql_table_t:s0
column | tpart.xmin | unconfined_u:object_r:user_sepgsql_table_t:s0
(40 rows)
--
-- Tests for SECURITY LABEL
@ -122,6 +188,16 @@ SECURITY LABEL ON COLUMN t2
ERROR: column name must be qualified
SECURITY LABEL ON COLUMN t2.b
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- ok
SECURITY LABEL ON TABLE tpart
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- ok
SECURITY LABEL ON TABLE tpart
IS 'invalid security context'; -- failed
ERROR: SELinux: invalid security label: "invalid security context"
SECURITY LABEL ON COLUMN tpart
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- failed
ERROR: column name must be qualified
SECURITY LABEL ON COLUMN tpart.o
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- ok
--
-- Tests for Trusted Procedures
--
@ -422,8 +498,19 @@ SELECT * FROM foo_tbl; -- OK
4 | ddd
(4 rows)
SELECT * FROM foo_ptbl; -- OK
o | p
----+-----
0 | aaa
9 | bbb
10 | ccc
99 | ddd
(4 rows)
SELECT * FROM var_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM var_ptbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM auth_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT sepgsql_setcon(NULL); -- end of session
@ -441,8 +528,12 @@ SELECT sepgsql_getcon();
-- the pooler cannot touch these tables directly
SELECT * FROM foo_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM foo_ptbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM var_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM var_ptbl; -- failed
ERROR: SELinux: security policy violation
-- switch to "var"
SELECT auth_func('var', 'b2145aac704ce76dbe1ac7adac535b23');
auth_func
@ -458,6 +549,8 @@ SELECT sepgsql_getcon();
SELECT * FROM foo_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM foo_ptbl; -- failed
ERROR: SELinux: security policy violation
SELECT * FROM var_tbl; -- OK
x | y
---+-----
@ -467,6 +560,15 @@ SELECT * FROM var_tbl; -- OK
5 | xyz
(4 rows)
SELECT * FROM var_ptbl; -- OK
q | r
----+-----
0 | xxx
9 | yyy
10 | zzz
99 | xyz
(4 rows)
SELECT * FROM auth_tbl; -- failed
ERROR: SELinux: security policy violation
SELECT sepgsql_setcon(NULL); -- end of session
@ -501,6 +603,7 @@ DROP TABLE IF EXISTS t1 CASCADE;
DROP TABLE IF EXISTS t2 CASCADE;
DROP TABLE IF EXISTS t3 CASCADE;
DROP TABLE IF EXISTS t4 CASCADE;
DROP TABLE IF EXISTS tpart CASCADE;
DROP FUNCTION IF EXISTS f1() CASCADE;
DROP FUNCTION IF EXISTS f2() CASCADE;
DROP FUNCTION IF EXISTS f3() CASCADE;