Skip to content

Commit 470c0a4

Browse files
committed
Introduce mdb_read_all_data/mdb_write_all_data
1 parent afe040b commit 470c0a4

8 files changed

Lines changed: 212 additions & 5 deletions

File tree

src/backend/catalog/aclchk.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,6 +3290,8 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
32903290
bool isNull;
32913291
Acl *acl;
32923292
Oid ownerId;
3293+
Oid mdb_read_all_data_oid;
3294+
Oid mdb_write_all_data_oid;
32933295

32943296
/*
32953297
* Must get the relation's tuple from pg_class
@@ -3340,6 +3342,9 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
33403342
*/
33413343
ownerId = classForm->relowner;
33423344

3345+
mdb_read_all_data_oid = get_role_oid("mdb_read_all_data", true);
3346+
mdb_write_all_data_oid = get_role_oid("mdb_write_all_data", true);
3347+
33433348
aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
33443349
&isNull);
33453350
if (isNull)
@@ -3379,6 +3384,17 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
33793384
has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA))
33803385
result |= ACL_SELECT;
33813386

3387+
3388+
/*
3389+
* Check if ACL_SELECT is being checked and, if so, and not set already as
3390+
* part of the result, then check if the user is a member of the
3391+
* mdb_read_all_data role, and this is not some dangerous relation to grant SELECT to
3392+
*/
3393+
if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3394+
has_privs_of_role(roleid, mdb_read_all_data_oid) &&
3395+
!has_privs_of_unwanted_system_role(ownerId))
3396+
result |= ACL_SELECT;
3397+
33823398
/*
33833399
* Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if
33843400
* so, and not set already as part of the result, then check if the user
@@ -3391,6 +3407,19 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
33913407
has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA))
33923408
result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
33933409

3410+
3411+
/*
3412+
* Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if
3413+
* so, and not set already as part of the result, then check if the user
3414+
* is a member of the mdb_write_all_data role, and this is not some
3415+
* dangerous relation to grant write access.
3416+
*/
3417+
if (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE) &&
3418+
!(result & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
3419+
has_privs_of_role(roleid, mdb_write_all_data_oid) &&
3420+
!has_privs_of_unwanted_system_role(ownerId))
3421+
result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
3422+
33943423
/*
33953424
* Check if ACL_MAINTAIN is being checked and, if so, and not already set
33963425
* as part of the result, then check if the user is a member of the
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
CREATE ROLE regress_mdb_superuser_user1;
2+
CREATE ROLE regress_mdb_superuser_user2;
3+
CREATE ROLE regress_mdb_superuser_user3;
4+
CREATE ROLE regress_superuser WITH SUPERUSER;
5+
GRANT mdb_superuser TO regress_mdb_superuser_user1;
6+
GRANT CREATE ON DATABASE regression TO regress_mdb_superuser_user2;
7+
SET ROLE regress_superuser;
8+
CREATE TABLE regress_superuser_table();
9+
SET ROLE pg_read_server_files;
10+
CREATE TABLE regress_pgrsf_table();
11+
SET ROLE pg_write_server_files;
12+
CREATE TABLE regress_pgwsf_table();
13+
SET ROLE pg_execute_server_program;
14+
CREATE TABLE regress_pgxsp_table();
15+
SET ROLE pg_read_all_data;
16+
CREATE TABLE regress_pgrad_table();
17+
SET ROLE pg_write_all_data;
18+
CREATE TABLE regress_pgrwd_table();
19+
SET ROLE regress_mdb_superuser_user1;
20+
CREATE TABLE regress_mdbsu_table();
21+
SET ROLE regress_mdb_superuser_user2;
22+
CREATE TABLE regress_mdbsu_table2();
23+
SET ROLE mdb_read_all_data;
24+
-- cannot read all data (fail)
25+
TABLE pg_authid;
26+
ERROR: permission denied for table pg_authid
27+
TABLE regress_superuser_table;
28+
ERROR: permission denied for table regress_superuser_table
29+
TABLE regress_pgrsf_table;
30+
ERROR: permission denied for table regress_pgrsf_table
31+
TABLE regress_pgwsf_table;
32+
ERROR: permission denied for table regress_pgwsf_table
33+
TABLE regress_pgxsp_table;
34+
ERROR: permission denied for table regress_pgxsp_table
35+
TABLE regress_pgrad_table;
36+
ERROR: permission denied for table regress_pgrad_table
37+
TABLE regress_pgwsf_table;
38+
ERROR: permission denied for table regress_pgwsf_table
39+
-- is allow to read all other data
40+
TABLE regress_mdbsu_table;
41+
--
42+
(0 rows)
43+
44+
TABLE regress_mdbsu_table2;
45+
--
46+
(0 rows)
47+
48+
SET ROLE mdb_write_all_data;
49+
CREATE TABLE regress_tt_dat();
50+
-- cannot read all data (fail)
51+
INSERT INTO regress_superuser_table TABLE regress_tt_dat;
52+
ERROR: permission denied for table regress_superuser_table
53+
INSERT INTO regress_pgrsf_table TABLE regress_tt_dat;
54+
ERROR: permission denied for table regress_pgrsf_table
55+
INSERT INTO regress_pgwsf_table TABLE regress_tt_dat;
56+
ERROR: permission denied for table regress_pgwsf_table
57+
INSERT INTO regress_pgxsp_table TABLE regress_tt_dat;
58+
ERROR: permission denied for table regress_pgxsp_table
59+
INSERT INTO regress_pgrad_table TABLE regress_tt_dat;
60+
ERROR: permission denied for table regress_pgrad_table
61+
INSERT INTO regress_pgwsf_table TABLE regress_tt_dat;
62+
ERROR: permission denied for table regress_pgwsf_table
63+
-- is allow to read all other data
64+
INSERT INTO regress_mdbsu_table TABLE regress_tt_dat;
65+
INSERT INTO regress_mdbsu_table2 TABLE regress_tt_dat;
66+
-- end tests
67+
RESET SESSION AUTHORIZATION;
68+
--
69+
DROP TABLE regress_pgrsf_table;
70+
DROP TABLE regress_pgwsf_table;
71+
DROP TABLE regress_pgxsp_table;
72+
DROP TABLE regress_pgrad_table;
73+
DROP TABLE regress_pgrwd_table;
74+
DROP TABLE regress_mdbsu_table;
75+
DROP TABLE regress_mdbsu_table2;
76+
DROP TABLE regress_superuser_table;
77+
REVOKE CREATE ON DATABASE regression FROM regress_mdb_superuser_user2;
78+
REVOKE CREATE ON DATABASE regression FROM regress_mdb_superuser_user3;
79+
DROP ROLE regress_mdb_superuser_user1;
80+
DROP ROLE regress_mdb_superuser_user2;
81+
DROP ROLE regress_mdb_superuser_user3;
82+
DROP ROLE regress_superuser;

src/test/regress/expected/mdb_superuser.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ CREATE ROLE regress_mdb_superuser_user3;
44
CREATE ROLE regress_mdb_su_role_o1;
55
CREATE ROLE regress_mdb_su_role_o2;
66
GRANT mdb_superuser TO regress_mdb_su_role_o1;
7-
GRANT mdb_admin TO mdb_superuser;
87
CREATE ROLE regress_superuser WITH SUPERUSER;
98
GRANT mdb_superuser TO regress_mdb_superuser_user1;
109
GRANT CREATE ON DATABASE regression TO regress_mdb_superuser_user2;
@@ -59,7 +58,7 @@ DROP TABLE regress_pgwsf_table;
5958
DROP TABLE regress_pgxsp_table;
6059
DROP TABLE regress_pgrad_table;
6160
DROP TABLE regress_pgrwd_table;
62-
-- does allowed to creare database, role or extension
61+
-- does NOT allowed to create database, role or extension
6362
-- or grant such priviledge
6463
CREATE DATABASE regress_db_fail;
6564
ERROR: permission denied to create database
@@ -128,3 +127,4 @@ DROP SCHEMA regress_mdb_superuser_schema;
128127
DROP ROLE regress_mdb_superuser_user1;
129128
DROP ROLE regress_mdb_superuser_user2;
130129
DROP ROLE regress_mdb_superuser_user3;
130+
DROP ROLE regress_superuser;

src/test/regress/expected/test_setup.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,8 @@ create function fipshash(text)
237237
return substr(encode(sha256($1::bytea), 'hex'), 1, 32);
238238
CREATE ROLE mdb_admin;
239239
CREATE ROLE mdb_superuser;
240+
CREATE ROLE mdb_read_all_data;
241+
CREATE ROLE mdb_write_all_data;
240242
CREATE ROLE mdb_replication;
243+
GRANT mdb_admin TO mdb_superuser;
241244
GRANT pg_create_subscription TO mdb_admin;

src/test/regress/parallel_schedule

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ test: mdb_replication
2121

2222
test: mdb_copy
2323

24+
test: mdb_read_write_roles
25+
2426
# ----------
2527
# The first group of parallel tests
2628
# ----------
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
CREATE ROLE regress_mdb_superuser_user1;
2+
CREATE ROLE regress_mdb_superuser_user2;
3+
CREATE ROLE regress_mdb_superuser_user3;
4+
5+
CREATE ROLE regress_superuser WITH SUPERUSER;
6+
7+
GRANT mdb_superuser TO regress_mdb_superuser_user1;
8+
9+
GRANT CREATE ON DATABASE regression TO regress_mdb_superuser_user2;
10+
11+
SET ROLE regress_superuser;
12+
CREATE TABLE regress_superuser_table();
13+
14+
SET ROLE pg_read_server_files;
15+
CREATE TABLE regress_pgrsf_table();
16+
17+
SET ROLE pg_write_server_files;
18+
CREATE TABLE regress_pgwsf_table();
19+
20+
SET ROLE pg_execute_server_program;
21+
CREATE TABLE regress_pgxsp_table();
22+
23+
SET ROLE pg_read_all_data;
24+
CREATE TABLE regress_pgrad_table();
25+
26+
SET ROLE pg_write_all_data;
27+
CREATE TABLE regress_pgrwd_table();
28+
29+
SET ROLE regress_mdb_superuser_user1;
30+
CREATE TABLE regress_mdbsu_table();
31+
32+
SET ROLE regress_mdb_superuser_user2;
33+
CREATE TABLE regress_mdbsu_table2();
34+
35+
SET ROLE mdb_read_all_data;
36+
-- cannot read all data (fail)
37+
TABLE pg_authid;
38+
TABLE regress_superuser_table;
39+
TABLE regress_pgrsf_table;
40+
TABLE regress_pgwsf_table;
41+
TABLE regress_pgxsp_table;
42+
TABLE regress_pgrad_table;
43+
TABLE regress_pgwsf_table;
44+
45+
46+
-- is allow to read all other data
47+
48+
TABLE regress_mdbsu_table;
49+
TABLE regress_mdbsu_table2;
50+
51+
52+
SET ROLE mdb_write_all_data;
53+
CREATE TABLE regress_tt_dat();
54+
-- cannot read all data (fail)
55+
INSERT INTO regress_superuser_table TABLE regress_tt_dat;
56+
INSERT INTO regress_pgrsf_table TABLE regress_tt_dat;
57+
INSERT INTO regress_pgwsf_table TABLE regress_tt_dat;
58+
INSERT INTO regress_pgxsp_table TABLE regress_tt_dat;
59+
INSERT INTO regress_pgrad_table TABLE regress_tt_dat;
60+
INSERT INTO regress_pgwsf_table TABLE regress_tt_dat;
61+
62+
63+
-- is allow to read all other data
64+
65+
INSERT INTO regress_mdbsu_table TABLE regress_tt_dat;
66+
INSERT INTO regress_mdbsu_table2 TABLE regress_tt_dat;
67+
68+
-- end tests
69+
70+
RESET SESSION AUTHORIZATION;
71+
--
72+
73+
DROP TABLE regress_pgrsf_table;
74+
DROP TABLE regress_pgwsf_table;
75+
DROP TABLE regress_pgxsp_table;
76+
DROP TABLE regress_pgrad_table;
77+
DROP TABLE regress_pgrwd_table;
78+
79+
DROP TABLE regress_mdbsu_table;
80+
DROP TABLE regress_mdbsu_table2;
81+
DROP TABLE regress_superuser_table;
82+
83+
REVOKE CREATE ON DATABASE regression FROM regress_mdb_superuser_user2;
84+
REVOKE CREATE ON DATABASE regression FROM regress_mdb_superuser_user3;
85+
86+
DROP ROLE regress_mdb_superuser_user1;
87+
DROP ROLE regress_mdb_superuser_user2;
88+
DROP ROLE regress_mdb_superuser_user3;
89+
DROP ROLE regress_superuser;

src/test/regress/sql/mdb_superuser.sql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ CREATE ROLE regress_mdb_su_role_o2;
77

88
GRANT mdb_superuser TO regress_mdb_su_role_o1;
99

10-
GRANT mdb_admin TO mdb_superuser;
11-
1210
CREATE ROLE regress_superuser WITH SUPERUSER;
1311

1412
GRANT mdb_superuser TO regress_mdb_superuser_user1;
@@ -90,7 +88,7 @@ DROP TABLE regress_pgrad_table;
9088
DROP TABLE regress_pgrwd_table;
9189

9290

93-
-- does allowed to creare database, role or extension
91+
-- does NOT allowed to create database, role or extension
9492
-- or grant such priviledge
9593

9694
CREATE DATABASE regress_db_fail;
@@ -162,3 +160,4 @@ DROP SCHEMA regress_mdb_superuser_schema;
162160
DROP ROLE regress_mdb_superuser_user1;
163161
DROP ROLE regress_mdb_superuser_user2;
164162
DROP ROLE regress_mdb_superuser_user3;
163+
DROP ROLE regress_superuser;

src/test/regress/sql/test_setup.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ create function fipshash(text)
292292

293293
CREATE ROLE mdb_admin;
294294
CREATE ROLE mdb_superuser;
295+
CREATE ROLE mdb_read_all_data;
296+
CREATE ROLE mdb_write_all_data;
295297
CREATE ROLE mdb_replication;
296298

299+
GRANT mdb_admin TO mdb_superuser;
297300
GRANT pg_create_subscription TO mdb_admin;

0 commit comments

Comments
 (0)