Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eb5e9d9

Browse files
committed
pg_dump: Fix handling of ALTER DEFAULT PRIVILEGES
In commit 23f34fa, we changed how ACLs were handled to use the new pg_init_privs catalog and to dump out the ACL commands as REVOKE+GRANT combinations instead of trying to REVOKE all rights always and then GRANT back just the ones which were in place. Unfortunately, the DEFAULT PRIVILEGES system didn't quite get the correct treatment with this change and ended up (incorrectly) only including positive GRANTs instead of both the REVOKEs and GRANTs necessary to preserve the correct privileges. There are only a couple cases where such REVOKEs are possible because, generally speaking, there's few rights which exist on objects by default to be revoked. Examples of REVOKEs which weren't being correctly preserved are when privileges are REVOKE'd from the creator/owner, like so: ALTER DEFAULT PRIVILEGES FOR ROLE myrole REVOKE SELECT ON TABLES FROM myrole; or when other default privileges are being revoked, such as EXECUTE rights granted to public for functions: ALTER DEFAULT PRIVILEGES FOR ROLE myrole REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC; Fix this by correctly working out what the correct REVOKE statements are (if any) and dump them out, just as we do for everything else. Noticed while developing additional regression tests for pg_dump, which will be landing shortly. Back-patch to 9.6 where the bug was introduced.
1 parent 3e9c361 commit eb5e9d9

File tree

4 files changed

+78
-15
lines changed

4 files changed

+78
-15
lines changed

