aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-10-22 15:22:25 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-10-22 15:22:25 -0400
commit3ad2c2455be0bd42f1ca22907850b93c3afc575b (patch)
treeffa000632f0b1eda2c429d4c2ca232240eca5320 /src
parent52c0c11367fdac78a59997de2b24031c0501fbe7 (diff)
downloadpostgresql-3ad2c2455be0bd42f1ca22907850b93c3afc575b.tar.gz
postgresql-3ad2c2455be0bd42f1ca22907850b93c3afc575b.zip
pg_dump: fix mis-dumping of non-global default privileges.
Non-global default privilege entries should be dumped as-is, not made relative to the default ACL for their object type. This would typically only matter if one had revoked some on-by-default privileges in a global entry, and then wanted to grant them again in a non-global entry. Per report from Boris Korzun. This is an old bug, so back-patch to all supported branches. Neil Chen, test case by Masahiko Sawada Discussion: https://postgr.es/m/111621616618184@mail.yandex.ru Discussion: https://postgr.es/m/CAA3qoJnr2+1dVJObNtfec=qW4Z0nz=A9+r5bZKoTSy5RDjskMw@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c19
-rw-r--r--src/bin/pg_dump/t/002_pg_dump.pl19
2 files changed, 37 insertions, 1 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index d9940dc4e87..fee7055249e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -9787,9 +9787,26 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
PQExpBuffer initacl_subquery = createPQExpBuffer();
PQExpBuffer initracl_subquery = createPQExpBuffer();
+ /*
+ * Global entries (with defaclnamespace=0) replace the hard-wired
+ * default ACL for their object type. We should dump them as deltas
+ * from the default ACL, since that will be used as a starting point
+ * for interpreting the ALTER DEFAULT PRIVILEGES commands. On the
+ * other hand, non-global entries can only add privileges not revoke
+ * them. We must dump those as-is (i.e., as deltas from an empty
+ * ACL). We implement that by passing NULL as the object type for
+ * acldefault(), which works because acldefault() is STRICT.
+ *
+ * We can use defaclobjtype as the object type for acldefault(),
+ * except for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be
+ * converted to 's'.
+ */
buildACLQueries(acl_subquery, racl_subquery, initacl_subquery,
initracl_subquery, "defaclacl", "defaclrole",
- "CASE WHEN defaclobjtype = 'S' THEN 's' ELSE defaclobjtype END::\"char\"",
+ "CASE WHEN defaclnamespace = 0 THEN"
+ " CASE WHEN defaclobjtype = 'S' THEN 's'::\"char\""
+ " ELSE defaclobjtype END "
+ "ELSE NULL END",
dopt->binary_upgrade);
appendPQExpBuffer(query, "SELECT d.oid, d.tableoid, "
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 9342738918f..4e613efbfa6 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -436,6 +436,25 @@ my %tests = (
},
},
+ 'ALTER DEFAULT PRIVILEGES FOR ROLE regress_dump_test_role GRANT EXECUTE ON FUNCTIONS'
+ => {
+ create_order => 15,
+ create_sql => 'ALTER DEFAULT PRIVILEGES
+ FOR ROLE regress_dump_test_role IN SCHEMA dump_test
+ GRANT EXECUTE ON FUNCTIONS TO regress_dump_test_role;',
+ regexp => qr/^
+ \QALTER DEFAULT PRIVILEGES \E
+ \QFOR ROLE regress_dump_test_role IN SCHEMA dump_test \E
+ \QGRANT ALL ON FUNCTIONS TO regress_dump_test_role;\E
+ /xm,
+ like =>
+ { %full_runs, %dump_test_schema_runs, section_post_data => 1, },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ no_privs => 1,
+ },
+ },
+
'ALTER DEFAULT PRIVILEGES FOR ROLE regress_dump_test_role REVOKE' => {
create_order => 55,
create_sql => 'ALTER DEFAULT PRIVILEGES