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

Commit e2090d9

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 6af8b89 commit e2090d9

File tree

4 files changed

+78
-15
lines changed

4 files changed

+78
-15
lines changed

src/bin/pg_dump/dumputils.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,12 @@ buildACLCommands(const char *name, const char *subname,
364364
*/
365365
bool
366366
buildDefaultACLCommands(const char *type, const char *nspname,
367-
const char *acls, const char *owner,
367+
const char *acls, const char *racls,
368+
const char *initacls, const char *initracls,
369+
const char *owner,
368370
int remoteVersion,
369371
PQExpBuffer sql)
370372
{
371-
bool result;
372373
PQExpBuffer prefix;
373374

374375
prefix = createPQExpBuffer();
@@ -384,14 +385,22 @@ buildDefaultACLCommands(const char *type, const char *nspname,
384385
if (nspname)
385386
appendPQExpBuffer(prefix, "IN SCHEMA %s ", fmtId(nspname));
386387

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

392401
destroyPQExpBuffer(prefix);
393402

394-
return result;
403+
return true;
395404
}
396405

397406
/*

src/bin/pg_dump/dumputils.h

Lines changed: 3 additions & 1 deletion
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

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8683,6 +8683,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
86838683
int i_defaclnamespace;
86848684
int i_defaclobjtype;
86858685
int i_defaclacl;
8686+
int i_rdefaclacl;
8687+
int i_initdefaclacl;
8688+
int i_initrdefaclacl;
86868689
int i,
86878690
ntups;
86888691

@@ -8697,13 +8700,50 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
86978700
/* Make sure we are in proper schema */
86988701
selectSourceSchema(fout, "pg_catalog");
86998702

8700-
appendPQExpBuffer(query, "SELECT oid, tableoid, "
8701-
"(%s defaclrole) AS defaclrole, "
8702-
"defaclnamespace, "
8703-
"defaclobjtype, "
8704-
"defaclacl "
8705-
"FROM pg_default_acl",
8706-
username_subquery);
8703+
if (fout->remoteVersion >= 90600)
8704+
{
8705+
PQExpBuffer acl_subquery = createPQExpBuffer();
8706+
PQExpBuffer racl_subquery = createPQExpBuffer();
8707+
PQExpBuffer initacl_subquery = createPQExpBuffer();
8708+
PQExpBuffer initracl_subquery = createPQExpBuffer();
8709+
8710+
buildACLQueries(acl_subquery, racl_subquery, initacl_subquery,
8711+
initracl_subquery, "defaclacl", "defaclrole",
8712+
"CASE WHEN defaclobjtype = 'S' THEN 's' ELSE defaclobjtype END::\"char\"",
8713+
dopt->binary_upgrade);
8714+
8715+
appendPQExpBuffer(query, "SELECT d.oid, d.tableoid, "
8716+
"(%s d.defaclrole) AS defaclrole, "
8717+
"d.defaclnamespace, "
8718+
"d.defaclobjtype, "
8719+
"%s AS defaclacl, "
8720+
"%s AS rdefaclacl, "
8721+
"%s AS initdefaclacl, "
8722+
"%s AS initrdefaclacl "
8723+
"FROM pg_default_acl d "
8724+
"LEFT JOIN pg_init_privs pip ON "
8725+
"(d.oid = pip.objoid "
8726+
"AND pip.classoid = 'pg_default_acl'::regclass "
8727+
"AND pip.objsubid = 0) ",
8728+
username_subquery,
8729+
acl_subquery->data,
8730+
racl_subquery->data,
8731+
initacl_subquery->data,
8732+
initracl_subquery->data);
8733+
}
8734+
else
8735+
{
8736+
appendPQExpBuffer(query, "SELECT oid, tableoid, "
8737+
"(%s defaclrole) AS defaclrole, "
8738+
"defaclnamespace, "
8739+
"defaclobjtype, "
8740+
"defaclacl, "
8741+
"NULL AS rdefaclacl, "
8742+
"NULL AS initdefaclacl, "
8743+
"NULL AS initrdefaclacl "
8744+
"FROM pg_default_acl",
8745+
username_subquery);
8746+
}
87078747

87088748
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
87098749

@@ -8718,6 +8758,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
87188758
i_defaclnamespace = PQfnumber(res, "defaclnamespace");
87198759
i_defaclobjtype = PQfnumber(res, "defaclobjtype");
87208760
i_defaclacl = PQfnumber(res, "defaclacl");
8761+
i_rdefaclacl = PQfnumber(res, "rdefaclacl");
8762+
i_initdefaclacl = PQfnumber(res, "initdefaclacl");
8763+
i_initrdefaclacl = PQfnumber(res, "initrdefaclacl");
87218764

87228765
for (i = 0; i < ntups; i++)
87238766
{
@@ -8738,6 +8781,9 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
87388781
daclinfo[i].defaclrole = pg_strdup(PQgetvalue(res, i, i_defaclrole));
87398782
daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
87408783
daclinfo[i].defaclacl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
8784+
daclinfo[i].rdefaclacl = pg_strdup(PQgetvalue(res, i, i_rdefaclacl));
8785+
daclinfo[i].initdefaclacl = pg_strdup(PQgetvalue(res, i, i_initdefaclacl));
8786+
daclinfo[i].initrdefaclacl = pg_strdup(PQgetvalue(res, i, i_initrdefaclacl));
87418787

87428788
/* Decide whether we want to dump it */
87438789
selectDumpableDefaultACL(&(daclinfo[i]), dopt);
@@ -14038,6 +14084,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1403814084
daclinfo->dobj.namespace != NULL ?
1403914085
daclinfo->dobj.namespace->dobj.name : NULL,
1404014086
daclinfo->defaclacl,
14087+
daclinfo->rdefaclacl,
14088+
daclinfo->initdefaclacl,
14089+
daclinfo->initrdefaclacl,
1404114090
daclinfo->defaclrole,
1404214091
fout->remoteVersion,
1404314092
q))

src/bin/pg_dump/pg_dump.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ typedef struct _defaultACLInfo
539539
char *defaclrole;
540540
char defaclobjtype;
541541
char *defaclacl;
542+
char *rdefaclacl;
543+
char *initdefaclacl;
544+
char *initrdefaclacl;
542545
} DefaultACLInfo;
543546

544547
typedef struct _blobInfo

0 commit comments

Comments
 (0)