src/bin/pg_dump/dumputils.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,12 @@ buildACLCommands(const char *name, const char *subname,
368368
*/
369369
bool
370370
buildDefaultACLCommands(const char *type, const char *nspname,
371-
const char *acls, const char *owner,
371+
const char *acls, const char *racls,
372+
const char *initacls, const char *initracls,
373+
const char *owner,
372374
int remoteVersion,
373375
PQExpBuffer sql)
374376
{
375-
bool result;
376377
PQExpBuffer prefix;
377378

378379
prefix = createPQExpBuffer();
@@ -388,14 +389,22 @@ buildDefaultACLCommands(const char *type, const char *nspname,
388389
if (nspname)
389390
appendPQExpBuffer(prefix, "IN SCHEMA %s ", fmtId(nspname));
390391

391-
result = buildACLCommands("", NULL,
392-
type, acls, "", owner,
393-
prefix->data, remoteVersion,
394-
sql);
392+
if (strlen(initacls) != 0 || strlen(initracls) != 0)
393+
{
394+
appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
395+
if (!buildACLCommands("", NULL, type, initacls, initracls, owner,
396+
prefix->data, remoteVersion, sql))
397+
return false;
398+
appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
399+
}
400+
401+
if (!buildACLCommands("", NULL, type, acls, racls, owner,
402+
prefix->data, remoteVersion, sql))
403+
return false;
395404

396405
destroyPQExpBuffer(prefix);
397406

398-
return result;
407+
return true;
399408
}
400409

401410
/*

src/bin/pg_dump/dumputils.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ extern bool buildACLCommands(const char *name, const char *subname,
4141
const char *owner, const char *prefix, int remoteVersion,
4242
PQExpBuffer sql);
4343
extern bool buildDefaultACLCommands(const char *type, const char *nspname,
44-
const char *acls, const char *owner,
44+
const char *acls, const char *racls,
45+
const char *initacls, const char *initracls,
46+
const char *owner,
4547
int remoteVersion,
4648
PQExpBuffer sql);
4749
extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name,

src/bin/pg_dump/pg_dump.c

+56-7
Original file line numberDiff line numberDiff line change
@@ -8954,6 +8954,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
89548954
int i_defaclnamespace;
89558955
int i_defaclobjtype;
89568956
int i_defaclacl;
8957+
int i_rdefaclacl;
8958+
int i_initdefaclacl;
8959+
int i_initrdefaclacl;
89578960
int i,
89588961
ntups;
89598962

@@ -8968,13 +8971,50 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
89688971
/* Make sure we are in proper schema */
89698972
selectSourceSchema(fout, "pg_catalog");
89708973

8971-
appendPQExpBuffer(query, "SELECT oid, tableoid, "
8972-
"(%s defaclrole) AS defaclrole, "
8973-
"defaclnamespace, "
8974-
"defaclobjtype, "
8975-
"defaclacl "
8976-
"FROM pg_default_acl",
8977-
username_subquery);
8974+
if (fout->remoteVersion >= 90600)
8975+
{
8976+
PQExpBuffer acl_subquery = createPQExpBuffer();
8977+
PQExpBuffer racl_subquery = createPQExpBuffer();
8978+
PQExpBuffer initacl_subquery = createPQExpBuffer();
8979+
PQExpBuffer initracl_subquery = createPQExpBuffer();
8980+
8981+
buildACLQueries(acl_subquery, racl_subquery, initacl_subquery,
8982+
initracl_subquery, "defaclacl", "defaclrole",
8983+
"CASE WHEN defaclobjtype = 'S' THEN 's' ELSE defaclobjtype END::\"char\"",
8984+
dopt->binary_upgrade);
8985+
8986+
appendPQExpBuffer(query, "SELECT d.oid, d.tableoid, "
8987+
"(%s d.defaclrole) AS defaclrole, "
8988+
"d.defaclnamespace, "
8989+
"d.defaclobjtype, "
8990+
"%s AS defaclacl, "
8991+
"%s AS rdefaclacl, "
8992+
"%s AS initdefaclacl, "
8993+
"%s AS initrdefaclacl "
8994+
"FROM pg_default_acl d "
8995+
"LEFT JOIN pg_init_privs pip ON "
8996+
"(d.oid = pip.objoid "
8997+
"AND pip.classoid = 'pg_default_acl'::regclass "
8998+
"AND pip.objsubid = 0) ",
8999+
username_subquery,
9000+
acl_subquery->data,
9001+
racl_subquery->data,
9002+
initacl_subquery->data,
9003+
initracl_subquery->data);
9004+
}
9005+
else
9006+
{
9007+
appendPQExpBuffer(query, "SELECT oid, tableoid, "
9008+
"(%s defaclrole) AS defaclrole, "
9009+
"defaclnamespace, "
9010+
"defaclobjtype, "
9011+
"defaclacl, "
9012+
"NULL AS rdefaclacl, "
9013+
"NULL AS initdefaclacl, "
9014+
"NULL AS initrdefaclacl "
9015+
"FROM pg_default_acl",
9016+
username_subquery);
9017+
}
89789018

89799019
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
89809020

@@ -8989,6 +9029,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
89899029
i_defaclnamespace = PQfnumber(res, "defaclnamespace");
89909030
i_defaclobjtype = PQfnumber(res, "defaclobjtype");
89919031
i_defaclacl = PQfnumber(res, "defaclacl");
9032+
i_rdefaclacl = PQfnumber(res, "rdefaclacl");
9033+
i_initdefaclacl = PQfnumber(res, "initdefaclacl");
9034+
i_initrdefaclacl = PQfnumber(res, "initrdefaclacl");
89929035

89939036
for (i = 0; i < ntups; i++)
89949037
{
@@ -9010,6 +9053,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
90109053
daclinfo[i].defaclrole = pg_strdup(PQgetvalue(res, i, i_defaclrole));
90119054
daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
90129055
daclinfo[i].defaclacl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
9056+
daclinfo[i].rdefaclacl = pg_strdup(PQgetvalue(res, i, i_rdefaclacl));
9057+
daclinfo[i].initdefaclacl = pg_strdup(PQgetvalue(res, i, i_initdefaclacl));
9058+
daclinfo[i].initrdefaclacl = pg_strdup(PQgetvalue(res, i, i_initrdefaclacl));
90139059

90149060
/* Decide whether we want to dump it */
90159061
selectDumpableDefaultACL(&(daclinfo[i]), dopt);
@@ -14615,6 +14661,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1461514661
daclinfo->dobj.namespace != NULL ?
1461614662
daclinfo->dobj.namespace->dobj.name : NULL,
1461714663
daclinfo->defaclacl,
14664+
daclinfo->rdefaclacl,
14665+
daclinfo->initdefaclacl,
14666+
daclinfo->initrdefaclacl,
1461814667
daclinfo->defaclrole,
1461914668
fout->remoteVersion,
1462014669
q))

src/bin/pg_dump/pg_dump.h

+3
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ typedef struct _defaultACLInfo
524524
char *defaclrole;
525525
char defaclobjtype;
526526
char *defaclacl;
527+
char *rdefaclacl;
528+
char *initdefaclacl;
529+
char *initrdefaclacl;
527530
} DefaultACLInfo;
528531

529532
typedef struct _blobInfo

0 commit comments

Comments
 (0)